From: Peter Tyser Date: Tue, 13 Apr 2010 03:28:11 +0000 (-0500) Subject: arm: Move cpu/$CPU to arch/arm/cpu/$CPU X-Git-Tag: v2010.06-rc1~98 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=84ad688473bec2875e171b71040eb9e033c6c206;p=oweals%2Fu-boot.git arm: Move cpu/$CPU to arch/arm/cpu/$CPU Signed-off-by: Peter Tyser --- diff --git a/Makefile b/Makefile index ddfe73c063..e922ec3a7b 100644 --- a/Makefile +++ b/Makefile @@ -193,7 +193,7 @@ ifdef SOC LIBS += $(CPUDIR)/$(SOC)/lib$(SOC).a endif ifeq ($(CPU),ixp) -LIBS += cpu/ixp/npe/libnpe.a +LIBS += arch/arm/cpu/ixp/npe/libnpe.a endif LIBS += arch/$(ARCH)/lib/lib$(ARCH).a LIBS += fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a \ diff --git a/arch/arm/cpu/arm1136/Makefile b/arch/arm/cpu/arm1136/Makefile new file mode 100644 index 0000000000..7701b03bbe --- /dev/null +++ b/arch/arm/cpu/arm1136/Makefile @@ -0,0 +1,47 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(CPU).a + +START = start.o +COBJS = cpu.o + +SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm1136/config.mk b/arch/arm/cpu/arm1136/config.mk new file mode 100644 index 0000000000..3e685354ab --- /dev/null +++ b/arch/arm/cpu/arm1136/config.mk @@ -0,0 +1,32 @@ +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float + +# Make ARMv5 to allow more compilers to work, even though its v6. +PLATFORM_CPPFLAGS += -march=armv5 +# ========================================================================= +# +# Supply options according to compiler version +# +# ========================================================================= +PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/arch/arm/cpu/arm1136/cpu.c b/arch/arm/cpu/arm1136/cpu.c new file mode 100644 index 0000000000..ade7f46800 --- /dev/null +++ b/arch/arm/cpu/arm1136/cpu.c @@ -0,0 +1,76 @@ +/* + * (C) Copyright 2004 Texas Insturments + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * CPU specific code + */ + +#include +#include +#include + +static void cache_flush(void); + +int cleanup_before_linux (void) +{ + /* + * this function is called just before we call linux + * it prepares the processor for linux + * + * we turn off caches etc ... + */ + + disable_interrupts (); + +#ifdef CONFIG_LCD + { + extern void lcd_disable(void); + extern void lcd_panel_disable(void); + + lcd_disable(); /* proper disable of lcd & panel */ + lcd_panel_disable(); + } +#endif + + /* turn off I/D-cache */ + icache_disable(); + dcache_disable(); + /* flush I/D-cache */ + cache_flush(); + + return 0; +} + +static void cache_flush(void) +{ + unsigned long i = 0; + + asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); /* invalidate both caches and flush btb */ + asm ("mcr p15, 0, %0, c7, c10, 4": :"r" (i)); /* mem barrier to sync things */ +} diff --git a/arch/arm/cpu/arm1136/mx31/Makefile b/arch/arm/cpu/arm1136/mx31/Makefile new file mode 100644 index 0000000000..c8e18f7f02 --- /dev/null +++ b/arch/arm/cpu/arm1136/mx31/Makefile @@ -0,0 +1,47 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +COBJS += generic.o +COBJS += timer.o +COBJS += devices.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm1136/mx31/devices.c b/arch/arm/cpu/arm1136/mx31/devices.c new file mode 100644 index 0000000000..1f4ca7eb44 --- /dev/null +++ b/arch/arm/cpu/arm1136/mx31/devices.c @@ -0,0 +1,56 @@ +/* + * + * (C) Copyright 2009 Magnus Lilja + * + * (c) 2007 Pengutronix, Sascha Hauer + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +#ifdef CONFIG_SYS_MX31_UART1 +void mx31_uart1_hw_init(void) +{ + /* setup pins for UART1 */ + mx31_gpio_mux(MUX_RXD1__UART1_RXD_MUX); + mx31_gpio_mux(MUX_TXD1__UART1_TXD_MUX); + mx31_gpio_mux(MUX_RTS1__UART1_RTS_B); + mx31_gpio_mux(MUX_CTS1__UART1_CTS_B); +} +#endif + +#ifdef CONFIG_MXC_SPI +void mx31_spi2_hw_init(void) +{ + /* SPI2 */ + mx31_gpio_mux(MUX_CSPI2_SS2__CSPI2_SS2_B); + mx31_gpio_mux(MUX_CSPI2_SCLK__CSPI2_CLK); + mx31_gpio_mux(MUX_CSPI2_SPI_RDY__CSPI2_DATAREADY_B); + mx31_gpio_mux(MUX_CSPI2_MOSI__CSPI2_MOSI); + mx31_gpio_mux(MUX_CSPI2_MISO__CSPI2_MISO); + mx31_gpio_mux(MUX_CSPI2_SS0__CSPI2_SS0_B); + mx31_gpio_mux(MUX_CSPI2_SS1__CSPI2_SS1_B); + + /* start SPI2 clock */ + __REG(CCM_CGR2) = __REG(CCM_CGR2) | (3 << 4); +} +#endif diff --git a/arch/arm/cpu/arm1136/mx31/generic.c b/arch/arm/cpu/arm1136/mx31/generic.c new file mode 100644 index 0000000000..1415d6c2ae --- /dev/null +++ b/arch/arm/cpu/arm1136/mx31/generic.c @@ -0,0 +1,100 @@ +/* + * (C) Copyright 2007 + * Sascha Hauer, Pengutronix + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +static u32 mx31_decode_pll(u32 reg, u32 infreq) +{ + u32 mfi = (reg >> 10) & 0xf; + u32 mfn = reg & 0x3ff; + u32 mfd = (reg >> 16) & 0x3ff; + u32 pd = (reg >> 26) & 0xf; + + mfi = mfi <= 5 ? 5 : mfi; + mfd += 1; + pd += 1; + + return ((2 * (infreq >> 10) * (mfi * mfd + mfn)) / + (mfd * pd)) << 10; +} + +static u32 mx31_get_mpl_dpdgck_clk(void) +{ + u32 infreq; + + if ((__REG(CCM_CCMR) & CCMR_PRCS_MASK) == CCMR_FPM) + infreq = CONFIG_MX31_CLK32 * 1024; + else + infreq = CONFIG_MX31_HCLK_FREQ; + + return mx31_decode_pll(__REG(CCM_MPCTL), infreq); +} + +static u32 mx31_get_mcu_main_clk(void) +{ + /* For now we assume mpl_dpdgck_clk == mcu_main_clk + * which should be correct for most boards + */ + return mx31_get_mpl_dpdgck_clk(); +} + +u32 mx31_get_ipg_clk(void) +{ + u32 freq = mx31_get_mcu_main_clk(); + u32 pdr0 = __REG(CCM_PDR0); + + freq /= ((pdr0 >> 3) & 0x7) + 1; + freq /= ((pdr0 >> 6) & 0x3) + 1; + + return freq; +} + +void mx31_dump_clocks(void) +{ + u32 cpufreq = mx31_get_mcu_main_clk(); + printf("mx31 cpu clock: %dMHz\n",cpufreq / 1000000); + printf("ipg clock : %dHz\n", mx31_get_ipg_clk()); +} + +void mx31_gpio_mux(unsigned long mode) +{ + unsigned long reg, shift, tmp; + + reg = IOMUXC_BASE + (mode & 0x1fc); + shift = (~mode & 0x3) * 8; + + tmp = __REG(reg); + tmp &= ~(0xff << shift); + tmp |= ((mode >> IOMUX_MODE_POS) & 0xff) << shift; + __REG(reg) = tmp; +} + +#if defined(CONFIG_DISPLAY_CPUINFO) +int print_cpuinfo (void) +{ + printf("CPU: Freescale i.MX31 at %d MHz\n", + mx31_get_mcu_main_clk() / 1000000); + return 0; +} +#endif diff --git a/arch/arm/cpu/arm1136/mx31/timer.c b/arch/arm/cpu/arm1136/mx31/timer.c new file mode 100644 index 0000000000..7972ba0dd7 --- /dev/null +++ b/arch/arm/cpu/arm1136/mx31/timer.c @@ -0,0 +1,170 @@ +/* + * (C) Copyright 2007 + * Sascha Hauer, Pengutronix + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +#define TIMER_BASE 0x53f90000 /* General purpose timer 1 */ + +/* General purpose timers registers */ +#define GPTCR __REG(TIMER_BASE) /* Control register */ +#define GPTPR __REG(TIMER_BASE + 0x4) /* Prescaler register */ +#define GPTSR __REG(TIMER_BASE + 0x8) /* Status register */ +#define GPTCNT __REG(TIMER_BASE + 0x24) /* Counter register */ + +/* General purpose timers bitfields */ +#define GPTCR_SWR (1 << 15) /* Software reset */ +#define GPTCR_FRR (1 << 9) /* Freerun / restart */ +#define GPTCR_CLKSOURCE_32 (4 << 6) /* Clock source */ +#define GPTCR_TEN 1 /* Timer enable */ + +static ulong timestamp; +static ulong lastinc; + +/* "time" is measured in 1 / CONFIG_SYS_HZ seconds, "tick" is internal timer period */ +#ifdef CONFIG_MX31_TIMER_HIGH_PRECISION +/* ~0.4% error - measured with stop-watch on 100s boot-delay */ +static inline unsigned long long tick_to_time(unsigned long long tick) +{ + tick *= CONFIG_SYS_HZ; + do_div(tick, CONFIG_MX31_CLK32); + return tick; +} + +static inline unsigned long long time_to_tick(unsigned long long time) +{ + time *= CONFIG_MX31_CLK32; + do_div(time, CONFIG_SYS_HZ); + return time; +} + +static inline unsigned long long us_to_tick(unsigned long long us) +{ + us = us * CONFIG_MX31_CLK32 + 999999; + do_div(us, 1000000); + return us; +} +#else +/* ~2% error */ +#define TICK_PER_TIME ((CONFIG_MX31_CLK32 + CONFIG_SYS_HZ / 2) / CONFIG_SYS_HZ) +#define US_PER_TICK (1000000 / CONFIG_MX31_CLK32) + +static inline unsigned long long tick_to_time(unsigned long long tick) +{ + do_div(tick, TICK_PER_TIME); + return tick; +} + +static inline unsigned long long time_to_tick(unsigned long long time) +{ + return time * TICK_PER_TIME; +} + +static inline unsigned long long us_to_tick(unsigned long long us) +{ + us += US_PER_TICK - 1; + do_div(us, US_PER_TICK); + return us; +} +#endif + +/* The 32768Hz 32-bit timer overruns in 131072 seconds */ +int timer_init (void) +{ + int i; + + /* setup GP Timer 1 */ + GPTCR = GPTCR_SWR; + for (i = 0; i < 100; i++) + GPTCR = 0; /* We have no udelay by now */ + GPTPR = 0; /* 32Khz */ + /* Freerun Mode, PERCLK1 input */ + GPTCR |= GPTCR_CLKSOURCE_32 | GPTCR_TEN; + + return 0; +} + +void reset_timer_masked (void) +{ + /* reset time */ + lastinc = GPTCNT; /* capture current incrementer value time */ + timestamp = 0; /* start "advancing" time stamp from 0 */ +} + +void reset_timer(void) +{ + reset_timer_masked(); +} + +unsigned long long get_ticks (void) +{ + ulong now = GPTCNT; /* current tick value */ + + if (now >= lastinc) /* normal mode (non roll) */ + /* move stamp forward with absolut diff ticks */ + timestamp += (now - lastinc); + else /* we have rollover of incrementer */ + timestamp += (0xFFFFFFFF - lastinc) + now; + lastinc = now; + return timestamp; +} + +ulong get_timer_masked (void) +{ + /* + * get_ticks() returns a long long (64 bit), it wraps in + * 2^64 / CONFIG_MX31_CLK32 = 2^64 / 2^15 = 2^49 ~ 5 * 10^14 (s) ~ + * 5 * 10^9 days... and get_ticks() * CONFIG_SYS_HZ wraps in + * 5 * 10^6 days - long enough. + */ + return tick_to_time(get_ticks()); +} + +ulong get_timer (ulong base) +{ + return get_timer_masked () - base; +} + +void set_timer (ulong t) +{ + timestamp = time_to_tick(t); +} + +/* delay x useconds AND perserve advance timstamp value */ +void __udelay (unsigned long usec) +{ + unsigned long long tmp; + ulong tmo; + + tmo = us_to_tick(usec); + tmp = get_ticks() + tmo; /* get current timestamp */ + + while (get_ticks() < tmp) /* loop till event */ + /*NOP*/; +} + +void reset_cpu (ulong addr) +{ + __REG16(WDOG_BASE) = 4; +} diff --git a/arch/arm/cpu/arm1136/omap24xx/Makefile b/arch/arm/cpu/arm1136/omap24xx/Makefile new file mode 100644 index 0000000000..48dc7e3283 --- /dev/null +++ b/arch/arm/cpu/arm1136/omap24xx/Makefile @@ -0,0 +1,47 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +SOBJS = reset.o + +COBJS = timer.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm1136/omap24xx/reset.S b/arch/arm/cpu/arm1136/omap24xx/reset.S new file mode 100644 index 0000000000..5f8343fe62 --- /dev/null +++ b/arch/arm/cpu/arm1136/omap24xx/reset.S @@ -0,0 +1,42 @@ +/* + * armboot - Startup Code for OMP2420/ARM1136 CPU-core + * + * Copyright (c) 2004 Texas Instruments + * + * Copyright (c) 2001 Marius Gröger + * Copyright (c) 2002 Alex Züpke + * Copyright (c) 2002 Gary Jennejohn + * Copyright (c) 2003 Richard Woodruff + * Copyright (c) 2003 Kshitij + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +.globl reset_cpu +reset_cpu: + ldr r1, rstctl /* get addr for global reset reg */ + mov r3, #0x2 /* full reset pll+mpu */ + str r3, [r1] /* force reset */ + mov r0, r0 +_loop_forever: + b _loop_forever +rstctl: + .word PM_RSTCTRL_WKUP diff --git a/arch/arm/cpu/arm1136/omap24xx/timer.c b/arch/arm/cpu/arm1136/omap24xx/timer.c new file mode 100644 index 0000000000..67547490fd --- /dev/null +++ b/arch/arm/cpu/arm1136/omap24xx/timer.c @@ -0,0 +1,158 @@ +/* + * (C) Copyright 2004 + * Texas Instruments + * Richard Woodruff + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * Alex Zuepke + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +#define TIMER_LOAD_VAL 0 + +/* macro to read the 32 bit timer */ +#define READ_TIMER (*((volatile ulong *)(CONFIG_SYS_TIMERBASE+TCRR))) + +static ulong timestamp; +static ulong lastinc; + +int timer_init (void) +{ + int32_t val; + + /* Start the counter ticking up */ + *((int32_t *) (CONFIG_SYS_TIMERBASE + TLDR)) = TIMER_LOAD_VAL; /* reload value on overflow*/ + val = (CONFIG_SYS_PTV << 2) | BIT5 | BIT1 | BIT0; /* mask to enable timer*/ + *((int32_t *) (CONFIG_SYS_TIMERBASE + TCLR)) = val; /* start timer */ + + reset_timer_masked(); /* init the timestamp and lastinc value */ + + return(0); +} +/* + * timer without interrupts + */ +void reset_timer (void) +{ + reset_timer_masked (); +} + +ulong get_timer (ulong base) +{ + return get_timer_masked () - base; +} + +void set_timer (ulong t) +{ + timestamp = t; +} + +/* delay x useconds AND perserve advance timstamp value */ +void __udelay (unsigned long usec) +{ + ulong tmo, tmp; + + if (usec >= 1000) { /* if "big" number, spread normalization to seconds */ + tmo = usec / 1000; /* start to normalize for usec to ticks per sec */ + tmo *= CONFIG_SYS_HZ; /* find number of "ticks" to wait to achieve target */ + tmo /= 1000; /* finish normalize. */ + } else { /* else small number, don't kill it prior to HZ multiply */ + tmo = usec * CONFIG_SYS_HZ; + tmo /= (1000*1000); + } + + tmp = get_timer (0); /* get current timestamp */ + if ( (tmo + tmp + 1) < tmp )/* if setting this forward will roll time stamp */ + reset_timer_masked (); /* reset "advancing" timestamp to 0, set lastinc value */ + else + tmo += tmp; /* else, set advancing stamp wake up time */ + while (get_timer_masked () < tmo)/* loop till event */ + /*NOP*/; +} + +void reset_timer_masked (void) +{ + /* reset time */ + lastinc = READ_TIMER; /* capture current incrementer value time */ + timestamp = 0; /* start "advancing" time stamp from 0 */ +} + +ulong get_timer_masked (void) +{ + ulong now = READ_TIMER; /* current tick value */ + + if (now >= lastinc) /* normal mode (non roll) */ + timestamp += (now - lastinc); /* move stamp fordward with absoulte diff ticks */ + else /* we have rollover of incrementer */ + timestamp += (0xFFFFFFFF - lastinc) + now; + lastinc = now; + return timestamp; +} + +/* waits specified delay value and resets timestamp */ +void udelay_masked (unsigned long usec) +{ + ulong tmo; + ulong endtime; + signed long diff; + + if (usec >= 1000) { /* if "big" number, spread normalization to seconds */ + tmo = usec / 1000; /* start to normalize for usec to ticks per sec */ + tmo *= CONFIG_SYS_HZ; /* find number of "ticks" to wait to achieve target */ + tmo /= 1000; /* finish normalize. */ + } else { /* else small number, don't kill it prior to HZ multiply */ + tmo = usec * CONFIG_SYS_HZ; + tmo /= (1000*1000); + } + endtime = get_timer_masked () + tmo; + + do { + ulong now = get_timer_masked (); + diff = endtime - now; + } while (diff >= 0); +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk (void) +{ + ulong tbclk; + tbclk = CONFIG_SYS_HZ; + return tbclk; +} diff --git a/arch/arm/cpu/arm1136/start.S b/arch/arm/cpu/arm1136/start.S new file mode 100644 index 0000000000..957f4389b2 --- /dev/null +++ b/arch/arm/cpu/arm1136/start.S @@ -0,0 +1,443 @@ +/* + * armboot - Startup Code for OMP2420/ARM1136 CPU-core + * + * Copyright (c) 2004 Texas Instruments + * + * Copyright (c) 2001 Marius Gröger + * Copyright (c) 2002 Alex Züpke + * Copyright (c) 2002 Gary Jennejohn + * Copyright (c) 2003 Richard Woodruff + * Copyright (c) 2003 Kshitij + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +.globl _start +_start: b reset +#ifdef CONFIG_PRELOADER + ldr pc, _hang + ldr pc, _hang + ldr pc, _hang + ldr pc, _hang + ldr pc, _hang + ldr pc, _hang + ldr pc, _hang + +_hang: + .word do_hang + .word 0x12345678 + .word 0x12345678 + .word 0x12345678 + .word 0x12345678 + .word 0x12345678 + .word 0x12345678 + .word 0x12345678 /* now 16*4=64 */ +#else + 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 + +_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 +_pad: .word 0x12345678 /* now 16*4=64 */ +#endif /* CONFIG_PRELOADER */ +.global _end_vect +_end_vect: + + .balignl 16,0xdeadbeef +/* + ************************************************************************* + * + * Startup Code (reset vector) + * + * do important init only if we don't start from memory! + * setup Memory and board specific bits prior to relocation. + * relocate armboot to ram + * setup stack + * + ************************************************************************* + */ + +_TEXT_BASE: + .word TEXT_BASE + +.globl _armboot_start +_armboot_start: + .word _start + +/* + * These are defined in the board-specific linker script. + */ +.globl _bss_start +_bss_start: + .word __bss_start + +.globl _bss_end +_bss_end: + .word _end + +#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 + +/* + * the actual reset code + */ + +reset: + /* + * set the cpu to SVC32 mode + */ + mrs r0,cpsr + bic r0,r0,#0x1f + orr r0,r0,#0xd3 + msr cpsr,r0 + +#ifdef CONFIG_OMAP2420H4 + /* Copy vectors to mask ROM indirect addr */ + adr r0, _start /* r0 <- current position of code */ + add r0, r0, #4 /* skip reset vector */ + mov r2, #64 /* r2 <- size to copy */ + add r2, r0, r2 /* r2 <- source end address */ + mov r1, #SRAM_OFFSET0 /* build vect addr */ + mov r3, #SRAM_OFFSET1 + add r1, r1, r3 + mov r3, #SRAM_OFFSET2 + add r1, r1, r3 +next: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end address [r2] */ + bne next /* loop until equal */ + bl cpy_clk_code /* put dpll adjust code behind vectors */ +#endif + /* the mask ROM code should have PLL and others stable */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl cpu_init_crit +#endif + +#ifndef CONFIG_SKIP_RELOCATE_UBOOT +relocate: /* relocate U-Boot to RAM */ + adr r0, _start /* r0 <- current position of code */ + ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ + cmp r0, r1 /* don't reloc during debug */ +#ifndef CONFIG_PRELOADER + beq stack_setup +#endif /* CONFIG_PRELOADER */ + + ldr r2, _armboot_start + ldr r3, _bss_start + sub r2, r3, r2 /* r2 <- size of armboot */ + add r2, r0, r2 /* r2 <- source end address */ + +copy_loop: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end addreee [r2] */ + ble copy_loop +#endif /* CONFIG_SKIP_RELOCATE_UBOOT */ + + /* Set up the stack */ +stack_setup: + ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ +#ifdef CONFIG_PRELOADER + sub sp, r0, #128 /* leave 32 words for abort-stack */ +#else + sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */ + sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ +#ifdef CONFIG_USE_IRQ + sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) +#endif + sub sp, r0, #12 /* leave 3 words for abort-stack */ +#endif /* CONFIG_PRELOADER */ + +clear_bss: + ldr r0, _bss_start /* find start of bss segment */ + ldr r1, _bss_end /* stop here */ + mov r2, #0x00000000 /* clear */ + +#ifndef CONFIG_PRELOADER +clbss_l:str r2, [r0] /* clear loop... */ + add r0, r0, #4 + cmp r0, r1 + bne clbss_l +#endif + + ldr pc, _start_armboot + +#ifdef CONFIG_NAND_SPL +_start_armboot: .word nand_boot +#else +#ifdef CONFIG_ONENAND_IPL +_start_armboot: .word start_oneboot +#else +_start_armboot: .word start_armboot +#endif /* CONFIG_ONENAND_IPL */ +#endif /* CONFIG_NAND_SPL */ + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + ************************************************************************* + */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT +cpu_init_crit: + /* + * flush v4 I/D caches + */ + mov r0, #0 + mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ + mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ + + /* + * disable MMU stuff and caches + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) + bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) + orr r0, r0, #0x00000002 @ set bit 2 (A) Align + orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache + mcr p15, 0, r0, c1, c0, 0 + + /* + * Jump to board specific initialization... The Mask ROM will have already initialized + * basic memory. Go here to bump up clock rate and handle wake up conditions. + */ + mov ip, lr /* persevere link reg across call */ + bl lowlevel_init /* go setup pll,mux,memory */ + mov lr, ip /* restore link */ + mov pc, lr /* back to my caller */ +#endif /* CONFIG_SKIP_LOWLEVEL_INIT */ + +#ifndef CONFIG_PRELOADER +/* + ************************************************************************* + * + * 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 +#define I_BIT 0x80 + +/* + * use bad_save_user_regs for abort/prefetch/undef/swi ... + * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling + */ + + .macro bad_save_user_regs + sub sp, sp, #S_FRAME_SIZE @ carve out a frame on current user stack + stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12 + + ldr r2, _armboot_start + sub r2, r2, #(CONFIG_SYS_MALLOC_LEN) + sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack + ldmia r2, {r2 - r3} @ get values for "aborted" pc and cpsr (into parm regs) + add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack + + add r5, sp, #S_SP + mov r1, lr + stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr + mov r0, sp @ save current stack into r0 (param register) + .endm + + .macro irq_save_user_regs + sub sp, sp, #S_FRAME_SIZE + stmia sp, {r0 - r12} @ Calling r0-r12 + add r8, sp, #S_PC @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good. + 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, _armboot_start @ setup our mode stack (enter in banked mode) + sub r13, r13, #(CONFIG_SYS_MALLOC_LEN) @ move past malloc pool + sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ move to reserved a couple spots for abort stack + + str lr, [r13] @ save caller lr in position 0 of saved stack + mrs lr, spsr @ get the spsr + str lr, [r13, #4] @ save spsr in position 1 of saved stack + + mov r13, #MODE_SVC @ prepare SVC-Mode + @ msr spsr_c, r13 + msr spsr, r13 @ switch modes, make sure moves will execute + mov lr, pc @ capture return pc + movs pc, lr @ jump to next instruction & switch modes. + .endm + + .macro get_bad_stack_swi + sub r13, r13, #4 @ space on current stack for scratch reg. + str r0, [r13] @ save R0's value. + ldr r0, _armboot_start @ get data regions start + sub r0, r0, #(CONFIG_SYS_MALLOC_LEN) @ move past malloc pool + sub r0, r0, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ move past gbl and a couple spots for abort stack + str lr, [r0] @ save caller lr in position 0 of saved stack + mrs r0, spsr @ get the spsr + str lr, [r0, #4] @ save spsr in position 1 of saved stack + ldr r0, [r13] @ restore r0 + add r13, r13, #4 @ pop stack entry + .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 +#endif /* CONFIG_PRELOADER */ + +/* + * exception handlers + */ +#ifdef CONFIG_PRELOADER + .align 5 +do_hang: + ldr sp, _TEXT_BASE /* use 32 words about stack */ + bl hang /* hang and never return */ +#else /* !CONFIG_PRELOADER */ + .align 5 +undefined_instruction: + get_bad_stack + bad_save_user_regs + bl do_undefined_instruction + + .align 5 +software_interrupt: + get_bad_stack_swi + 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 + /* someone ought to write a more effiction fiq_save_user_regs */ + irq_save_user_regs + bl do_fiq + 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 + .align 5 +.global arm1136_cache_flush +arm1136_cache_flush: + mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache + mov pc, lr @ back to caller +#endif /* CONFIG_PRELOADER */ diff --git a/arch/arm/cpu/arm1136/u-boot.lds b/arch/arm/cpu/arm1136/u-boot.lds new file mode 100644 index 0000000000..e7eefc972c --- /dev/null +++ b/arch/arm/cpu/arm1136/u-boot.lds @@ -0,0 +1,64 @@ +/* + * (C) Copyright 2009 + * Ilya Yanok, Emcraft Systems Ltd, + * + * Copyright (C) 2005-2007 Samsung Electronics + * Kyungin Park + * + * Copyright (c) 2004 Texas Instruments + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + arch/arm/cpu/arm1136/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = ALIGN(4); + __bss_start = .; + .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } + _end = .; +} diff --git a/arch/arm/cpu/arm1176/Makefile b/arch/arm/cpu/arm1176/Makefile new file mode 100644 index 0000000000..1ca9199a64 --- /dev/null +++ b/arch/arm/cpu/arm1176/Makefile @@ -0,0 +1,50 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2008 +# Guennadi Liakhovetki, DENX Software Engineering, +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(CPU).a + +START = start.o +COBJS = cpu.o + +SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm1176/config.mk b/arch/arm/cpu/arm1176/config.mk new file mode 100644 index 0000000000..14346cfff3 --- /dev/null +++ b/arch/arm/cpu/arm1176/config.mk @@ -0,0 +1,32 @@ +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float + +# Make ARMv5 to allow more compilers to work, even though its v6. +PLATFORM_CPPFLAGS += -march=armv5t +# ========================================================================= +# +# Supply options according to compiler version +# +# ========================================================================= +PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/arch/arm/cpu/arm1176/cpu.c b/arch/arm/cpu/arm1176/cpu.c new file mode 100644 index 0000000000..befa0cdcc4 --- /dev/null +++ b/arch/arm/cpu/arm1176/cpu.c @@ -0,0 +1,70 @@ +/* + * (C) Copyright 2004 Texas Insturments + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * CPU specific code + */ + +#include +#include +#ifdef CONFIG_S3C64XX +#include +#endif +#include + +static void cache_flush (void); + +int cleanup_before_linux (void) +{ + /* + * this function is called just before we call linux + * it prepares the processor for linux + * + * we turn off caches etc ... + */ + + disable_interrupts (); + + /* turn off I/D-cache */ + icache_disable(); + dcache_disable(); + /* flush I/D-cache */ + cache_flush(); + + return 0; +} + +/* flush I/D-cache */ +static void cache_flush (void) +{ + /* invalidate both caches and flush btb */ + asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (0)); + /* mem barrier to sync things */ + asm ("mcr p15, 0, %0, c7, c10, 4": :"r" (0)); +} diff --git a/arch/arm/cpu/arm1176/s3c64xx/Makefile b/arch/arm/cpu/arm1176/s3c64xx/Makefile new file mode 100644 index 0000000000..b527939137 --- /dev/null +++ b/arch/arm/cpu/arm1176/s3c64xx/Makefile @@ -0,0 +1,50 @@ +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2008 +# Guennadi Liakhovetki, DENX Software Engineering, +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +SOBJS = reset.o + +COBJS-$(CONFIG_S3C6400) += cpu_init.o speed.o +COBJS-y += timer.o + +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y)) + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm1176/s3c64xx/config.mk b/arch/arm/cpu/arm1176/s3c64xx/config.mk new file mode 100644 index 0000000000..14346cfff3 --- /dev/null +++ b/arch/arm/cpu/arm1176/s3c64xx/config.mk @@ -0,0 +1,32 @@ +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float + +# Make ARMv5 to allow more compilers to work, even though its v6. +PLATFORM_CPPFLAGS += -march=armv5t +# ========================================================================= +# +# Supply options according to compiler version +# +# ========================================================================= +PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/arch/arm/cpu/arm1176/s3c64xx/cpu_init.S b/arch/arm/cpu/arm1176/s3c64xx/cpu_init.S new file mode 100644 index 0000000000..df88cba342 --- /dev/null +++ b/arch/arm/cpu/arm1176/s3c64xx/cpu_init.S @@ -0,0 +1,135 @@ +/* + * Originates from Samsung's u-boot 1.1.6 port to S3C6400 / SMDK6400 + * + * Copyright (C) 2008 + * Guennadi Liakhovetki, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + + .globl mem_ctrl_asm_init +mem_ctrl_asm_init: + /* DMC1 base address 0x7e001000 */ + ldr r0, =ELFIN_DMC1_BASE + + ldr r1, =0x4 + str r1, [r0, #INDEX_DMC_MEMC_CMD] + + ldr r1, =DMC_DDR_REFRESH_PRD + str r1, [r0, #INDEX_DMC_REFRESH_PRD] + + ldr r1, =DMC_DDR_CAS_LATENCY + str r1, [r0, #INDEX_DMC_CAS_LATENCY] + + ldr r1, =DMC_DDR_t_DQSS + str r1, [r0, #INDEX_DMC_T_DQSS] + + ldr r1, =DMC_DDR_t_MRD + str r1, [r0, #INDEX_DMC_T_MRD] + + ldr r1, =DMC_DDR_t_RAS + str r1, [r0, #INDEX_DMC_T_RAS] + + ldr r1, =DMC_DDR_t_RC + str r1, [r0, #INDEX_DMC_T_RC] + + ldr r1, =DMC_DDR_t_RCD + ldr r2, =DMC_DDR_schedule_RCD + orr r1, r1, r2 + str r1, [r0, #INDEX_DMC_T_RCD] + + ldr r1, =DMC_DDR_t_RFC + ldr r2, =DMC_DDR_schedule_RFC + orr r1, r1, r2 + str r1, [r0, #INDEX_DMC_T_RFC] + + ldr r1, =DMC_DDR_t_RP + ldr r2, =DMC_DDR_schedule_RP + orr r1, r1, r2 + str r1, [r0, #INDEX_DMC_T_RP] + + ldr r1, =DMC_DDR_t_RRD + str r1, [r0, #INDEX_DMC_T_RRD] + + ldr r1, =DMC_DDR_t_WR + str r1, [r0, #INDEX_DMC_T_WR] + + ldr r1, =DMC_DDR_t_WTR + str r1, [r0, #INDEX_DMC_T_WTR] + + ldr r1, =DMC_DDR_t_XP + str r1, [r0, #INDEX_DMC_T_XP] + + ldr r1, =DMC_DDR_t_XSR + str r1, [r0, #INDEX_DMC_T_XSR] + + ldr r1, =DMC_DDR_t_ESR + str r1, [r0, #INDEX_DMC_T_ESR] + + ldr r1, =DMC1_MEM_CFG + str r1, [r0, #INDEX_DMC_MEMORY_CFG] + + ldr r1, =DMC1_MEM_CFG2 + str r1, [r0, #INDEX_DMC_MEMORY_CFG2] + + ldr r1, =DMC1_CHIP0_CFG + str r1, [r0, #INDEX_DMC_CHIP_0_CFG] + + ldr r1, =DMC_DDR_32_CFG + str r1, [r0, #INDEX_DMC_USER_CONFIG] + + /* DMC0 DDR Chip 0 configuration direct command reg */ + ldr r1, =DMC_NOP0 + str r1, [r0, #INDEX_DMC_DIRECT_CMD] + + /* Precharge All */ + ldr r1, =DMC_PA0 + str r1, [r0, #INDEX_DMC_DIRECT_CMD] + + /* Auto Refresh 2 time */ + ldr r1, =DMC_AR0 + str r1, [r0, #INDEX_DMC_DIRECT_CMD] + str r1, [r0, #INDEX_DMC_DIRECT_CMD] + + /* MRS */ + ldr r1, =DMC_mDDR_EMR0 + str r1, [r0, #INDEX_DMC_DIRECT_CMD] + + /* Mode Reg */ + ldr r1, =DMC_mDDR_MR0 + str r1, [r0, #INDEX_DMC_DIRECT_CMD] + + /* Enable DMC1 */ + mov r1, #0x0 + str r1, [r0, #INDEX_DMC_MEMC_CMD] + +check_dmc1_ready: + ldr r1, [r0, #INDEX_DMC_MEMC_STATUS] + mov r2, #0x3 + and r1, r1, r2 + cmp r1, #0x1 + bne check_dmc1_ready + nop + + mov pc, lr + + .ltorg diff --git a/arch/arm/cpu/arm1176/s3c64xx/reset.S b/arch/arm/cpu/arm1176/s3c64xx/reset.S new file mode 100644 index 0000000000..eae572e4fd --- /dev/null +++ b/arch/arm/cpu/arm1176/s3c64xx/reset.S @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2009 Samsung Electronics. + * Minkyu Kang + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +.globl reset_cpu +reset_cpu: + ldr r1, =ELFIN_CLOCK_POWER_BASE + ldr r2, [r1, #SYS_ID_OFFSET] + ldr r3, =0xffff + and r2, r3, r2, lsr #12 + str r2, [r1, #SW_RST_OFFSET] +_loop_forever: + b _loop_forever diff --git a/arch/arm/cpu/arm1176/s3c64xx/speed.c b/arch/arm/cpu/arm1176/s3c64xx/speed.c new file mode 100644 index 0000000000..11962acade --- /dev/null +++ b/arch/arm/cpu/arm1176/s3c64xx/speed.c @@ -0,0 +1,145 @@ +/* + * (C) Copyright 2001-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2002 + * David Mueller, ELSOFT AG, d.mueller@elsoft.ch + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * This code should work for both the S3C2400 and the S3C2410 + * as they seem to have the same PLL and clock machinery inside. + * The different address mapping is handled by the s3c24xx.h files below. + */ + +#include +#include + +#define APLL 0 +#define MPLL 1 +#define EPLL 2 + +/* ------------------------------------------------------------------------- */ +/* + * NOTE: This describes the proper use of this file. + * + * CONFIG_SYS_CLK_FREQ should be defined as the input frequency of the PLL. + * + * get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of + * the specified bus in HZ. + */ +/* ------------------------------------------------------------------------- */ + +static ulong get_PLLCLK(int pllreg) +{ + ulong r, m, p, s; + + switch (pllreg) { + case APLL: + r = APLL_CON_REG; + break; + case MPLL: + r = MPLL_CON_REG; + break; + case EPLL: + r = EPLL_CON0_REG; + break; + default: + hang(); + } + + m = (r >> 16) & 0x3ff; + p = (r >> 8) & 0x3f; + s = r & 0x7; + + return m * (CONFIG_SYS_CLK_FREQ / (p * (1 << s))); +} + +/* return ARMCORE frequency */ +ulong get_ARMCLK(void) +{ + ulong div; + + div = CLK_DIV0_REG; + + return get_PLLCLK(APLL) / ((div & 0x7) + 1); +} + +/* return FCLK frequency */ +ulong get_FCLK(void) +{ + return get_PLLCLK(APLL); +} + +/* return HCLK frequency */ +ulong get_HCLK(void) +{ + ulong fclk; + + uint hclkx2_div = ((CLK_DIV0_REG >> 9) & 0x7) + 1; + uint hclk_div = ((CLK_DIV0_REG >> 8) & 0x1) + 1; + + /* + * Bit 7 exists on s3c6410, and not on s3c6400, it is reserved on + * s3c6400 and is always 0, and it is indeed running in ASYNC mode + */ + if (OTHERS_REG & 0x80) + fclk = get_FCLK(); /* SYNC Mode */ + else + fclk = get_PLLCLK(MPLL); /* ASYNC Mode */ + + return fclk / (hclk_div * hclkx2_div); +} + +/* return PCLK frequency */ +ulong get_PCLK(void) +{ + ulong fclk; + uint hclkx2_div = ((CLK_DIV0_REG >> 9) & 0x7) + 1; + uint pre_div = ((CLK_DIV0_REG >> 12) & 0xf) + 1; + + if (OTHERS_REG & 0x80) + fclk = get_FCLK(); /* SYNC Mode */ + else + fclk = get_PLLCLK(MPLL); /* ASYNC Mode */ + + return fclk / (hclkx2_div * pre_div); +} + +/* return UCLK frequency */ +ulong get_UCLK(void) +{ + return get_PLLCLK(EPLL); +} + +int print_cpuinfo(void) +{ + printf("\nCPU: S3C6400@%luMHz\n", get_ARMCLK() / 1000000); + printf(" Fclk = %luMHz, Hclk = %luMHz, Pclk = %luMHz ", + get_FCLK() / 1000000, get_HCLK() / 1000000, + get_PCLK() / 1000000); + + if (OTHERS_REG & 0x80) + printf("(SYNC Mode) \n"); + else + printf("(ASYNC Mode) \n"); + return 0; +} diff --git a/arch/arm/cpu/arm1176/s3c64xx/timer.c b/arch/arm/cpu/arm1176/s3c64xx/timer.c new file mode 100644 index 0000000000..9768319efa --- /dev/null +++ b/arch/arm/cpu/arm1176/s3c64xx/timer.c @@ -0,0 +1,177 @@ +/* + * (C) Copyright 2003 + * Texas Instruments + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * (C) Copyright 2002-2004 + * Gary Jennejohn, DENX Software Engineering, + * + * (C) Copyright 2004 + * Philippe Robin, ARM Ltd. + * + * (C) Copyright 2008 + * Guennadi Liakhovetki, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include + +static ulong timer_load_val; + +#define PRESCALER 167 + +static s3c64xx_timers *s3c64xx_get_base_timers(void) +{ + return (s3c64xx_timers *)ELFIN_TIMER_BASE; +} + +/* macro to read the 16 bit timer */ +static inline ulong read_timer(void) +{ + s3c64xx_timers *const timers = s3c64xx_get_base_timers(); + + return timers->TCNTO4; +} + +/* Internal tick units */ +/* Last decremneter snapshot */ +static unsigned long lastdec; +/* Monotonic incrementing timer */ +static unsigned long long timestamp; + +int timer_init(void) +{ + s3c64xx_timers *const timers = s3c64xx_get_base_timers(); + + /* use PWM Timer 4 because it has no output */ + /* + * We use the following scheme for the timer: + * Prescaler is hard fixed at 167, divider at 1/4. + * This gives at PCLK frequency 66MHz approx. 10us ticks + * The timer is set to wrap after 100s, at 66MHz this obviously + * happens after 10,000,000 ticks. A long variable can thus + * keep values up to 40,000s, i.e., 11 hours. This should be + * enough for most uses:-) Possible optimizations: select a + * binary-friendly frequency, e.g., 1ms / 128. Also calculate + * the prescaler automatically for other PCLK frequencies. + */ + timers->TCFG0 = PRESCALER << 8; + if (timer_load_val == 0) { + timer_load_val = get_PCLK() / PRESCALER * (100 / 4); /* 100s */ + timers->TCFG1 = (timers->TCFG1 & ~0xf0000) | 0x20000; + } + + /* load value for 10 ms timeout */ + lastdec = timers->TCNTB4 = timer_load_val; + /* auto load, manual update of Timer 4 */ + timers->TCON = (timers->TCON & ~0x00700000) | TCON_4_AUTO | + TCON_4_UPDATE; + + /* auto load, start Timer 4 */ + timers->TCON = (timers->TCON & ~0x00700000) | TCON_4_AUTO | COUNT_4_ON; + timestamp = 0; + + return 0; +} + +/* + * timer without interrupts + */ + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + ulong now = read_timer(); + + if (lastdec >= now) { + /* normal mode */ + timestamp += lastdec - now; + } else { + /* we have an overflow ... */ + timestamp += lastdec + timer_load_val - now; + } + lastdec = now; + + return timestamp; +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + /* We overrun in 100s */ + return (ulong)(timer_load_val / 100); +} + +void reset_timer_masked(void) +{ + /* reset time */ + lastdec = read_timer(); + timestamp = 0; +} + +void reset_timer(void) +{ + reset_timer_masked(); +} + +ulong get_timer_masked(void) +{ + unsigned long long res = get_ticks(); + do_div (res, (timer_load_val / (100 * CONFIG_SYS_HZ))); + return res; +} + +ulong get_timer(ulong base) +{ + return get_timer_masked() - base; +} + +void set_timer(ulong t) +{ + timestamp = t * (timer_load_val / (100 * CONFIG_SYS_HZ)); +} + +void __udelay(unsigned long usec) +{ + unsigned long long tmp; + ulong tmo; + + tmo = (usec + 9) / 10; + tmp = get_ticks() + tmo; /* get current timestamp */ + + while (get_ticks() < tmp)/* loop till event */ + /*NOP*/; +} diff --git a/arch/arm/cpu/arm1176/start.S b/arch/arm/cpu/arm1176/start.S new file mode 100644 index 0000000000..e2b6c9b08d --- /dev/null +++ b/arch/arm/cpu/arm1176/start.S @@ -0,0 +1,468 @@ +/* + * armboot - Startup Code for S3C6400/ARM1176 CPU-core + * + * Copyright (c) 2007 Samsung Electronics + * + * Copyright (C) 2008 + * Guennadi Liakhovetki, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * 2007-09-21 - Restructured codes by jsgood (jsgood.yang@samsung.com) + * 2007-09-21 - Added MoviNAND and OneNAND boot codes by + * jsgood (jsgood.yang@samsung.com) + * Base codes by scsuh (sc.suh) + */ + +#include +#include +#ifdef CONFIG_ENABLE_MMU +#include +#endif +#ifdef CONFIG_S3C64XX +#include +#endif + +#if !defined(CONFIG_ENABLE_MMU) && !defined(CONFIG_SYS_PHY_UBOOT_BASE) +#define CONFIG_SYS_PHY_UBOOT_BASE CONFIG_SYS_UBOOT_BASE +#endif + +/* + ************************************************************************* + * + * Jump vector table as in table 3.1 in [1] + * + ************************************************************************* + */ + +.globl _start +_start: b reset +#ifndef CONFIG_NAND_SPL + 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 + +_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 +_pad: + .word 0x12345678 /* now 16*4=64 */ +#else + . = _start + 64 +#endif + +.global _end_vect +_end_vect: + .balignl 16,0xdeadbeef +/* + ************************************************************************* + * + * Startup Code (reset vector) + * + * do important init only if we don't start from memory! + * setup Memory and board specific bits prior to relocation. + * relocate armboot to ram + * setup stack + * + ************************************************************************* + */ + +_TEXT_BASE: + .word TEXT_BASE + +/* + * Below variable is very important because we use MMU in U-Boot. + * Without it, we cannot run code correctly before MMU is ON. + * by scsuh. + */ +_TEXT_PHY_BASE: + .word CONFIG_SYS_PHY_UBOOT_BASE + +.globl _armboot_start +_armboot_start: + .word _start + +/* + * These are defined in the board-specific linker script. + */ +.globl _bss_start +_bss_start: + .word __bss_start + +.globl _bss_end +_bss_end: + .word _end + +/* + * the actual reset code + */ + +reset: + /* + * set the cpu to SVC32 mode + */ + mrs r0, cpsr + bic r0, r0, #0x3f + orr r0, r0, #0xd3 + msr cpsr, r0 + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + ************************************************************************* + */ + /* + * we do sys-critical inits only at reboot, + * not when booting from ram! + */ +cpu_init_crit: + /* + * When booting from NAND - it has definitely been a reset, so, no need + * to flush caches and disable the MMU + */ +#ifndef CONFIG_NAND_SPL + /* + * flush v4 I/D caches + */ + mov r0, #0 + mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ + mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ + + /* + * disable MMU stuff and caches + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) + bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) + orr r0, r0, #0x00000002 @ set bit 2 (A) Align + orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache + /* Prepare to disable the MMU */ + adr r1, mmu_disable_phys + /* We presume we're within the first 1024 bytes */ + and r1, r1, #0x3fc + ldr r2, _TEXT_PHY_BASE + ldr r3, =0xfff00000 + and r2, r2, r3 + orr r2, r2, r1 + b mmu_disable + + .align 5 + /* Run in a single cache-line */ +mmu_disable: + mcr p15, 0, r0, c1, c0, 0 + nop + nop + mov pc, r2 +#endif + +mmu_disable_phys: +#ifdef CONFIG_S3C64XX + /* Peri port setup */ + ldr r0, =0x70000000 + orr r0, r0, #0x13 + mcr p15,0,r0,c15,c2,4 @ 256M (0x70000000 - 0x7fffffff) +#endif + + /* + * Go setup Memory and board specific bits prior to relocation. + */ + bl lowlevel_init /* go setup pll,mux,memory */ + +after_copy: +#ifdef CONFIG_ENABLE_MMU +enable_mmu: + /* enable domain access */ + ldr r5, =0x0000ffff + mcr p15, 0, r5, c3, c0, 0 /* load domain access register */ + + /* Set the TTB register */ + ldr r0, _mmu_table_base + ldr r1, =CONFIG_SYS_PHY_UBOOT_BASE + ldr r2, =0xfff00000 + bic r0, r0, r2 + orr r1, r0, r1 + mcr p15, 0, r1, c2, c0, 0 + + /* Enable the MMU */ + mrc p15, 0, r0, c1, c0, 0 + orr r0, r0, #1 /* Set CR_M to enable MMU */ + + /* Prepare to enable the MMU */ + adr r1, skip_hw_init + and r1, r1, #0x3fc + ldr r2, _TEXT_BASE + ldr r3, =0xfff00000 + and r2, r2, r3 + orr r2, r2, r1 + b mmu_enable + + .align 5 + /* Run in a single cache-line */ +mmu_enable: + + mcr p15, 0, r0, c1, c0, 0 + nop + nop + mov pc, r2 +#endif + +skip_hw_init: + /* Set up the stack */ +stack_setup: + ldr r0, =CONFIG_SYS_UBOOT_BASE /* base of copy in DRAM */ + sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */ + sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ + sub sp, r0, #12 /* leave 3 words for abort-stack */ + +clear_bss: + ldr r0, _bss_start /* find start of bss segment */ + ldr r1, _bss_end /* stop here */ + mov r2, #0 /* clear */ + +clbss_l: + str r2, [r0] /* clear loop... */ + add r0, r0, #4 + cmp r0, r1 + ble clbss_l + +#ifndef CONFIG_NAND_SPL + ldr pc, _start_armboot + +_start_armboot: + .word start_armboot +#else + b nand_boot +/* .word nand_boot*/ +#endif + +#ifdef CONFIG_ENABLE_MMU +_mmu_table_base: + .word mmu_table +#endif + +#ifndef CONFIG_NAND_SPL +/* + * we assume that cache operation is done before. (eg. cleanup_before_linux()) + * actually, we don't need to do anything about cache if not use d-cache in + * U-Boot. So, in this function we clean only MMU. by scsuh + * + * void theLastJump(void *kernel, int arch_num, uint boot_params); + */ +#ifdef CONFIG_ENABLE_MMU + .globl theLastJump +theLastJump: + mov r9, r0 + ldr r3, =0xfff00000 + ldr r4, _TEXT_PHY_BASE + adr r5, phy_last_jump + bic r5, r5, r3 + orr r5, r5, r4 + mov pc, r5 +phy_last_jump: + /* + * disable MMU stuff + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x00002300 /* clear bits 13, 9:8 (--V- --RS) */ + bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */ + orr r0, r0, #0x00000002 /* set bit 2 (A) Align */ + orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */ + mcr p15, 0, r0, c1, c0, 0 + + mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ + + mov r0, #0 + mov pc, r9 +#endif +/* + ************************************************************************* + * + * 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 +#define I_BIT 0x80 + +/* + * use bad_save_user_regs for abort/prefetch/undef/swi ... + */ + + .macro bad_save_user_regs + /* carve out a frame on current user stack */ + sub sp, sp, #S_FRAME_SIZE + /* Save user registers (now in svc mode) r0-r12 */ + stmia sp, {r0 - r12} + + ldr r2, _armboot_start + sub r2, r2, #(CONFIG_SYS_MALLOC_LEN) + /* set base 2 words into abort stack */ + sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) + /* get values for "aborted" pc and cpsr (into parm regs) */ + ldmia r2, {r2 - r3} + /* grab pointer to old stack */ + add r0, sp, #S_FRAME_SIZE + + add r5, sp, #S_SP + mov r1, lr + /* save sp_SVC, lr_SVC, pc, cpsr */ + stmia r5, {r0 - r3} + /* save current stack into r0 (param register) */ + mov r0, sp + .endm + + .macro get_bad_stack + /* setup our mode stack (enter in banked mode) */ + ldr r13, _armboot_start + /* move past malloc pool */ + sub r13, r13, #(CONFIG_SYS_MALLOC_LEN) + /* move to reserved a couple spots for abort stack */ + sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE + 8) + + /* save caller lr in position 0 of saved stack */ + str lr, [r13] + /* get the spsr */ + mrs lr, spsr + /* save spsr in position 1 of saved stack */ + str lr, [r13, #4] + + /* prepare SVC-Mode */ + mov r13, #MODE_SVC + @ msr spsr_c, r13 + /* switch modes, make sure moves will execute */ + msr spsr, r13 + /* capture return pc */ + mov lr, pc + /* jump to next instruction & switch modes. */ + movs pc, lr + .endm + + .macro get_bad_stack_swi + /* space on current stack for scratch reg. */ + sub r13, r13, #4 + /* save R0's value. */ + str r0, [r13] + /* get data regions start */ + ldr r0, _armboot_start + /* move past malloc pool */ + sub r0, r0, #(CONFIG_SYS_MALLOC_LEN) + /* move past gbl and a couple spots for abort stack */ + sub r0, r0, #(CONFIG_SYS_GBL_DATA_SIZE + 8) + /* save caller lr in position 0 of saved stack */ + str lr, [r0] + /* get the spsr */ + mrs r0, spsr + /* save spsr in position 1 of saved stack */ + str lr, [r0, #4] + /* restore r0 */ + ldr r0, [r13] + /* pop stack entry */ + add r13, r13, #4 + .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_swi + 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 + + .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 /* CONFIG_NAND_SPL */ diff --git a/arch/arm/cpu/arm1176/u-boot.lds b/arch/arm/cpu/arm1176/u-boot.lds new file mode 100644 index 0000000000..8969587e8c --- /dev/null +++ b/arch/arm/cpu/arm1176/u-boot.lds @@ -0,0 +1,56 @@ +/* + * (C) Copyright 2002-2004 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + arch/arm/cpu/arm1176/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = ALIGN(4); + __bss_start = .; + .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } + _end = .; +} diff --git a/arch/arm/cpu/arm720t/Makefile b/arch/arm/cpu/arm720t/Makefile new file mode 100644 index 0000000000..d5ac7d3fd9 --- /dev/null +++ b/arch/arm/cpu/arm720t/Makefile @@ -0,0 +1,47 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(CPU).a + +START = start.o +COBJS = interrupts.o cpu.o + +SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm720t/config.mk b/arch/arm/cpu/arm720t/config.mk new file mode 100644 index 0000000000..3844c626af --- /dev/null +++ b/arch/arm/cpu/arm720t/config.mk @@ -0,0 +1,33 @@ +# +# (C) Copyright 2002 +# Sysgo Real-Time Solutions, GmbH +# Marius Groeger +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float + +PLATFORM_CPPFLAGS += -march=armv4 -mtune=arm7tdmi +# ========================================================================= +# +# Supply options according to compiler version +# +# ========================================================================= +PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/arch/arm/cpu/arm720t/cpu.c b/arch/arm/cpu/arm720t/cpu.c new file mode 100644 index 0000000000..88c71bfe18 --- /dev/null +++ b/arch/arm/cpu/arm720t/cpu.c @@ -0,0 +1,90 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * CPU specific code + */ + +#include +#include +#include +#include +#include + +#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO) +static void cache_flush(void); +#endif + +int cleanup_before_linux (void) +{ + /* + * this function is called just before we call linux + * it prepares the processor for linux + * + * we turn off caches etc ... + * and we set the CPU-speed to 73 MHz - see start.S for details + */ + +#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO) + disable_interrupts (); + + /* turn off I-cache */ + icache_disable(); + dcache_disable(); + + /* flush I-cache */ + cache_flush(); +#ifdef CONFIG_ARM7_REVD + /* go to high speed */ + IO_SYSCON3 = (IO_SYSCON3 & ~CLKCTL) | CLKCTL_73; +#endif +#elif defined(CONFIG_NETARM) || defined(CONFIG_S3C4510B) || defined(CONFIG_LPC2292) + disable_interrupts (); + /* Nothing more needed */ +#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR) + /* No cleanup before linux for IntegratorAP/CM720T as yet */ +#else +#error No cleanup_before_linux() defined for this CPU type +#endif + return 0; +} + +#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO) +/* flush I/D-cache */ +static void cache_flush (void) +{ + unsigned long i = 0; + + asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (i)); +} +#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR) + /* No specific cache setup for IntegratorAP/CM720T as yet */ + void icache_enable (void) + { + } +#endif diff --git a/arch/arm/cpu/arm720t/interrupts.c b/arch/arm/cpu/arm720t/interrupts.c new file mode 100644 index 0000000000..eb8d425318 --- /dev/null +++ b/arch/arm/cpu/arm720t/interrupts.c @@ -0,0 +1,316 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include + +#ifndef CONFIG_NETARM +/* we always count down the max. */ +#define TIMER_LOAD_VAL 0xffff +/* macro to read the 16 bit timer */ +#define READ_TIMER (IO_TC1D & 0xffff) + +#ifdef CONFIG_LPC2292 +#undef READ_TIMER +#define READ_TIMER (0xFFFFFFFF - GET32(T0TC)) +#endif + +#else +#define IRQEN (*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_INTR_ENABLE)) +#define TM2CTRL (*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_TIMER2_CONTROL)) +#define TM2STAT (*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_TIMER2_STATUS)) +#define TIMER_LOAD_VAL NETARM_GEN_TSTAT_CTC_MASK +#define READ_TIMER (TM2STAT & NETARM_GEN_TSTAT_CTC_MASK) +#endif + +#ifdef CONFIG_S3C4510B +/* require interrupts for the S3C4510B */ +# ifndef CONFIG_USE_IRQ +# error CONFIG_USE_IRQ _must_ be defined when using CONFIG_S3C4510B +# else +static struct _irq_handler IRQ_HANDLER[N_IRQS]; +# endif +#endif /* CONFIG_S3C4510B */ + +#ifdef CONFIG_USE_IRQ +void do_irq (struct pt_regs *pt_regs) +{ +#if defined(CONFIG_S3C4510B) + unsigned int pending; + + while ( (pending = GET_REG( REG_INTOFFSET)) != 0x54) { /* sentinal value for no pending interrutps */ + IRQ_HANDLER[pending>>2].m_func( IRQ_HANDLER[pending>>2].m_data); + + /* clear pending interrupt */ + PUT_REG( REG_INTPEND, (1<<(pending>>2))); + } +#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR) + /* No do_irq() for IntegratorAP/CM720T as yet */ +#elif defined(CONFIG_LPC2292) + + void (*pfnct)(void); + + pfnct = (void (*)(void))VICVectAddr; + + (*pfnct)(); +#else +#error do_irq() not defined for this CPU type +#endif +} +#endif + +#ifdef CONFIG_S3C4510B +static void default_isr( void *data) { + printf ("default_isr(): called for IRQ %d\n", (int)data); +} + +static void timer_isr( void *data) { + unsigned int *pTime = (unsigned int *)data; + + (*pTime)++; + if ( !(*pTime % (CONFIG_SYS_HZ/4))) { + /* toggle LED 0 */ + PUT_REG( REG_IOPDATA, GET_REG(REG_IOPDATA) ^ 0x1); + } + +} +#endif + +#if defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR) + /* Use IntegratorAP routines in board/integratorap.c */ +#else + +static ulong timestamp; +static ulong lastdec; + +#if defined(CONFIG_USE_IRQ) && defined(CONFIG_S3C4510B) +int arch_interrupt_init (void) +{ + int i; + + /* install default interrupt handlers */ + for ( i = 0; i < N_IRQS; i++) { + IRQ_HANDLER[i].m_data = (void *)i; + IRQ_HANDLER[i].m_func = default_isr; + } + + /* configure interrupts for IRQ mode */ + PUT_REG( REG_INTMODE, 0x0); + /* clear any pending interrupts */ + PUT_REG( REG_INTPEND, 0x1FFFFF); + + lastdec = 0; + + /* install interrupt handler for timer */ + IRQ_HANDLER[INT_TIMER0].m_data = (void *)×tamp; + IRQ_HANDLER[INT_TIMER0].m_func = timer_isr; + + return 0; +} +#endif + +int timer_init (void) +{ +#if defined(CONFIG_NETARM) + /* disable all interrupts */ + IRQEN = 0; + + /* operate timer 2 in non-prescale mode */ + TM2CTRL = ( NETARM_GEN_TIMER_SET_HZ(CONFIG_SYS_HZ) | + NETARM_GEN_TCTL_ENABLE | + NETARM_GEN_TCTL_INIT_COUNT(TIMER_LOAD_VAL)); + + /* set timer 2 counter */ + lastdec = TIMER_LOAD_VAL; +#elif defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO) + /* disable all interrupts */ + IO_INTMR1 = 0; + + /* operate timer 1 in prescale mode */ + IO_SYSCON1 |= SYSCON1_TC1M; + + /* select 2kHz clock source for timer 1 */ + IO_SYSCON1 &= ~SYSCON1_TC1S; + + /* set timer 1 counter */ + lastdec = IO_TC1D = TIMER_LOAD_VAL; +#elif defined(CONFIG_S3C4510B) + /* configure free running timer 0 */ + PUT_REG( REG_TMOD, 0x0); + /* Stop timer 0 */ + CLR_REG( REG_TMOD, TM0_RUN); + + /* Configure for interval mode */ + CLR_REG( REG_TMOD, TM1_TOGGLE); + + /* + * Load Timer data register with count down value. + * count_down_val = CONFIG_SYS_SYS_CLK_FREQ/CONFIG_SYS_HZ + */ + PUT_REG( REG_TDATA0, (CONFIG_SYS_SYS_CLK_FREQ / CONFIG_SYS_HZ)); + + /* + * Enable global interrupt + * Enable timer0 interrupt + */ + CLR_REG( REG_INTMASK, ((1<= now) { + /* normal mode */ + timestamp += lastdec - now; + } else { + /* we have an overflow ... */ + timestamp += lastdec + TIMER_LOAD_VAL - now; + } + lastdec = now; + + return timestamp; +} + +void udelay_masked (unsigned long usec) +{ + ulong tmo; + ulong endtime; + signed long diff; + + if (usec >= 1000) { + tmo = usec / 1000; + tmo *= CONFIG_SYS_HZ; + tmo /= 1000; + } else { + tmo = usec * CONFIG_SYS_HZ; + tmo /= (1000*1000); + } + + endtime = get_timer_masked () + tmo; + + do { + ulong now = get_timer_masked (); + diff = endtime - now; + } while (diff >= 0); +} + +#elif defined(CONFIG_S3C4510B) + +ulong get_timer (ulong base) +{ + return timestamp - base; +} + +void __udelay (unsigned long usec) +{ + u32 ticks; + + ticks = (usec * CONFIG_SYS_HZ) / 1000000; + + ticks += get_timer (0); + + while (get_timer (0) < ticks) + /*NOP*/; + +} + +#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR) + /* No timer routines for IntegratorAP/CM720T as yet */ +#else +#error Timer routines not defined for this CPU type +#endif diff --git a/arch/arm/cpu/arm720t/lpc2292/Makefile b/arch/arm/cpu/arm720t/lpc2292/Makefile new file mode 100644 index 0000000000..240f1e3b3b --- /dev/null +++ b/arch/arm/cpu/arm720t/lpc2292/Makefile @@ -0,0 +1,50 @@ +# +# (C) Copyright 2000-2007 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +COBJS = flash.o mmc.o mmc_hw.o spi.o +SOBJS = $(obj)iap_entry.o + +SRCS := $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) $(SOBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS) + +# this MUST be compiled as thumb code! +$(SOBJS): + $(CC) $(AFLAGS) -march=armv4t -c -o $(SOBJS) iap_entry.S + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm720t/lpc2292/flash.c b/arch/arm/cpu/arm720t/lpc2292/flash.c new file mode 100644 index 0000000000..3d2dc32231 --- /dev/null +++ b/arch/arm/cpu/arm720t/lpc2292/flash.c @@ -0,0 +1,249 @@ +/* + * (C) Copyright 2006 Embedded Artists AB + * + * Modified to remove all but the IAP-command related code by + * Gary Jennejohn + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +/* IAP commands use 32 bytes at the top of CPU internal sram, we + use 512 bytes below that */ +#define COPY_BUFFER_LOCATION 0x40003de0 + +#define IAP_LOCATION 0x7ffffff1 +#define IAP_CMD_PREPARE 50 +#define IAP_CMD_COPY 51 +#define IAP_CMD_ERASE 52 +#define IAP_CMD_CHECK 53 +#define IAP_CMD_ID 54 +#define IAP_CMD_VERSION 55 +#define IAP_CMD_COMPARE 56 + +#define IAP_RET_CMD_SUCCESS 0 + +static unsigned long command[5]; +static unsigned long result[2]; + +extern void iap_entry(unsigned long * command, unsigned long * result); + +/*----------------------------------------------------------------------- + * + */ +static int get_flash_sector(flash_info_t * info, ulong flash_addr) +{ + int i; + + for(i = 1; i < (info->sector_count); i++) { + if (flash_addr < (info->start[i])) + break; + } + + return (i-1); +} + +/*----------------------------------------------------------------------- + * This function assumes that flash_addr is aligned on 512 bytes boundary + * in flash. This function also assumes that prepare have been called + * for the sector in question. + */ +int lpc2292_copy_buffer_to_flash(flash_info_t * info, ulong flash_addr) +{ + int first_sector; + int last_sector; + + first_sector = get_flash_sector(info, flash_addr); + last_sector = get_flash_sector(info, flash_addr + 512 - 1); + + /* prepare sectors for write */ + command[0] = IAP_CMD_PREPARE; + command[1] = first_sector; + command[2] = last_sector; + iap_entry(command, result); + if (result[0] != IAP_RET_CMD_SUCCESS) { + printf("IAP prepare failed\n"); + return ERR_PROG_ERROR; + } + + command[0] = IAP_CMD_COPY; + command[1] = flash_addr; + command[2] = COPY_BUFFER_LOCATION; + command[3] = 512; + command[4] = CONFIG_SYS_SYS_CLK_FREQ >> 10; + iap_entry(command, result); + if (result[0] != IAP_RET_CMD_SUCCESS) { + printf("IAP copy failed\n"); + return 1; + } + + return 0; +} + +/*----------------------------------------------------------------------- + */ + +int lpc2292_flash_erase (flash_info_t * info, int s_first, int s_last) +{ + int flag; + int prot; + int sect; + + prot = 0; + for (sect = s_first; sect <= s_last; ++sect) { + if (info->protect[sect]) { + prot++; + } + } + if (prot) + return ERR_PROTECTED; + + + flag = disable_interrupts(); + + printf ("Erasing %d sectors starting at sector %2d.\n" + "This make take some time ... ", + s_last - s_first + 1, s_first); + + command[0] = IAP_CMD_PREPARE; + command[1] = s_first; + command[2] = s_last; + iap_entry(command, result); + if (result[0] != IAP_RET_CMD_SUCCESS) { + printf("IAP prepare failed\n"); + return ERR_PROTECTED; + } + + command[0] = IAP_CMD_ERASE; + command[1] = s_first; + command[2] = s_last; + command[3] = CONFIG_SYS_SYS_CLK_FREQ >> 10; + iap_entry(command, result); + if (result[0] != IAP_RET_CMD_SUCCESS) { + printf("IAP erase failed\n"); + return ERR_PROTECTED; + } + + if (flag) + enable_interrupts(); + + return ERR_OK; +} + +int lpc2292_write_buff (flash_info_t * info, uchar * src, ulong addr, + ulong cnt) +{ + int first_copy_size; + int last_copy_size; + int first_block; + int last_block; + int nbr_mid_blocks; + uchar memmap_value; + ulong i; + uchar* src_org; + uchar* dst_org; + int ret = ERR_OK; + + src_org = src; + dst_org = (uchar*)addr; + + first_block = addr / 512; + last_block = (addr + cnt) / 512; + nbr_mid_blocks = last_block - first_block - 1; + + first_copy_size = 512 - (addr % 512); + last_copy_size = (addr + cnt) % 512; + + debug("\ncopy first block: (1) %lX -> %lX 0x200 bytes, " + "(2) %lX -> %lX 0x%X bytes, (3) %lX -> %lX 0x200 bytes\n", + (ulong)(first_block * 512), + (ulong)COPY_BUFFER_LOCATION, + (ulong)src, + (ulong)(COPY_BUFFER_LOCATION + 512 - first_copy_size), + first_copy_size, + (ulong)COPY_BUFFER_LOCATION, + (ulong)(first_block * 512)); + + /* copy first block */ + memcpy((void*)COPY_BUFFER_LOCATION, + (void*)(first_block * 512), 512); + memcpy((void*)(COPY_BUFFER_LOCATION + 512 - first_copy_size), + src, first_copy_size); + lpc2292_copy_buffer_to_flash(info, first_block * 512); + src += first_copy_size; + addr += first_copy_size; + + /* copy middle blocks */ + for (i = 0; i < nbr_mid_blocks; i++) { + debug("copy middle block: %lX -> %lX 512 bytes, " + "%lX -> %lX 512 bytes\n", + (ulong)src, + (ulong)COPY_BUFFER_LOCATION, + (ulong)COPY_BUFFER_LOCATION, + (ulong)addr); + + memcpy((void*)COPY_BUFFER_LOCATION, src, 512); + lpc2292_copy_buffer_to_flash(info, addr); + src += 512; + addr += 512; + } + + + if (last_copy_size > 0) { + debug("copy last block: (1) %lX -> %lX 0x200 bytes, " + "(2) %lX -> %lX 0x%X bytes, (3) %lX -> %lX x200 bytes\n", + (ulong)(last_block * 512), + (ulong)COPY_BUFFER_LOCATION, + (ulong)src, + (ulong)(COPY_BUFFER_LOCATION), + last_copy_size, + (ulong)COPY_BUFFER_LOCATION, + (ulong)addr); + + /* copy last block */ + memcpy((void*)COPY_BUFFER_LOCATION, + (void*)(last_block * 512), 512); + memcpy((void*)COPY_BUFFER_LOCATION, + src, last_copy_size); + lpc2292_copy_buffer_to_flash(info, addr); + } + + /* verify write */ + memmap_value = GET8(MEMMAP); + + disable_interrupts(); + + PUT8(MEMMAP, 01); /* we must make sure that initial 64 + bytes are taken from flash when we + do the compare */ + + for (i = 0; i < cnt; i++) { + if (*dst_org != *src_org){ + printf("Write failed. Byte %lX differs\n", i); + ret = ERR_PROG_ERROR; + break; + } + dst_org++; + src_org++; + } + + PUT8(MEMMAP, memmap_value); + enable_interrupts(); + + return ret; +} diff --git a/arch/arm/cpu/arm720t/lpc2292/iap_entry.S b/arch/arm/cpu/arm720t/lpc2292/iap_entry.S new file mode 100644 index 0000000000..c31d5190bd --- /dev/null +++ b/arch/arm/cpu/arm720t/lpc2292/iap_entry.S @@ -0,0 +1,7 @@ +IAP_ADDRESS: .word 0x7FFFFFF1 + +.globl iap_entry +iap_entry: + ldr r2, IAP_ADDRESS + bx r2 + mov pc, lr diff --git a/arch/arm/cpu/arm720t/lpc2292/mmc.c b/arch/arm/cpu/arm720t/lpc2292/mmc.c new file mode 100644 index 0000000000..beaffe944c --- /dev/null +++ b/arch/arm/cpu/arm720t/lpc2292/mmc.c @@ -0,0 +1,131 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include "mmc_hw.h" +#include + +#ifdef CONFIG_MMC + +#undef MMC_DEBUG + +static block_dev_desc_t mmc_dev; + +/* these are filled out by a call to mmc_hw_get_parameters */ +static int hw_size; /* in kbytes */ +static int hw_nr_sects; +static int hw_sect_size; /* in bytes */ + +block_dev_desc_t * mmc_get_dev(int dev) +{ + return (block_dev_desc_t *)(&mmc_dev); +} + +unsigned long mmc_block_read(int dev, + unsigned long start, + lbaint_t blkcnt, + void *buffer) +{ + unsigned long rc = 0; + unsigned char *p = (unsigned char *)buffer; + unsigned long i; + unsigned long addr = start; + +#ifdef MMC_DEBUG + printf("mmc_block_read: start=%lu, blkcnt=%lu\n", start, + (unsigned long)blkcnt); +#endif + + for(i = 0; i < (unsigned long)blkcnt; i++) { +#ifdef MMC_DEBUG + printf("mmc_read_sector: addr=%lu, buffer=%p\n", addr, p); +#endif + (void)mmc_read_sector(addr, p); + rc++; + addr++; + p += hw_sect_size; + } + + return rc; +} + +/*----------------------------------------------------------------------------- + * Read hardware paramterers (sector size, size, number of sectors) + */ +static int mmc_hw_get_parameters(void) +{ + unsigned char csddata[16]; + unsigned int sizemult; + unsigned int size; + + mmc_read_csd(csddata); + hw_sect_size = 1<<(csddata[5] & 0x0f); + size = ((csddata[6]&0x03)<<10)+(csddata[7]<<2)+(csddata[8]&0xc0); + sizemult = ((csddata[10] & 0x80)>>7)+((csddata[9] & 0x03)<<1); + hw_nr_sects = (size+1)*(1<<(sizemult+2)); + hw_size = hw_nr_sects*hw_sect_size/1024; + +#ifdef MMC_DEBUG + printf("mmc_hw_get_parameters: hw_sect_size=%d, hw_nr_sects=%d, " + "hw_size=%d\n", hw_sect_size, hw_nr_sects, hw_size); +#endif + + return 0; +} + +int mmc_legacy_init(int verbose) +{ + int ret = -ENODEV; + + if (verbose) + printf("mmc_legacy_init\n"); + + spi_init(); + /* this meeds to be done twice */ + mmc_hw_init(); + udelay(1000); + mmc_hw_init(); + + mmc_hw_get_parameters(); + + mmc_dev.if_type = IF_TYPE_MMC; + mmc_dev.part_type = PART_TYPE_DOS; + mmc_dev.dev = 0; + mmc_dev.lun = 0; + mmc_dev.type = 0; + mmc_dev.blksz = hw_sect_size; + mmc_dev.lba = hw_nr_sects; + sprintf((char*)mmc_dev.vendor, "Unknown vendor"); + sprintf((char*)mmc_dev.product, "Unknown product"); + sprintf((char*)mmc_dev.revision, "N/A"); + mmc_dev.removable = 0; /* should be true??? */ + mmc_dev.block_read = mmc_block_read; + + fat_register_device(&mmc_dev, 1); + + ret = 0; + + return ret; +} + +#endif /* CONFIG_MMC */ diff --git a/arch/arm/cpu/arm720t/lpc2292/mmc_hw.c b/arch/arm/cpu/arm720t/lpc2292/mmc_hw.c new file mode 100644 index 0000000000..b4dc4a6e2f --- /dev/null +++ b/arch/arm/cpu/arm720t/lpc2292/mmc_hw.c @@ -0,0 +1,233 @@ +/* + This code was original written by Ulrich Radig and modified by + Embedded Artists AB (www.embeddedartists.com). + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include + +#define MMC_Enable() PUT32(IO1CLR, 1l << 22) +#define MMC_Disable() PUT32(IO1SET, 1l << 22) +#define mmc_spi_cfg() spi_set_clock(8); spi_set_cfg(0, 1, 0); + +static unsigned char Write_Command_MMC (unsigned char *CMD); +static void MMC_Read_Block(unsigned char *CMD, unsigned char *Buffer, + unsigned short int Bytes); + +/* initialize the hardware */ +int mmc_hw_init(void) +{ + unsigned long a; + unsigned short int Timeout = 0; + unsigned char b; + unsigned char CMD[] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x95}; + + /* set-up GPIO and SPI */ + (*((volatile unsigned long *)PINSEL2)) &= ~(1l << 3); /* clear bit 3 */ + (*((volatile unsigned long *)IO1DIR)) |= (1l << 22); /* set bit 22 (output) */ + + MMC_Disable(); + + spi_lock(); + spi_set_clock(248); + spi_set_cfg(0, 1, 0); + MMC_Enable(); + + /* waste some time */ + for(a=0; a < 20000; a++) + asm("nop"); + + /* Put the MMC/SD-card into SPI-mode */ + for (b = 0; b < 10; b++) /* Sends min 74+ clocks to the MMC/SD-card */ + spi_write(0xff); + + /* Sends command CMD0 to MMC/SD-card */ + while (Write_Command_MMC(CMD) != 1) { + if (Timeout++ > 200) { + MMC_Disable(); + spi_unlock(); + return(1); /* Abort with command 1 (return 1) */ + } + } + /* Sends Command CMD1 an MMC/SD-card */ + Timeout = 0; + CMD[0] = 0x41;/* Command 1 */ + CMD[5] = 0xFF; + + while (Write_Command_MMC(CMD) != 0) { + if (Timeout++ > 200) { + MMC_Disable(); + spi_unlock(); + return (2); /* Abort with command 2 (return 2) */ + } + } + + MMC_Disable(); + spi_unlock(); + + return 0; +} + +/* ############################################################################ + Sends a command to the MMC/SD-card + ######################################################################### */ +static unsigned char Write_Command_MMC (unsigned char *CMD) +{ + unsigned char a, tmp = 0xff; + unsigned short int Timeout = 0; + + MMC_Disable(); + spi_write(0xFF); + MMC_Enable(); + + for (a = 0; a < 0x06; a++) + spi_write(*CMD++); + + while (tmp == 0xff) { + tmp = spi_read(); + if (Timeout++ > 5000) + break; + } + + return (tmp); +} + +/* ############################################################################ + Routine to read the CID register from the MMC/SD-card (16 bytes) + ######################################################################### */ +void MMC_Read_Block(unsigned char *CMD, unsigned char *Buffer, unsigned short + int Bytes) +{ + unsigned short int a; + + spi_lock(); + mmc_spi_cfg(); + MMC_Enable(); + + if (Write_Command_MMC(CMD) != 0) { + MMC_Disable(); + spi_unlock(); + return; + } + + while (spi_read() != 0xfe) {}; + for (a = 0; a < Bytes; a++) + *Buffer++ = spi_read(); + + /* Read the CRC-byte */ + spi_read(); /* CRC - byte is discarded */ + spi_read(); /* CRC - byte is discarded */ + /* set MMC_Chip_Select to high (MMC/SD-card Inaktiv) */ + MMC_Disable(); + spi_unlock(); + + return; +} + +/* ############################################################################ + Routine to read a block (512 bytes) from the MMC/SD-card + ######################################################################### */ +unsigned char mmc_read_sector (unsigned long addr,unsigned char *Buffer) +{ + /* Command 16 to read aBlocks from the MMC/SD - caed */ + unsigned char CMD[] = {0x51,0x00,0x00,0x00,0x00,0xFF}; + + /* The addres on the MMC/SD-card is in bytes, + addr is transformed from blocks to bytes and the result is + placed into the command */ + + addr = addr << 9; /* addr = addr * 512 */ + + CMD[1] = ((addr & 0xFF000000) >> 24); + CMD[2] = ((addr & 0x00FF0000) >> 16); + CMD[3] = ((addr & 0x0000FF00) >> 8 ); + + MMC_Read_Block(CMD, Buffer, 512); + + return (0); +} + +/* ############################################################################ + Routine to write a block (512 byte) to the MMC/SD-card + ######################################################################### */ +unsigned char mmc_write_sector (unsigned long addr,unsigned char *Buffer) +{ + unsigned char tmp, a; + unsigned short int b; + /* Command 24 to write a block to the MMC/SD - card */ + unsigned char CMD[] = {0x58, 0x00, 0x00, 0x00, 0x00, 0xFF}; + + /* The addres on the MMC/SD-card is in bytes, + addr is transformed from blocks to bytes and the result is + placed into the command */ + + addr = addr << 9; /* addr = addr * 512 */ + + CMD[1] = ((addr & 0xFF000000) >> 24); + CMD[2] = ((addr & 0x00FF0000) >> 16); + CMD[3] = ((addr & 0x0000FF00) >> 8 ); + + spi_lock(); + mmc_spi_cfg(); + MMC_Enable(); + + /* Send command CMD24 to the MMC/SD-card (Write 1 Block/512 Bytes) */ + tmp = Write_Command_MMC(CMD); + if (tmp != 0) { + MMC_Disable(); + spi_unlock(); + return(tmp); + } + + /* Do a short delay and send a clock-pulse to the MMC/SD-card */ + for (a = 0; a < 100; a++) + spi_read(); + + /* Send a start byte to the MMC/SD-card */ + spi_write(0xFE); + + /* Write the block (512 bytes) to the MMC/SD-card */ + for (b = 0; b < 512; b++) + spi_write(*Buffer++); + + /* write the CRC-Byte */ + spi_write(0xFF); /* write a dummy CRC */ + spi_write(0xFF); /* CRC code is not used */ + + /* Wait for MMC/SD-card busy */ + while (spi_read() != 0xff) {}; + + /* set MMC_Chip_Select to high (MMC/SD-card inactive) */ + MMC_Disable(); + spi_unlock(); + return (0); +} + +/* ######################################################################### + Routine to read the CSD register from the MMC/SD-card (16 bytes) + ######################################################################### */ +unsigned char mmc_read_csd (unsigned char *Buffer) +{ + /* Command to read the CSD register */ + unsigned char CMD[] = {0x49, 0x00, 0x00, 0x00, 0x00, 0xFF}; + + MMC_Read_Block(CMD, Buffer, 16); + + return (0); +} diff --git a/arch/arm/cpu/arm720t/lpc2292/mmc_hw.h b/arch/arm/cpu/arm720t/lpc2292/mmc_hw.h new file mode 100644 index 0000000000..3687dbf696 --- /dev/null +++ b/arch/arm/cpu/arm720t/lpc2292/mmc_hw.h @@ -0,0 +1,29 @@ +/* + This module implements a linux character device driver for the 24c256 chip. + Copyright (C) 2006 Embedded Artists AB (www.embeddedartists.com) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _MMC_HW_ +#define _MMC_HW_ + +unsigned char mmc_read_csd(unsigned char *Buffer); +unsigned char mmc_read_sector (unsigned long addr, + unsigned char *Buffer); +unsigned char mmc_write_sector (unsigned long addr,unsigned char *Buffer); +int mmc_hw_init(void); + +#endif /* _MMC_HW_ */ diff --git a/arch/arm/cpu/arm720t/lpc2292/spi.c b/arch/arm/cpu/arm720t/lpc2292/spi.c new file mode 100644 index 0000000000..d296bdac68 --- /dev/null +++ b/arch/arm/cpu/arm720t/lpc2292/spi.c @@ -0,0 +1,40 @@ +/* + This module implements an interface to the SPI on the lpc22xx. + Copyright (C) 2006 Embedded Artists AB (www.embeddedartists.com) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include +#include + +unsigned long spi_flags; +unsigned char spi_idle = 0x00; + +int spi_init(void) +{ + unsigned long pinsel0_value; + + /* activate spi pins */ + pinsel0_value = GET32(PINSEL0); + pinsel0_value &= ~(0xFFl << 8); + pinsel0_value |= (0x55l << 8); + PUT32(PINSEL0, pinsel0_value); + + return 0; +} diff --git a/arch/arm/cpu/arm720t/s3c4510b/Makefile b/arch/arm/cpu/arm720t/s3c4510b/Makefile new file mode 100644 index 0000000000..c099036351 --- /dev/null +++ b/arch/arm/cpu/arm720t/s3c4510b/Makefile @@ -0,0 +1,45 @@ +# +# (C) Copyright 2000-2008 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +COBJS-y += cache.o + +SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm720t/s3c4510b/cache.c b/arch/arm/cpu/arm720t/s3c4510b/cache.c new file mode 100644 index 0000000000..104d287b26 --- /dev/null +++ b/arch/arm/cpu/arm720t/s3c4510b/cache.c @@ -0,0 +1,86 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +void icache_enable (void) +{ + s32 i; + + /* disable all cache bits */ + CLR_REG( REG_SYSCFG, 0x3F); + + /* 8KB cache, write enable */ + SET_REG( REG_SYSCFG, CACHE_WRITE_BUFF | CACHE_MODE_01); + + /* clear TAG RAM bits */ + for ( i = 0; i < 256; i++) + PUT_REG( CACHE_TAG_RAM + 4*i, 0x00000000); + + /* clear SET0 RAM */ + for(i=0; i < 1024; i++) + PUT_REG( CACHE_SET0_RAM + 4*i, 0x00000000); + + /* clear SET1 RAM */ + for(i=0; i < 1024; i++) + PUT_REG( CACHE_SET1_RAM + 4*i, 0x00000000); + + /* enable cache */ + SET_REG( REG_SYSCFG, CACHE_ENABLE); + +} + +void icache_disable (void) +{ + /* disable all cache bits */ + CLR_REG( REG_SYSCFG, 0x3F); +} + +int icache_status (void) +{ + return GET_REG( REG_SYSCFG) & CACHE_ENABLE; +} + +void dcache_enable (void) +{ + /* we don't have seperate instruction/data caches */ + icache_enable(); +} + +void dcache_disable (void) +{ + /* we don't have seperate instruction/data caches */ + icache_disable(); +} + +int dcache_status (void) +{ + /* we don't have seperate instruction/data caches */ + return icache_status(); +} diff --git a/arch/arm/cpu/arm720t/start.S b/arch/arm/cpu/arm720t/start.S new file mode 100644 index 0000000000..022b873e35 --- /dev/null +++ b/arch/arm/cpu/arm720t/start.S @@ -0,0 +1,611 @@ +/* + * armboot - Startup Code for ARM720 CPU-core + * + * Copyright (c) 2001 Marius Gröger + * Copyright (c) 2002 Alex Züpke + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + +#include +#include +#include + +/* + ************************************************************************* + * + * Jump vector table as in table 3.1 in [1] + * + ************************************************************************* + */ + + +.globl _start +_start: b reset + ldr pc, _undefined_instruction + ldr pc, _software_interrupt + ldr pc, _prefetch_abort + ldr pc, _data_abort +#ifdef CONFIG_LPC2292 + .word 0xB4405F76 /* 2's complement of the checksum of the vectors */ +#else + ldr pc, _not_used +#endif + ldr pc, _irq + ldr pc, _fiq + +_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 RAM! + * relocate armboot to ram + * setup stack + * jump to second stage + * + ************************************************************************* + */ + +_TEXT_BASE: + .word TEXT_BASE + +.globl _armboot_start +_armboot_start: + .word _start + +/* + * These are defined in the board-specific linker script. + */ +.globl _bss_start +_bss_start: + .word __bss_start + +.globl _bss_end +_bss_end: + .word _end + +#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 + + +/* + * the actual reset code + */ + +reset: + /* + * set the cpu to SVC32 mode + */ + mrs r0,cpsr + bic r0,r0,#0x1f + orr r0,r0,#0x13 + msr cpsr,r0 + + /* + * we do sys-critical inits only at reboot, + * not when booting from ram! + */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl cpu_init_crit +#endif + +#ifdef CONFIG_LPC2292 + bl lowlevel_init +#endif + +#ifndef CONFIG_SKIP_RELOCATE_UBOOT +relocate: /* relocate U-Boot to RAM */ + adr r0, _start /* r0 <- current position of code */ + ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ + cmp r0, r1 /* don't reloc during debug */ + beq stack_setup + +#if TEXT_BASE +#ifndef CONFIG_LPC2292 /* already done in lowlevel_init */ + ldr r2, =0x0 /* Relocate the exception vectors */ + cmp r1, r2 /* and associated data to address */ + ldmneia r0!, {r3-r10} /* 0x0. Do nothing if TEXT_BASE is */ + stmneia r2!, {r3-r10} /* 0x0. Copy the first 15 words. */ + ldmneia r0, {r3-r9} + stmneia r2, {r3-r9} + adrne r0, _start /* restore r0 */ +#endif /* !CONFIG_LPC2292 */ +#endif + + ldr r2, _armboot_start + ldr r3, _bss_start + sub r2, r3, r2 /* r2 <- size of armboot */ + add r2, r0, r2 /* r2 <- source end address */ + +copy_loop: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end addreee [r2] */ + ble copy_loop + +#endif /* CONFIG_SKIP_RELOCATE_UBOOT */ + + /* Set up the stack */ +stack_setup: + ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ + sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */ + sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ +#ifdef CONFIG_USE_IRQ + sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) +#endif + sub sp, r0, #12 /* leave 3 words for abort-stack */ + +clear_bss: + ldr r0, _bss_start /* find start of bss segment */ + ldr r1, _bss_end /* stop here */ + mov r2, #0x00000000 /* clear */ + +clbss_l:str r2, [r0] /* clear loop... */ + add r0, r0, #4 + cmp r0, r1 + ble clbss_l + + ldr pc, _start_armboot + +_start_armboot: .word start_armboot + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + ************************************************************************* + */ + +#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO) + +/* Interupt-Controller base addresses */ +INTMR1: .word 0x80000280 @ 32 bit size +INTMR2: .word 0x80001280 @ 16 bit size +INTMR3: .word 0x80002280 @ 8 bit size + +/* SYSCONs */ +SYSCON1: .word 0x80000100 +SYSCON2: .word 0x80001100 +SYSCON3: .word 0x80002200 + +#define CLKCTL 0x6 /* mask */ +#define CLKCTL_18 0x0 /* 18.432 MHz */ +#define CLKCTL_36 0x2 /* 36.864 MHz */ +#define CLKCTL_49 0x4 /* 49.152 MHz */ +#define CLKCTL_73 0x6 /* 73.728 MHz */ + +#elif defined(CONFIG_LPC2292) +PLLCFG_ADR: .word PLLCFG +PLLFEED_ADR: .word PLLFEED +PLLCON_ADR: .word PLLCON +PLLSTAT_ADR: .word PLLSTAT +VPBDIV_ADR: .word VPBDIV +MEMMAP_ADR: .word MEMMAP + +#endif + +cpu_init_crit: +#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO) + + /* + * mask all IRQs by clearing all bits in the INTMRs + */ + mov r1, #0x00 + ldr r0, INTMR1 + str r1, [r0] + ldr r0, INTMR2 + str r1, [r0] + ldr r0, INTMR3 + str r1, [r0] + + /* + * flush v4 I/D caches + */ + mov r0, #0 + mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ + mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ + + /* + * disable MMU stuff and caches + */ + mrc p15,0,r0,c1,c0 + bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) + bic r0, r0, #0x0000008f @ clear bits 7, 3:0 (B--- WCAM) + orr r0, r0, #0x00000002 @ set bit 2 (A) Align + mcr p15,0,r0,c1,c0 +#elif defined(CONFIG_NETARM) + /* + * prior to software reset : need to set pin PORTC4 to be *HRESET + */ + ldr r0, =NETARM_GEN_MODULE_BASE + ldr r1, =(NETARM_GEN_PORT_MODE(0x10) | \ + NETARM_GEN_PORT_DIR(0x10)) + str r1, [r0, #+NETARM_GEN_PORTC] + /* + * software reset : see HW Ref. Guide 8.2.4 : Software Service register + * for an explanation of this process + */ + ldr r0, =NETARM_GEN_MODULE_BASE + ldr r1, =NETARM_GEN_SW_SVC_RESETA + str r1, [r0, #+NETARM_GEN_SOFTWARE_SERVICE] + ldr r1, =NETARM_GEN_SW_SVC_RESETB + str r1, [r0, #+NETARM_GEN_SOFTWARE_SERVICE] + ldr r1, =NETARM_GEN_SW_SVC_RESETA + str r1, [r0, #+NETARM_GEN_SOFTWARE_SERVICE] + ldr r1, =NETARM_GEN_SW_SVC_RESETB + str r1, [r0, #+NETARM_GEN_SOFTWARE_SERVICE] + /* + * setup PLL and System Config + */ + ldr r0, =NETARM_GEN_MODULE_BASE + + ldr r1, =( NETARM_GEN_SYS_CFG_LENDIAN | \ + NETARM_GEN_SYS_CFG_BUSFULL | \ + NETARM_GEN_SYS_CFG_USER_EN | \ + NETARM_GEN_SYS_CFG_ALIGN_ABORT | \ + NETARM_GEN_SYS_CFG_BUSARB_INT | \ + NETARM_GEN_SYS_CFG_BUSMON_EN ) + + str r1, [r0, #+NETARM_GEN_SYSTEM_CONTROL] + +#ifndef CONFIG_NETARM_PLL_BYPASS + ldr r1, =( NETARM_GEN_PLL_CTL_PLLCNT(NETARM_PLL_COUNT_VAL) | \ + NETARM_GEN_PLL_CTL_POLTST_DEF | \ + NETARM_GEN_PLL_CTL_INDIV(1) | \ + NETARM_GEN_PLL_CTL_ICP_DEF | \ + NETARM_GEN_PLL_CTL_OUTDIV(2) ) + str r1, [r0, #+NETARM_GEN_PLL_CONTROL] +#endif + + /* + * mask all IRQs by clearing all bits in the INTMRs + */ + mov r1, #0 + ldr r0, =NETARM_GEN_MODULE_BASE + str r1, [r0, #+NETARM_GEN_INTR_ENABLE] + +#elif defined(CONFIG_S3C4510B) + + /* + * Mask off all IRQ sources + */ + ldr r1, =REG_INTMASK + ldr r0, =0x3FFFFF + str r0, [r1] + + /* + * Disable Cache + */ + ldr r0, =REG_SYSCFG + ldr r1, =0x83ffffa0 /* cache-disabled */ + str r1, [r0] + +#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR) + /* No specific initialisation for IntegratorAP/CM720T as yet */ +#elif defined(CONFIG_LPC2292) + /* Set-up PLL */ + mov r3, #0xAA + mov r4, #0x55 + /* First disconnect and disable the PLL */ + ldr r0, PLLCON_ADR + mov r1, #0x00 + str r1, [r0] + ldr r0, PLLFEED_ADR /* start feed sequence */ + str r3, [r0] + str r4, [r0] /* feed sequence done */ + /* Set new M and P values */ + ldr r0, PLLCFG_ADR + mov r1, #0x23 /* M=4 and P=2 */ + str r1, [r0] + ldr r0, PLLFEED_ADR /* start feed sequence */ + str r3, [r0] + str r4, [r0] /* feed sequence done */ + /* Then enable the PLL */ + ldr r0, PLLCON_ADR + mov r1, #0x01 /* PLL enable bit */ + str r1, [r0] + ldr r0, PLLFEED_ADR /* start feed sequence */ + str r3, [r0] + str r4, [r0] /* feed sequence done */ + /* Wait for the lock */ + ldr r0, PLLSTAT_ADR + mov r1, #0x400 /* lock bit */ +lock_loop: + ldr r2, [r0] + and r2, r1, r2 + cmp r2, #0 + beq lock_loop + /* And finally connect the PLL */ + ldr r0, PLLCON_ADR + mov r1, #0x03 /* PLL enable bit and connect bit */ + str r1, [r0] + ldr r0, PLLFEED_ADR /* start feed sequence */ + str r3, [r0] + str r4, [r0] /* feed sequence done */ + /* Set-up VPBDIV register */ + ldr r0, VPBDIV_ADR + mov r1, #0x01 /* VPB clock is same as process clock */ + str r1, [r0] +#else +#error No cpu_init_crit() defined for current CPU type +#endif + +#ifdef CONFIG_ARM7_REVD + /* set clock speed */ + /* !!! we run @ 36 MHz due to a hardware flaw in Rev. D processors */ + /* !!! not doing DRAM refresh properly! */ + ldr r0, SYSCON3 + ldr r1, [r0] + bic r1, r1, #CLKCTL + orr r1, r1, #CLKCTL_36 + str r1, [r0] +#endif + +#ifndef CONFIG_LPC2292 + mov ip, lr + /* + * before relocating, we have to setup RAM timing + * because memory timing is board-dependent, you will + * find a lowlevel_init.S in your board directory. + */ + bl lowlevel_init + mov lr, ip +#endif + + mov pc, 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 +#define I_BIT 0x80 + +/* + * use bad_save_user_regs for abort/prefetch/undef/swi ... + * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling + */ + + .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, _armboot_start + sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) + sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack + 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 + + .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, _armboot_start @ setup our mode stack + sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) + sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort 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 + /* someone ought to write a more effiction fiq_save_user_regs */ + irq_save_user_regs + bl do_fiq + 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 + +#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO) + .align 5 +.globl reset_cpu +reset_cpu: + mov ip, #0 + mcr p15, 0, ip, c7, c7, 0 @ invalidate cache + mcr p15, 0, ip, c8, c7, 0 @ flush TLB (v4) + mrc p15, 0, ip, c1, c0, 0 @ get ctrl register + bic ip, ip, #0x000f @ ............wcam + bic ip, ip, #0x2100 @ ..v....s........ + mcr p15, 0, ip, c1, c0, 0 @ ctrl register + mov pc, r0 +#elif defined(CONFIG_NETARM) + .align 5 +.globl reset_cpu +reset_cpu: + ldr r1, =NETARM_MEM_MODULE_BASE + ldr r0, [r1, #+NETARM_MEM_CS0_BASE_ADDR] + ldr r1, =0xFFFFF000 + and r0, r1, r0 + ldr r1, =(relocate-TEXT_BASE) + add r0, r1, r0 + ldr r4, =NETARM_GEN_MODULE_BASE + ldr r1, =NETARM_GEN_SW_SVC_RESETA + str r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE] + ldr r1, =NETARM_GEN_SW_SVC_RESETB + str r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE] + ldr r1, =NETARM_GEN_SW_SVC_RESETA + str r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE] + ldr r1, =NETARM_GEN_SW_SVC_RESETB + str r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE] + mov pc, r0 +#elif defined(CONFIG_S3C4510B) +/* Nothing done here as reseting the CPU is board specific, depending + * on external peripherals such as watchdog timers, etc. */ +#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR) + /* No specific reset actions for IntegratorAP/CM720T as yet */ +#elif defined(CONFIG_LPC2292) + .align 5 +.globl reset_cpu +reset_cpu: + mov pc, r0 +#else +#error No reset_cpu() defined for current CPU type +#endif diff --git a/arch/arm/cpu/arm720t/u-boot.lds b/arch/arm/cpu/arm720t/u-boot.lds new file mode 100644 index 0000000000..c975fc3d5e --- /dev/null +++ b/arch/arm/cpu/arm720t/u-boot.lds @@ -0,0 +1,56 @@ +/* + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + arch/arm/cpu/arm720t/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = ALIGN(4); + __bss_start = .; + .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } + _end = .; +} diff --git a/arch/arm/cpu/arm920t/Makefile b/arch/arm/cpu/arm920t/Makefile new file mode 100644 index 0000000000..cbb13b2a4c --- /dev/null +++ b/arch/arm/cpu/arm920t/Makefile @@ -0,0 +1,49 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(CPU).a + +START = start.o + +COBJS-y += cpu.o +COBJS-$(CONFIG_USE_IRQ) += interrupts.o + +SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y) $(SOBJS)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm920t/a320/Makefile b/arch/arm/cpu/arm920t/a320/Makefile new file mode 100644 index 0000000000..f030c53626 --- /dev/null +++ b/arch/arm/cpu/arm920t/a320/Makefile @@ -0,0 +1,47 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +SOBJS += reset.o +COBJS += timer.o +COBJS += ftsmc020.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm920t/a320/ftsmc020.c b/arch/arm/cpu/arm920t/a320/ftsmc020.c new file mode 100644 index 0000000000..76465373ec --- /dev/null +++ b/arch/arm/cpu/arm920t/a320/ftsmc020.c @@ -0,0 +1,51 @@ +/* + * (C) Copyright 2009 Faraday Technology + * Po-Yu Chuang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +struct ftsmc020_config { + unsigned int config; + unsigned int timing; +}; + +static struct ftsmc020_config config[] = CONFIG_SYS_FTSMC020_CONFIGS; + +static struct ftsmc020 *smc = (struct ftsmc020 *)CONFIG_FTSMC020_BASE; + +static void ftsmc020_setup_bank(unsigned int bank, struct ftsmc020_config *cfg) +{ + if (bank > 3) { + printf("bank # %u invalid\n", bank); + return; + } + + writel(cfg->config, &smc->bank[bank].cr); + writel(cfg->timing, &smc->bank[bank].tpr); +} + +void ftsmc020_init(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(config); i++) + ftsmc020_setup_bank(i, &config[i]); +} diff --git a/arch/arm/cpu/arm920t/a320/reset.S b/arch/arm/cpu/arm920t/a320/reset.S new file mode 100644 index 0000000000..12ca527c5d --- /dev/null +++ b/arch/arm/cpu/arm920t/a320/reset.S @@ -0,0 +1,22 @@ +/* + * (C) Copyright 2009 Faraday Technology + * Po-Yu Chuang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +.global reset_cpu +reset_cpu: + b reset_cpu diff --git a/arch/arm/cpu/arm920t/a320/timer.c b/arch/arm/cpu/arm920t/a320/timer.c new file mode 100644 index 0000000000..bb655930de --- /dev/null +++ b/arch/arm/cpu/arm920t/a320/timer.c @@ -0,0 +1,193 @@ +/* + * (C) Copyright 2009 Faraday Technology + * Po-Yu Chuang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +static ulong timestamp; +static ulong lastdec; + +static struct fttmr010 *tmr = (struct fttmr010 *)CONFIG_FTTMR010_BASE; +static struct ftpmu010 *pmu = (struct ftpmu010 *)CONFIG_FTPMU010_BASE; + +#define TIMER_CLOCK 32768 +#define TIMER_LOAD_VAL 0xffffffff + +int timer_init(void) +{ + unsigned int oscc; + unsigned int cr; + + debug("%s()\n", __func__); + + /* disable timers */ + writel(0, &tmr->cr); + + /* + * use 32768Hz oscillator for RTC, WDT, TIMER + */ + + /* enable the 32768Hz oscillator */ + oscc = readl(&pmu->OSCC); + oscc &= ~(FTPMU010_OSCC_OSCL_OFF | FTPMU010_OSCC_OSCL_TRI); + writel(oscc, &pmu->OSCC); + + /* wait until ready */ + while (!(readl(&pmu->OSCC) & FTPMU010_OSCC_OSCL_STABLE)) + ; + + /* select 32768Hz oscillator */ + oscc = readl(&pmu->OSCC); + oscc |= FTPMU010_OSCC_OSCL_RTCLSEL; + writel(oscc, &pmu->OSCC); + + /* setup timer */ + writel(TIMER_LOAD_VAL, &tmr->timer3_load); + writel(TIMER_LOAD_VAL, &tmr->timer3_counter); + writel(0, &tmr->timer3_match1); + writel(0, &tmr->timer3_match2); + + /* we don't want timer to issue interrupts */ + writel(FTTMR010_TM3_MATCH1 | + FTTMR010_TM3_MATCH2 | + FTTMR010_TM3_OVERFLOW, + &tmr->interrupt_mask); + + cr = readl(&tmr->cr); + cr |= FTTMR010_TM3_CLOCK; /* use external clock */ + cr |= FTTMR010_TM3_ENABLE; + writel(cr, &tmr->cr); + + /* init the timestamp and lastdec value */ + reset_timer_masked(); + + return 0; +} + +/* + * timer without interrupts + */ + +/* + * reset time + */ +void reset_timer_masked(void) +{ + /* capure current decrementer value time */ + lastdec = readl(&tmr->timer3_counter) / (TIMER_CLOCK / CONFIG_SYS_HZ); + timestamp = 0; /* start "advancing" time stamp from 0 */ + + debug("%s(): lastdec = %lx\n", __func__, lastdec); +} + +void reset_timer(void) +{ + debug("%s()\n", __func__); + reset_timer_masked(); +} + +/* + * return timer ticks + */ +ulong get_timer_masked(void) +{ + /* current tick value */ + ulong now = readl(&tmr->timer3_counter) / (TIMER_CLOCK / CONFIG_SYS_HZ); + + debug("%s(): now = %lx, lastdec = %lx\n", __func__, now, lastdec); + + if (lastdec >= now) { + /* + * normal mode (non roll) + * move stamp fordward with absoulte diff ticks + */ + timestamp += lastdec - now; + } else { + /* + * we have overflow of the count down timer + * + * nts = ts + ld + (TLV - now) + * ts=old stamp, ld=time that passed before passing through -1 + * (TLV-now) amount of time after passing though -1 + * nts = new "advancing time stamp"...it could also roll and + * cause problems. + */ + timestamp += lastdec + TIMER_LOAD_VAL - now; + } + + lastdec = now; + + debug("%s() returns %lx\n", __func__, timestamp); + + return timestamp; +} + +/* + * return difference between timer ticks and base + */ +ulong get_timer(ulong base) +{ + debug("%s(%lx)\n", __func__, base); + return get_timer_masked() - base; +} + +void set_timer(ulong t) +{ + debug("%s(%lx)\n", __func__, t); + timestamp = t; +} + +/* delay x useconds AND perserve advance timstamp value */ +void udelay(unsigned long usec) +{ + long tmo = usec * (TIMER_CLOCK / 1000) / 1000; + unsigned long now, last = readl(&tmr->timer3_counter); + + debug("%s(%lu)\n", __func__, usec); + while (tmo > 0) { + now = readl(&tmr->timer3_counter); + if (now > last) /* count down timer overflow */ + tmo -= TIMER_LOAD_VAL + last - now; + else + tmo -= last - now; + last = now; + } +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + debug("%s()\n", __func__); + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + debug("%s()\n", __func__); + return CONFIG_SYS_HZ; +} diff --git a/arch/arm/cpu/arm920t/at91/Makefile b/arch/arm/cpu/arm920t/at91/Makefile new file mode 100644 index 0000000000..d8a4383650 --- /dev/null +++ b/arch/arm/cpu/arm920t/at91/Makefile @@ -0,0 +1,47 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +SOBJS += lowlevel_init.o +COBJS += reset.o +COBJS += timer.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm920t/at91/lowlevel_init.S b/arch/arm/cpu/arm920t/at91/lowlevel_init.S new file mode 100644 index 0000000000..22fc86cd5b --- /dev/null +++ b/arch/arm/cpu/arm920t/at91/lowlevel_init.S @@ -0,0 +1,164 @@ +/* + * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and + * Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl) + * + * Modified for the at91rm9200dk board by + * (C) Copyright 2004 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + +#include +#include +#include +#include + +#define ARM920T_CONTROL 0xC0000000 /* @ set bit 31 (iA) and 30 (nF) */ + +_MTEXT_BASE: +#undef START_FROM_MEM +#ifdef START_FROM_MEM + .word TEXT_BASE-PHYS_FLASH_1 +#else + .word TEXT_BASE +#endif + +.globl lowlevel_init +lowlevel_init: + ldr r1, =AT91_ASM_PMC_MOR + /* Main oscillator Enable register */ +#ifdef CONFIG_SYS_USE_MAIN_OSCILLATOR + ldr r0, =0x0000FF01 /* Enable main oscillator */ +#else + ldr r0, =0x0000FF00 /* Disable main oscillator */ +#endif + str r0, [r1] /*AT91C_CKGR_MOR] */ + /* Add loop to compensate Main Oscillator startup time */ + ldr r0, =0x00000010 +LoopOsc: + subs r0, r0, #1 + bhi LoopOsc + + /* memory control configuration */ + /* this isn't very elegant, but what the heck */ + ldr r0, =SMRDATA + ldr r1, _MTEXT_BASE + sub r0, r0, r1 + add r2, r0, #80 +pllloop: + /* the address */ + ldr r1, [r0], #4 + /* the value */ + ldr r3, [r0], #4 + str r3, [r1] + cmp r2, r0 + bne pllloop + /* delay - this is all done by guess */ + ldr r0, =0x00010000 + /* (vs reading PMC_SR for LOCKA, LOCKB ... or MOSCS earlier) */ +lock: + subs r0, r0, #1 + bhi lock + ldr r0, =SMRDATA1 + ldr r1, _MTEXT_BASE + sub r0, r0, r1 + add r2, r0, #176 +sdinit: + /* the address */ + ldr r1, [r0], #4 + /* the value */ + ldr r3, [r0], #4 + str r3, [r1] + cmp r2, r0 + bne sdinit + + /* switch from FastBus to Asynchronous clock mode */ + mrc p15, 0, r0, c1, c0, 0 + orr r0, r0, #ARM920T_CONTROL + mcr p15, 0, r0, c1, c0, 0 + + /* everything is fine now */ + mov pc, lr + + .ltorg + +SMRDATA: + .word AT91_ASM_MC_EBI_CFG + .word CONFIG_SYS_EBI_CFGR_VAL + .word AT91_ASM_MC_SMC_CSR0 + .word CONFIG_SYS_SMC_CSR0_VAL + .word AT91_ASM_PMC_PLLAR + .word CONFIG_SYS_PLLAR_VAL + .word AT91_ASM_PMC_PLLBR + .word CONFIG_SYS_PLLBR_VAL + .word AT91_ASM_PMC_MCKR + .word CONFIG_SYS_MCKR_VAL + /* here there's a delay */ +SMRDATA1: + .word AT91_ASM_PIOC_ASR + .word CONFIG_SYS_PIOC_ASR_VAL + .word AT91_ASM_PIOC_BSR + .word CONFIG_SYS_PIOC_BSR_VAL + .word AT91_ASM_PIOC_PDR + .word CONFIG_SYS_PIOC_PDR_VAL + .word AT91_ASM_MC_EBI_CSA + .word CONFIG_SYS_EBI_CSA_VAL + .word AT91_ASM_MC_SDRAMC_CR + .word CONFIG_SYS_SDRC_CR_VAL + .word AT91_ASM_MC_SDRAMC_MR + .word CONFIG_SYS_SDRC_MR_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word AT91_ASM_MC_SDRAMC_MR + .word CONFIG_SYS_SDRC_MR_VAL1 + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word AT91_ASM_MC_SDRAMC_MR + .word CONFIG_SYS_SDRC_MR_VAL2 + .word CONFIG_SYS_SDRAM1 + .word CONFIG_SYS_SDRAM_VAL + .word AT91_ASM_MC_SDRAMC_TR + .word CONFIG_SYS_SDRC_TR_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word AT91_ASM_MC_SDRAMC_MR + .word CONFIG_SYS_SDRC_MR_VAL3 + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + /* SMRDATA1 is 176 bytes long */ +#endif /* CONFIG_SKIP_LOWLEVEL_INIT */ diff --git a/arch/arm/cpu/arm920t/at91/reset.c b/arch/arm/cpu/arm920t/at91/reset.c new file mode 100644 index 0000000000..ce9c156154 --- /dev/null +++ b/arch/arm/cpu/arm920t/at91/reset.c @@ -0,0 +1,59 @@ +/* + * (C) Copyright 2002 + * Lineo, Inc. + * Bernhard Kuhn + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include + +void board_reset(void) __attribute__((__weak__)); + +void reset_cpu(ulong ignored) +{ + at91_st_t *st = (at91_st_t *) AT91_ST_BASE; +#if defined(CONFIG_AT91RM9200_USART) + /*shutdown the console to avoid strange chars during reset */ + serial_exit(); +#endif + + if (board_reset) + board_reset(); + + /* Reset the cpu by setting up the watchdog timer */ + writel(AT91_ST_WDMR_RSTEN | AT91_ST_WDMR_EXTEN | AT91_ST_WDMR_WDV(2), + &st->wdmr); + writel(AT91_ST_CR_WDRST, &st->cr); + /* and let it timeout */ + while (1) + ; + /* Never reached */ +} diff --git a/arch/arm/cpu/arm920t/at91/timer.c b/arch/arm/cpu/arm920t/at91/timer.c new file mode 100644 index 0000000000..91377d47a6 --- /dev/null +++ b/arch/arm/cpu/arm920t/at91/timer.c @@ -0,0 +1,163 @@ +/* + * (C) Copyright 2002 + * Lineo, Inc. + * Bernhard Kuhn + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +#include +#include +#include +#include + +/* the number of clocks per CONFIG_SYS_HZ */ +#define TIMER_LOAD_VAL (CONFIG_SYS_HZ_CLOCK/CONFIG_SYS_HZ) + +static u32 timestamp; +static u32 lastinc; + +int timer_init(void) +{ + at91_tc_t *tc = (at91_tc_t *) AT91_TC_BASE; + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + /* enables TC1.0 clock */ + writel(1 << AT91_ID_TC0, &pmc->pcer); /* enable clock */ + + writel(0, &tc->bcr); + writel(AT91_TC_BMR_TC0XC0S_NONE | AT91_TC_BMR_TC1XC1S_NONE | + AT91_TC_BMR_TC2XC2S_NONE , &tc->bmr); + + writel(AT91_TC_CCR_CLKDIS, &tc->tc[0].ccr); + /* set to MCLK/2 and restart the timer + when the value in TC_RC is reached */ + writel(AT91_TC_CMR_TCCLKS_CLOCK1 | AT91_TC_CMR_CPCTRG, &tc->tc[0].cmr); + + writel(0xFFFFFFFF, &tc->tc[0].idr); /* disable interupts */ + writel(TIMER_LOAD_VAL, &tc->tc[0].rc); + + writel(AT91_TC_CCR_SWTRG | AT91_TC_CCR_CLKEN, &tc->tc[0].ccr); + lastinc = 0; + timestamp = 0; + + return 0; +} + +/* + * timer without interrupts + */ + +void reset_timer(void) +{ + reset_timer_masked(); +} + +ulong get_timer(ulong base) +{ + return get_timer_masked() - base; +} + +void set_timer(ulong t) +{ + timestamp = t; +} + +void __udelay(unsigned long usec) +{ + udelay_masked(usec); +} + +void reset_timer_masked(void) +{ + /* reset time */ + at91_tc_t *tc = (at91_tc_t *) AT91_TC_BASE; + lastinc = readl(&tc->tc[0].cv) & 0x0000ffff; + timestamp = 0; +} + +ulong get_timer_raw(void) +{ + at91_tc_t *tc = (at91_tc_t *) AT91_TC_BASE; + u32 now; + + now = readl(&tc->tc[0].cv) & 0x0000ffff; + + if (now >= lastinc) { + /* normal mode */ + timestamp += now - lastinc; + } else { + /* we have an overflow ... */ + timestamp += now + TIMER_LOAD_VAL - lastinc; + } + lastinc = now; + + return timestamp; +} + +ulong get_timer_masked(void) +{ + return get_timer_raw()/TIMER_LOAD_VAL; +} + +void udelay_masked(unsigned long usec) +{ + u32 tmo; + u32 endtime; + signed long diff; + + tmo = CONFIG_SYS_HZ_CLOCK / 1000; + tmo *= usec; + tmo /= 1000; + + endtime = get_timer_raw() + tmo; + + do { + u32 now = get_timer_raw(); + diff = endtime - now; + } while (diff >= 0); +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + return CONFIG_SYS_HZ; +} diff --git a/arch/arm/cpu/arm920t/at91rm9200/Makefile b/arch/arm/cpu/arm920t/at91rm9200/Makefile new file mode 100644 index 0000000000..114d8adeb2 --- /dev/null +++ b/arch/arm/cpu/arm920t/at91rm9200/Makefile @@ -0,0 +1,56 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +SOBJS += lowlevel_init.o + +COBJS += bcm5221.o +COBJS += dm9161.o +COBJS += ether.o +COBJS += i2c.o +COBJS-$(CONFIG_KS8721_PHY) += ks8721.o +COBJS += lxt972.o +COBJS += reset.o +COBJS += spi.o +COBJS += timer.o +COBJS += usb.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS) $(COBJS-y)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm920t/at91rm9200/bcm5221.c b/arch/arm/cpu/arm920t/at91rm9200/bcm5221.c new file mode 100644 index 0000000000..8de3cba738 --- /dev/null +++ b/arch/arm/cpu/arm920t/at91rm9200/bcm5221.c @@ -0,0 +1,232 @@ +/* + * Broadcom BCM5221 Ethernet PHY + * + * (C) Copyright 2005 REA Elektronik GmbH + * Anders Larsen + * + * (C) Copyright 2003 + * Author : Hamid Ikdoumi (Atmel) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#ifdef CONFIG_DRIVER_ETHER + +#include + +#if defined(CONFIG_CMD_NET) + +/* + * Name: + * bcm5221_IsPhyConnected + * Description: + * Reads the 2 PHY ID registers + * Arguments: + * p_mac - pointer to AT91S_EMAC struct + * Return value: + * TRUE - if id read successfully + * FALSE- if error + */ +unsigned int bcm5221_IsPhyConnected (AT91PS_EMAC p_mac) +{ + unsigned short Id1, Id2; + + at91rm9200_EmacEnableMDIO (p_mac); + at91rm9200_EmacReadPhy (p_mac, BCM5221_PHYID1, &Id1); + at91rm9200_EmacReadPhy (p_mac, BCM5221_PHYID2, &Id2); + at91rm9200_EmacDisableMDIO (p_mac); + + if ((Id1 == (BCM5221_PHYID1_OUI >> 6)) && + ((Id2 >> 10) == (BCM5221_PHYID1_OUI & BCM5221_LSB_MASK))) + return TRUE; + + return FALSE; +} + +/* + * Name: + * bcm5221_GetLinkSpeed + * Description: + * Link parallel detection status of MAC is checked and set in the + * MAC configuration registers + * Arguments: + * p_mac - pointer to MAC + * Return value: + * TRUE - if link status set succesfully + * FALSE - if link status not set + */ +unsigned char bcm5221_GetLinkSpeed (AT91PS_EMAC p_mac) +{ + unsigned short stat1, stat2; + + if (!at91rm9200_EmacReadPhy (p_mac, BCM5221_BMSR, &stat1)) + return FALSE; + + if (!(stat1 & BCM5221_LINK_STATUS)) /* link status up? */ + return FALSE; + + if (!at91rm9200_EmacReadPhy (p_mac, BCM5221_ACSR, &stat2)) + return FALSE; + + if ((stat1 & BCM5221_100BASE_TX_FD) && (stat2 & BCM5221_100) && (stat2 & BCM5221_FDX)) { + /*set Emac for 100BaseTX and Full Duplex */ + p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD; + return TRUE; + } + + if ((stat1 & BCM5221_10BASE_T_FD) && !(stat2 & BCM5221_100) && (stat2 & BCM5221_FDX)) { + /*set MII for 10BaseT and Full Duplex */ + p_mac->EMAC_CFG = (p_mac->EMAC_CFG & + ~(AT91C_EMAC_SPD | AT91C_EMAC_FD)) + | AT91C_EMAC_FD; + return TRUE; + } + + if ((stat1 & BCM5221_100BASE_TX_HD) && (stat2 & BCM5221_100) && !(stat2 & BCM5221_FDX)) { + /*set MII for 100BaseTX and Half Duplex */ + p_mac->EMAC_CFG = (p_mac->EMAC_CFG & + ~(AT91C_EMAC_SPD | AT91C_EMAC_FD)) + | AT91C_EMAC_SPD; + return TRUE; + } + + if ((stat1 & BCM5221_10BASE_T_HD) && !(stat2 & BCM5221_100) && !(stat2 & BCM5221_FDX)) { + /*set MII for 10BaseT and Half Duplex */ + p_mac->EMAC_CFG &= ~(AT91C_EMAC_SPD | AT91C_EMAC_FD); + return TRUE; + } + return FALSE; +} + + +/* + * Name: + * bcm5221_InitPhy + * Description: + * MAC starts checking its link by using parallel detection and + * Autonegotiation and the same is set in the MAC configuration registers + * Arguments: + * p_mac - pointer to struct AT91S_EMAC + * Return value: + * TRUE - if link status set succesfully + * FALSE - if link status not set + */ +unsigned char bcm5221_InitPhy (AT91PS_EMAC p_mac) +{ + unsigned char ret = TRUE; + unsigned short IntValue; + + at91rm9200_EmacEnableMDIO (p_mac); + + if (!bcm5221_GetLinkSpeed (p_mac)) { + /* Try another time */ + ret = bcm5221_GetLinkSpeed (p_mac); + } + + /* Disable PHY Interrupts */ + at91rm9200_EmacReadPhy (p_mac, BCM5221_INTR, &IntValue); + /* clear FDX LED and INTR Enable */ + IntValue &= ~(BCM5221_FDX_LED | BCM5221_INTR_ENABLE); + /* set FDX, SPD, Link, INTR masks */ + IntValue |= (BCM5221_FDX_MASK | BCM5221_SPD_MASK | + BCM5221_LINK_MASK | BCM5221_INTR_MASK); + at91rm9200_EmacWritePhy (p_mac, BCM5221_INTR, &IntValue); + at91rm9200_EmacDisableMDIO (p_mac); + + return (ret); +} + + +/* + * Name: + * bcm5221_AutoNegotiate + * Description: + * MAC Autonegotiates with the partner status of same is set in the + * MAC configuration registers + * Arguments: + * dev - pointer to struct net_device + * Return value: + * TRUE - if link status set successfully + * FALSE - if link status not set + */ +unsigned char bcm5221_AutoNegotiate (AT91PS_EMAC p_mac, int *status) +{ + unsigned short value; + unsigned short PhyAnar; + unsigned short PhyAnalpar; + + /* Set bcm5221 control register */ + if (!at91rm9200_EmacReadPhy (p_mac, BCM5221_BMCR, &value)) + return FALSE; + value &= ~BCM5221_AUTONEG; /* remove autonegotiation enable */ + value |= BCM5221_ISOLATE; /* Electrically isolate PHY */ + if (!at91rm9200_EmacWritePhy (p_mac, BCM5221_BMCR, &value)) + return FALSE; + + /* Set the Auto_negotiation Advertisement Register */ + /* MII advertising for 100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3 */ + PhyAnar = BCM5221_TX_FDX | BCM5221_TX_HDX | + BCM5221_10_FDX | BCM5221_10_HDX | BCM5221_AN_IEEE_802_3; + if (!at91rm9200_EmacWritePhy (p_mac, BCM5221_ANAR, &PhyAnar)) + return FALSE; + + /* Read the Control Register */ + if (!at91rm9200_EmacReadPhy (p_mac, BCM5221_BMCR, &value)) + return FALSE; + + value |= BCM5221_SPEED_SELECT | BCM5221_AUTONEG | BCM5221_DUPLEX_MODE; + if (!at91rm9200_EmacWritePhy (p_mac, BCM5221_BMCR, &value)) + return FALSE; + /* Restart Auto_negotiation */ + value |= BCM5221_RESTART_AUTONEG; + value &= ~BCM5221_ISOLATE; + if (!at91rm9200_EmacWritePhy (p_mac, BCM5221_BMCR, &value)) + return FALSE; + + /*check AutoNegotiate complete */ + udelay (10000); + at91rm9200_EmacReadPhy (p_mac, BCM5221_BMSR, &value); + if (!(value & BCM5221_AUTONEG_COMP)) + return FALSE; + + /* Get the AutoNeg Link partner base page */ + if (!at91rm9200_EmacReadPhy (p_mac, BCM5221_ANLPAR, &PhyAnalpar)) + return FALSE; + + if ((PhyAnar & BCM5221_TX_FDX) && (PhyAnalpar & BCM5221_TX_FDX)) { + /*set MII for 100BaseTX and Full Duplex */ + p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD; + return TRUE; + } + + if ((PhyAnar & BCM5221_10_FDX) && (PhyAnalpar & BCM5221_10_FDX)) { + /*set MII for 10BaseT and Full Duplex */ + p_mac->EMAC_CFG = (p_mac->EMAC_CFG & + ~(AT91C_EMAC_SPD | AT91C_EMAC_FD)) + | AT91C_EMAC_FD; + return TRUE; + } + return FALSE; +} + +#endif + +#endif /* CONFIG_DRIVER_ETHER */ diff --git a/arch/arm/cpu/arm920t/at91rm9200/dm9161.c b/arch/arm/cpu/arm920t/at91rm9200/dm9161.c new file mode 100644 index 0000000000..6d4384f41a --- /dev/null +++ b/arch/arm/cpu/arm920t/at91rm9200/dm9161.c @@ -0,0 +1,225 @@ +/* + * (C) Copyright 2003 + * Author : Hamid Ikdoumi (Atmel) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#ifdef CONFIG_DRIVER_ETHER +#include + +#if defined(CONFIG_CMD_NET) + +/* + * Name: + * dm9161_IsPhyConnected + * Description: + * Reads the 2 PHY ID registers + * Arguments: + * p_mac - pointer to AT91S_EMAC struct + * Return value: + * TRUE - if id read successfully + * FALSE- if error + */ +unsigned int dm9161_IsPhyConnected (AT91PS_EMAC p_mac) +{ + unsigned short Id1, Id2; + + at91rm9200_EmacEnableMDIO (p_mac); + at91rm9200_EmacReadPhy (p_mac, DM9161_PHYID1, &Id1); + at91rm9200_EmacReadPhy (p_mac, DM9161_PHYID2, &Id2); + at91rm9200_EmacDisableMDIO (p_mac); + + if ((Id1 == (DM9161_PHYID1_OUI >> 6)) && + ((Id2 >> 10) == (DM9161_PHYID1_OUI & DM9161_LSB_MASK))) + return TRUE; + + return FALSE; +} + +/* + * Name: + * dm9161_GetLinkSpeed + * Description: + * Link parallel detection status of MAC is checked and set in the + * MAC configuration registers + * Arguments: + * p_mac - pointer to MAC + * Return value: + * TRUE - if link status set succesfully + * FALSE - if link status not set + */ +UCHAR dm9161_GetLinkSpeed (AT91PS_EMAC p_mac) +{ + unsigned short stat1, stat2; + + if (!at91rm9200_EmacReadPhy (p_mac, DM9161_BMSR, &stat1)) + return FALSE; + + if (!(stat1 & DM9161_LINK_STATUS)) /* link status up? */ + return FALSE; + + if (!at91rm9200_EmacReadPhy (p_mac, DM9161_DSCSR, &stat2)) + return FALSE; + + if ((stat1 & DM9161_100BASE_TX_FD) && (stat2 & DM9161_100FDX)) { + /*set Emac for 100BaseTX and Full Duplex */ + p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD; + return TRUE; + } + + if ((stat1 & DM9161_10BASE_T_FD) && (stat2 & DM9161_10FDX)) { + /*set MII for 10BaseT and Full Duplex */ + p_mac->EMAC_CFG = (p_mac->EMAC_CFG & + ~(AT91C_EMAC_SPD | AT91C_EMAC_FD)) + | AT91C_EMAC_FD; + return TRUE; + } + + if ((stat1 & DM9161_100BASE_TX_HD) && (stat2 & DM9161_100HDX)) { + /*set MII for 100BaseTX and Half Duplex */ + p_mac->EMAC_CFG = (p_mac->EMAC_CFG & + ~(AT91C_EMAC_SPD | AT91C_EMAC_FD)) + | AT91C_EMAC_SPD; + return TRUE; + } + + if ((stat1 & DM9161_10BASE_T_HD) && (stat2 & DM9161_10HDX)) { + /*set MII for 10BaseT and Half Duplex */ + p_mac->EMAC_CFG &= ~(AT91C_EMAC_SPD | AT91C_EMAC_FD); + return TRUE; + } + return FALSE; +} + + +/* + * Name: + * dm9161_InitPhy + * Description: + * MAC starts checking its link by using parallel detection and + * Autonegotiation and the same is set in the MAC configuration registers + * Arguments: + * p_mac - pointer to struct AT91S_EMAC + * Return value: + * TRUE - if link status set succesfully + * FALSE - if link status not set + */ +UCHAR dm9161_InitPhy (AT91PS_EMAC p_mac) +{ + UCHAR ret = TRUE; + unsigned short IntValue; + + at91rm9200_EmacEnableMDIO (p_mac); + + if (!dm9161_GetLinkSpeed (p_mac)) { + /* Try another time */ + ret = dm9161_GetLinkSpeed (p_mac); + } + + /* Disable PHY Interrupts */ + at91rm9200_EmacReadPhy (p_mac, DM9161_MDINTR, &IntValue); + /* set FDX, SPD, Link, INTR masks */ + IntValue |= (DM9161_FDX_MASK | DM9161_SPD_MASK | + DM9161_LINK_MASK | DM9161_INTR_MASK); + at91rm9200_EmacWritePhy (p_mac, DM9161_MDINTR, &IntValue); + at91rm9200_EmacDisableMDIO (p_mac); + + return (ret); +} + + +/* + * Name: + * dm9161_AutoNegotiate + * Description: + * MAC Autonegotiates with the partner status of same is set in the + * MAC configuration registers + * Arguments: + * dev - pointer to struct net_device + * Return value: + * TRUE - if link status set successfully + * FALSE - if link status not set + */ +UCHAR dm9161_AutoNegotiate (AT91PS_EMAC p_mac, int *status) +{ + unsigned short value; + unsigned short PhyAnar; + unsigned short PhyAnalpar; + + /* Set dm9161 control register */ + if (!at91rm9200_EmacReadPhy (p_mac, DM9161_BMCR, &value)) + return FALSE; + value &= ~DM9161_AUTONEG; /* remove autonegotiation enable */ + value |= DM9161_ISOLATE; /* Electrically isolate PHY */ + if (!at91rm9200_EmacWritePhy (p_mac, DM9161_BMCR, &value)) + return FALSE; + + /* Set the Auto_negotiation Advertisement Register */ + /* MII advertising for Next page, 100BaseTxFD and HD, */ + /* 10BaseTFD and HD, IEEE 802.3 */ + PhyAnar = DM9161_NP | DM9161_TX_FDX | DM9161_TX_HDX | + DM9161_10_FDX | DM9161_10_HDX | DM9161_AN_IEEE_802_3; + if (!at91rm9200_EmacWritePhy (p_mac, DM9161_ANAR, &PhyAnar)) + return FALSE; + + /* Read the Control Register */ + if (!at91rm9200_EmacReadPhy (p_mac, DM9161_BMCR, &value)) + return FALSE; + + value |= DM9161_SPEED_SELECT | DM9161_AUTONEG | DM9161_DUPLEX_MODE; + if (!at91rm9200_EmacWritePhy (p_mac, DM9161_BMCR, &value)) + return FALSE; + /* Restart Auto_negotiation */ + value |= DM9161_RESTART_AUTONEG; + value &= ~DM9161_ISOLATE; + if (!at91rm9200_EmacWritePhy (p_mac, DM9161_BMCR, &value)) + return FALSE; + + /*check AutoNegotiate complete */ + udelay (10000); + at91rm9200_EmacReadPhy (p_mac, DM9161_BMSR, &value); + if (!(value & DM9161_AUTONEG_COMP)) + return FALSE; + + /* Get the AutoNeg Link partner base page */ + if (!at91rm9200_EmacReadPhy (p_mac, DM9161_ANLPAR, &PhyAnalpar)) + return FALSE; + + if ((PhyAnar & DM9161_TX_FDX) && (PhyAnalpar & DM9161_TX_FDX)) { + /*set MII for 100BaseTX and Full Duplex */ + p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD; + return TRUE; + } + + if ((PhyAnar & DM9161_10_FDX) && (PhyAnalpar & DM9161_10_FDX)) { + /*set MII for 10BaseT and Full Duplex */ + p_mac->EMAC_CFG = (p_mac->EMAC_CFG & + ~(AT91C_EMAC_SPD | AT91C_EMAC_FD)) + | AT91C_EMAC_FD; + return TRUE; + } + return FALSE; +} + +#endif + +#endif /* CONFIG_DRIVER_ETHER */ diff --git a/arch/arm/cpu/arm920t/at91rm9200/ether.c b/arch/arm/cpu/arm920t/at91rm9200/ether.c new file mode 100644 index 0000000000..91eab95eed --- /dev/null +++ b/arch/arm/cpu/arm920t/at91rm9200/ether.c @@ -0,0 +1,316 @@ +/* + * (C) Copyright 2003 + * Author : Hamid Ikdoumi (Atmel) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include + +/* ----- Ethernet Buffer definitions ----- */ + +typedef struct { + unsigned long addr, size; +} rbf_t; + +#define RBF_ADDR 0xfffffffc +#define RBF_OWNER (1<<0) +#define RBF_WRAP (1<<1) +#define RBF_BROADCAST (1<<31) +#define RBF_MULTICAST (1<<30) +#define RBF_UNICAST (1<<29) +#define RBF_EXTERNAL (1<<28) +#define RBF_UNKOWN (1<<27) +#define RBF_SIZE 0x07ff +#define RBF_LOCAL4 (1<<26) +#define RBF_LOCAL3 (1<<25) +#define RBF_LOCAL2 (1<<24) +#define RBF_LOCAL1 (1<<23) + +#define RBF_FRAMEMAX 64 +#define RBF_FRAMELEN 0x600 + +#ifdef CONFIG_DRIVER_ETHER + +#if defined(CONFIG_CMD_NET) + +/* alignment as per Errata #11 (64 bytes) is insufficient! */ +rbf_t rbfdt[RBF_FRAMEMAX] __attribute__((aligned(512))); +rbf_t *rbfp; + +unsigned char rbf_framebuf[RBF_FRAMEMAX][RBF_FRAMELEN] + __attribute__((aligned(4))); + +/* structure to interface the PHY */ +AT91S_PhyOps PhyOps; + +AT91PS_EMAC p_mac; + +/*********** EMAC Phy layer Management functions *************************/ +/* + * Name: + * at91rm9200_EmacEnableMDIO + * Description: + * Enables the MDIO bit in MAC control register + * Arguments: + * p_mac - pointer to struct AT91S_EMAC + * Return value: + * none + */ +void at91rm9200_EmacEnableMDIO (AT91PS_EMAC p_mac) +{ + /* Mac CTRL reg set for MDIO enable */ + p_mac->EMAC_CTL |= AT91C_EMAC_MPE; /* Management port enable */ +} + +/* + * Name: + * at91rm9200_EmacDisableMDIO + * Description: + * Disables the MDIO bit in MAC control register + * Arguments: + * p_mac - pointer to struct AT91S_EMAC + * Return value: + * none + */ +void at91rm9200_EmacDisableMDIO (AT91PS_EMAC p_mac) +{ + /* Mac CTRL reg set for MDIO disable */ + p_mac->EMAC_CTL &= ~AT91C_EMAC_MPE; /* Management port disable */ +} + + +/* + * Name: + * at91rm9200_EmacReadPhy + * Description: + * Reads data from the PHY register + * Arguments: + * dev - pointer to struct net_device + * RegisterAddress - unsigned char + * pInput - pointer to value read from register + * Return value: + * TRUE - if data read successfully + */ +UCHAR at91rm9200_EmacReadPhy (AT91PS_EMAC p_mac, + unsigned char RegisterAddress, + unsigned short *pInput) +{ + p_mac->EMAC_MAN = (AT91C_EMAC_HIGH & ~AT91C_EMAC_LOW) | + (AT91C_EMAC_RW_R) | + (RegisterAddress << 18) | + (AT91C_EMAC_CODE_802_3); + + udelay (10000); + + *pInput = (unsigned short) p_mac->EMAC_MAN; + + return TRUE; +} + + +/* + * Name: + * at91rm9200_EmacWritePhy + * Description: + * Writes data to the PHY register + * Arguments: + * dev - pointer to struct net_device + * RegisterAddress - unsigned char + * pOutput - pointer to value to be written in the register + * Return value: + * TRUE - if data read successfully + */ +UCHAR at91rm9200_EmacWritePhy (AT91PS_EMAC p_mac, + unsigned char RegisterAddress, + unsigned short *pOutput) +{ + p_mac->EMAC_MAN = (AT91C_EMAC_HIGH & ~AT91C_EMAC_LOW) | + AT91C_EMAC_CODE_802_3 | AT91C_EMAC_RW_W | + (RegisterAddress << 18) | *pOutput; + + udelay (10000); + + return TRUE; +} + +int eth_init (bd_t * bd) +{ + int ret; + int i; + uchar enetaddr[6]; + + p_mac = AT91C_BASE_EMAC; + + /* PIO Disable Register */ + *AT91C_PIOA_PDR = AT91C_PA16_EMDIO | AT91C_PA15_EMDC | AT91C_PA14_ERXER | + AT91C_PA13_ERX1 | AT91C_PA12_ERX0 | AT91C_PA11_ECRS_ECRSDV | + AT91C_PA10_ETX1 | AT91C_PA9_ETX0 | AT91C_PA8_ETXEN | + AT91C_PA7_ETXCK_EREFCK; + +#ifdef CONFIG_AT91C_USE_RMII + *AT91C_PIOB_PDR = AT91C_PB19_ERXCK; + *AT91C_PIOB_BSR = AT91C_PB19_ERXCK; +#else + *AT91C_PIOB_PDR = AT91C_PB19_ERXCK | AT91C_PB18_ECOL | AT91C_PB17_ERXDV | + AT91C_PB16_ERX3 | AT91C_PB15_ERX2 | AT91C_PB14_ETXER | + AT91C_PB13_ETX3 | AT91C_PB12_ETX2; + + /* Select B Register */ + *AT91C_PIOB_BSR = AT91C_PB19_ERXCK | AT91C_PB18_ECOL | + AT91C_PB17_ERXDV | AT91C_PB16_ERX3 | AT91C_PB15_ERX2 | + AT91C_PB14_ETXER | AT91C_PB13_ETX3 | AT91C_PB12_ETX2; +#endif + + *AT91C_PMC_PCER = 1 << AT91C_ID_EMAC; /* Peripheral Clock Enable Register */ + + p_mac->EMAC_CFG |= AT91C_EMAC_CSR; /* Clear statistics */ + + /* Init Ethernet buffers */ + for (i = 0; i < RBF_FRAMEMAX; i++) { + rbfdt[i].addr = (unsigned long)rbf_framebuf[i]; + rbfdt[i].size = 0; + } + rbfdt[RBF_FRAMEMAX - 1].addr |= RBF_WRAP; + rbfp = &rbfdt[0]; + + eth_getenv_enetaddr("ethaddr", enetaddr); + + /* The CSB337 originally used a version of the MicroMonitor bootloader + * which saved Ethernet addresses in the "wrong" order. Operating + * systems (like Linux) know this, and apply a workaround. Replicate + * that MicroMonitor behavior so we avoid needing to make such OS code + * care about which bootloader was used. + */ + if (machine_is_csb337()) { + p_mac->EMAC_SA2H = (enetaddr[0] << 8) | (enetaddr[1]); + p_mac->EMAC_SA2L = (enetaddr[2] << 24) | (enetaddr[3] << 16) + | (enetaddr[4] << 8) | (enetaddr[5]); + } else { + p_mac->EMAC_SA2L = (enetaddr[3] << 24) | (enetaddr[2] << 16) + | (enetaddr[1] << 8) | (enetaddr[0]); + p_mac->EMAC_SA2H = (enetaddr[5] << 8) | (enetaddr[4]); + } + + p_mac->EMAC_RBQP = (long) (&rbfdt[0]); + p_mac->EMAC_RSR &= ~(AT91C_EMAC_RSR_OVR | AT91C_EMAC_REC | AT91C_EMAC_BNA); + + p_mac->EMAC_CFG = (p_mac->EMAC_CFG | AT91C_EMAC_CAF | AT91C_EMAC_NBC) + & ~AT91C_EMAC_CLK; + +#ifdef CONFIG_AT91C_USE_RMII + p_mac->EMAC_CFG |= AT91C_EMAC_RMII; +#endif + +#if (AT91C_MASTER_CLOCK > 40000000) + /* MDIO clock must not exceed 2.5 MHz, so enable MCK divider */ + p_mac->EMAC_CFG |= AT91C_EMAC_CLK_HCLK_64; +#endif + + p_mac->EMAC_CTL |= AT91C_EMAC_TE | AT91C_EMAC_RE; + + at91rm9200_GetPhyInterface (& PhyOps); + + if (!PhyOps.IsPhyConnected (p_mac)) + printf ("PHY not connected!!\n\r"); + + /* MII management start from here */ + if (!(p_mac->EMAC_SR & AT91C_EMAC_LINK)) { + if (!(ret = PhyOps.Init (p_mac))) { + printf ("MAC: error during MII initialization\n"); + return 0; + } + } else { + printf ("No link\n\r"); + return 0; + } + + return 0; +} + +int eth_send (volatile void *packet, int length) +{ + while (!(p_mac->EMAC_TSR & AT91C_EMAC_BNQ)); + p_mac->EMAC_TAR = (long) packet; + p_mac->EMAC_TCR = length; + while (p_mac->EMAC_TCR & 0x7ff); + p_mac->EMAC_TSR |= AT91C_EMAC_COMP; + return 0; +} + +int eth_rx (void) +{ + int size; + + if (!(rbfp->addr & RBF_OWNER)) + return 0; + + size = rbfp->size & RBF_SIZE; + NetReceive ((volatile uchar *) (rbfp->addr & RBF_ADDR), size); + + rbfp->addr &= ~RBF_OWNER; + if (rbfp->addr & RBF_WRAP) + rbfp = &rbfdt[0]; + else + rbfp++; + + p_mac->EMAC_RSR |= AT91C_EMAC_REC; + + return size; +} + +void eth_halt (void) +{ +}; + +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) +int at91rm9200_miiphy_read(char *devname, unsigned char addr, + unsigned char reg, unsigned short * value) +{ + at91rm9200_EmacEnableMDIO (p_mac); + at91rm9200_EmacReadPhy (p_mac, reg, value); + at91rm9200_EmacDisableMDIO (p_mac); + return 0; +} + +int at91rm9200_miiphy_write(char *devname, unsigned char addr, + unsigned char reg, unsigned short value) +{ + at91rm9200_EmacEnableMDIO (p_mac); + at91rm9200_EmacWritePhy (p_mac, reg, &value); + at91rm9200_EmacDisableMDIO (p_mac); + return 0; +} + +#endif + +int at91rm9200_miiphy_initialize(bd_t *bis) +{ +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) + miiphy_register("at91rm9200phy", at91rm9200_miiphy_read, at91rm9200_miiphy_write); +#endif + return 0; +} + +#endif + +#endif /* CONFIG_DRIVER_ETHER */ diff --git a/arch/arm/cpu/arm920t/at91rm9200/i2c.c b/arch/arm/cpu/arm920t/at91rm9200/i2c.c new file mode 100644 index 0000000000..1711088ad3 --- /dev/null +++ b/arch/arm/cpu/arm920t/at91rm9200/i2c.c @@ -0,0 +1,192 @@ +/* + * i2c Support for Atmel's AT91RM9200 Two-Wire Interface + * + * (c) Rick Bronson + * + * Borrowed heavily from original work by: + * Copyright (c) 2000 Philip Edelbrock + * + * Modified to work with u-boot by (C) 2004 Gary Jennejohn garyj@denx.de + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * +*/ +#include + +#ifdef CONFIG_HARD_I2C + +#include +#include +#include + +#include + +/* define DEBUG */ + +/* + * Poll the i2c status register until the specified bit is set. + * Returns 0 if timed out (100 msec) + */ +static short at91_poll_status(AT91PS_TWI twi, unsigned long bit) { + int loop_cntr = 10000; + do { + udelay(10); + } while (!(twi->TWI_SR & bit) && (--loop_cntr > 0)); + + return (loop_cntr > 0); +} + +/* + * Generic i2c master transfer entrypoint + * + * rw == 1 means that this is a read + */ +static int +at91_xfer(unsigned char chip, unsigned int addr, int alen, + unsigned char *buffer, int len, int rw) +{ + AT91PS_TWI twi = (AT91PS_TWI) AT91_TWI_BASE; + int length; + unsigned char *buf; + /* Set the TWI Master Mode Register */ + twi->TWI_MMR = (chip << 16) | (alen << 8) + | ((rw == 1) ? AT91C_TWI_MREAD : 0); + + /* Set TWI Internal Address Register with first messages data field */ + if (alen > 0) + twi->TWI_IADR = addr; + + length = len; + buf = buffer; + if (length && buf) { /* sanity check */ + if (rw) { + twi->TWI_CR = AT91C_TWI_START; + while (length--) { + if (!length) + twi->TWI_CR = AT91C_TWI_STOP; + /* Wait until transfer is finished */ + if (!at91_poll_status(twi, AT91C_TWI_RXRDY)) { + debug ("at91_i2c: timeout 1\n"); + return 1; + } + *buf++ = twi->TWI_RHR; + } + if (!at91_poll_status(twi, AT91C_TWI_TXCOMP)) { + debug ("at91_i2c: timeout 2\n"); + return 1; + } + } else { + twi->TWI_CR = AT91C_TWI_START; + while (length--) { + twi->TWI_THR = *buf++; + if (!length) + twi->TWI_CR = AT91C_TWI_STOP; + if (!at91_poll_status(twi, AT91C_TWI_TXRDY)) { + debug ("at91_i2c: timeout 3\n"); + return 1; + } + } + /* Wait until transfer is finished */ + if (!at91_poll_status(twi, AT91C_TWI_TXCOMP)) { + debug ("at91_i2c: timeout 4\n"); + return 1; + } + } + } + return 0; +} + +int +i2c_probe(unsigned char chip) +{ + unsigned char buffer[1]; + + return at91_xfer(chip, 0, 0, buffer, 1, 1); +} + +int +i2c_read (unsigned char chip, unsigned int addr, int alen, + unsigned char *buffer, int len) +{ +#ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW + /* we only allow one address byte */ + if (alen > 1) + return 1; + /* XXX assume an ATMEL AT24C16 */ + if (alen == 1) { +#if 0 /* EEPROM code already sets this correctly */ + chip |= (addr >> 8) & 0xff; +#endif + addr = addr & 0xff; + } +#endif + return at91_xfer(chip, addr, alen, buffer, len, 1); +} + +int +i2c_write(unsigned char chip, unsigned int addr, int alen, + unsigned char *buffer, int len) +{ +#ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW + int i; + unsigned char *buf; + + /* we only allow one address byte */ + if (alen > 1) + return 1; + /* XXX assume an ATMEL AT24C16 */ + if (alen == 1) { + buf = buffer; + /* do single byte writes */ + for (i = 0; i < len; i++) { +#if 0 /* EEPROM code already sets this correctly */ + chip |= (addr >> 8) & 0xff; +#endif + addr = addr & 0xff; + if (at91_xfer(chip, addr, alen, buf++, 1, 0)) + return 1; + addr++; + } + return 0; + } +#endif + return at91_xfer(chip, addr, alen, buffer, len, 0); +} + +/* + * Main initialization routine + */ +void +i2c_init(int speed, int slaveaddr) +{ + AT91PS_TWI twi = (AT91PS_TWI) AT91_TWI_BASE; + + *AT91C_PIOA_PDR = AT91C_PA25_TWD | AT91C_PA26_TWCK; + *AT91C_PIOA_ASR = AT91C_PA25_TWD | AT91C_PA26_TWCK; + *AT91C_PIOA_MDER = AT91C_PA25_TWD | AT91C_PA26_TWCK; + *AT91C_PMC_PCER = 1 << AT91C_ID_TWI; /* enable peripheral clock */ + + twi->TWI_IDR = 0x3ff; /* Disable all interrupts */ + twi->TWI_CR = AT91C_TWI_SWRST; /* Reset peripheral */ + twi->TWI_CR = AT91C_TWI_MSEN | AT91C_TWI_SVDIS; /* Set Master mode */ + + /* Here, CKDIV = 1 and CHDIV=CLDIV ==> CLDIV = CHDIV = 1/4*((Fmclk/FTWI) -6) */ + twi->TWI_CWGR = AT91C_TWI_CKDIV1 | AT91C_TWI_CLDIV3 | (AT91C_TWI_CLDIV3 << 8); + + debug ("Found AT91 i2c\n"); + return; +} + +#endif /* CONFIG_HARD_I2C */ diff --git a/arch/arm/cpu/arm920t/at91rm9200/ks8721.c b/arch/arm/cpu/arm920t/at91rm9200/ks8721.c new file mode 100644 index 0000000000..9fe379369a --- /dev/null +++ b/arch/arm/cpu/arm920t/at91rm9200/ks8721.c @@ -0,0 +1,249 @@ +/* + * (C) Copyright 2006 + * Author : Eric Benard (Eukrea Electromatique) + * based on dm9161.c which is : + * (C) Copyright 2003 + * Author : Hamid Ikdoumi (Atmel) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +#ifdef CONFIG_DRIVER_ETHER + +#if defined(CONFIG_CMD_NET) + +/* + * Name: + * ks8721_isphyconnected + * Description: + * Reads the 2 PHY ID registers + * Arguments: + * p_mac - pointer to AT91S_EMAC struct + * Return value: + * 1 - if id read successfully + * 0 - if error + */ +unsigned int ks8721_isphyconnected(AT91PS_EMAC p_mac) +{ + unsigned short id1, id2; + + at91rm9200_EmacEnableMDIO(p_mac); + at91rm9200_EmacReadPhy(p_mac, + CONFIG_PHY_ADDRESS | KS8721_PHYID1, &id1); + at91rm9200_EmacReadPhy(p_mac, + CONFIG_PHY_ADDRESS | KS8721_PHYID2, &id2); + at91rm9200_EmacDisableMDIO(p_mac); + + if ((id1 == (KS8721_PHYID_OUI >> 6)) && + ((id2 >> 10) == (KS8721_PHYID_OUI & KS8721_LSB_MASK))) { + if ((id2 & KS8721_MODELMASK) == KS8721BL_MODEL) + printf("Micrel KS8721bL PHY detected : "); + else + printf("Unknown Micrel PHY detected : "); + return 1; + } + return 0; +} + +/* + * Name: + * ks8721_getlinkspeed + * Description: + * Link parallel detection status of MAC is checked and set in the + * MAC configuration registers + * Arguments: + * p_mac - pointer to MAC + * Return value: + * 1 - if link status set succesfully + * 0 - if link status not set + */ +unsigned char ks8721_getlinkspeed(AT91PS_EMAC p_mac) +{ + unsigned short stat1; + + if (!at91rm9200_EmacReadPhy(p_mac, KS8721_BMSR, &stat1)) + return 0; + + if (!(stat1 & KS8721_LINK_STATUS)) { + /* link status up? */ + printf("Link Down !\n"); + return 0; + } + + if (stat1 & KS8721_100BASE_TX_FD) { + /* set Emac for 100BaseTX and Full Duplex */ + printf("100BT FD\n"); + p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD; + return 1; + } + + if (stat1 & KS8721_10BASE_T_FD) { + /* set MII for 10BaseT and Full Duplex */ + printf("10BT FD\n"); + p_mac->EMAC_CFG = (p_mac->EMAC_CFG & + ~(AT91C_EMAC_SPD | AT91C_EMAC_FD)) + | AT91C_EMAC_FD; + return 1; + } + + if (stat1 & KS8721_100BASE_T4_HD) { + /* set MII for 100BaseTX and Half Duplex */ + printf("100BT HD\n"); + p_mac->EMAC_CFG = (p_mac->EMAC_CFG & + ~(AT91C_EMAC_SPD | AT91C_EMAC_FD)) + | AT91C_EMAC_SPD; + return 1; + } + + if (stat1 & KS8721_10BASE_T_HD) { + /* set MII for 10BaseT and Half Duplex */ + printf("10BT HD\n"); + p_mac->EMAC_CFG &= ~(AT91C_EMAC_SPD | AT91C_EMAC_FD); + return 1; + } + return 0; +} + +/* + * Name: + * ks8721_initphy + * Description: + * MAC starts checking its link by using parallel detection and + * Autonegotiation and the same is set in the MAC configuration registers + * Arguments: + * p_mac - pointer to struct AT91S_EMAC + * Return value: + * 1 - if link status set succesfully + * 0 - if link status not set + */ +unsigned char ks8721_initphy(AT91PS_EMAC p_mac) +{ + unsigned char ret = 1; + unsigned short intvalue; + + at91rm9200_EmacEnableMDIO(p_mac); + + /* Try another time */ + if (!ks8721_getlinkspeed(p_mac)) + ret = ks8721_getlinkspeed(p_mac); + + /* Disable PHY Interrupts */ + intvalue = 0; + at91rm9200_EmacWritePhy(p_mac, + CONFIG_PHY_ADDRESS | KS8721_MDINTR, &intvalue); + at91rm9200_EmacDisableMDIO(p_mac); + + return ret; +} + +/* + * Name: + * ks8721_autonegotiate + * Description: + * MAC Autonegotiates with the partner status of same is set in the + * MAC configuration registers + * Arguments: + * dev - pointer to struct net_device + * Return value: + * 1 - if link status set successfully + * 0 - if link status not set + */ +unsigned char ks8721_autonegotiate(AT91PS_EMAC p_mac, int *status) +{ + unsigned short value; + unsigned short phyanar; + unsigned short phyanalpar; + + /* Set ks8721 control register */ + if (!at91rm9200_EmacReadPhy(p_mac, + CONFIG_PHY_ADDRESS | KS8721_BMCR, &value)) + return 0; + + /* remove autonegotiation enable */ + value &= ~KS8721_AUTONEG; + /* Electrically isolate PHY */ + value |= KS8721_ISOLATE; + if (!at91rm9200_EmacWritePhy(p_mac, + CONFIG_PHY_ADDRESS | KS8721_BMCR, &value)) { + return 0; + } + /* + * Set the Auto_negotiation Advertisement Register + * MII advertising for Next page, 100BaseTxFD and HD, + * 10BaseTFD and HD, IEEE 802.3 + */ + phyanar = KS8721_NP | KS8721_TX_FDX | KS8721_TX_HDX | + KS8721_10_FDX | KS8721_10_HDX | KS8721_AN_IEEE_802_3; + if (!at91rm9200_EmacWritePhy(p_mac, + CONFIG_PHY_ADDRESS | KS8721_ANAR, &phyanar)) { + return 0; + } + /* Read the Control Register */ + if (!at91rm9200_EmacReadPhy(p_mac, + CONFIG_PHY_ADDRESS | KS8721_BMCR, &value)) { + return 0; + } + value |= KS8721_SPEED_SELECT | KS8721_AUTONEG | KS8721_DUPLEX_MODE; + if (!at91rm9200_EmacWritePhy(p_mac, + CONFIG_PHY_ADDRESS | KS8721_BMCR, &value)) { + return 0; + } + /* Restart Auto_negotiation */ + value |= KS8721_RESTART_AUTONEG; + value &= ~KS8721_ISOLATE; + if (!at91rm9200_EmacWritePhy(p_mac, + CONFIG_PHY_ADDRESS | KS8721_BMCR, &value)) { + return 0; + } + /* Check AutoNegotiate complete */ + udelay(10000); + at91rm9200_EmacReadPhy(p_mac, + CONFIG_PHY_ADDRESS | KS8721_BMSR, &value); + if (!(value & KS8721_AUTONEG_COMP)) + return 0; + + /* Get the AutoNeg Link partner base page */ + if (!at91rm9200_EmacReadPhy(p_mac, + CONFIG_PHY_ADDRESS | KS8721_ANLPAR, &phyanalpar)) { + return 0; + } + + if ((phyanar & KS8721_TX_FDX) && (phyanalpar & KS8721_TX_FDX)) { + /* Set MII for 100BaseTX and Full Duplex */ + p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD; + return 1; + } + + if ((phyanar & KS8721_10_FDX) && (phyanalpar & KS8721_10_FDX)) { + /* Set MII for 10BaseT and Full Duplex */ + p_mac->EMAC_CFG = (p_mac->EMAC_CFG & + ~(AT91C_EMAC_SPD | AT91C_EMAC_FD)) + | AT91C_EMAC_FD; + return 1; + } + return 0; +} + +#endif /* CONFIG_CMD_NET */ + +#endif /* CONFIG_DRIVER_ETHER */ diff --git a/arch/arm/cpu/arm920t/at91rm9200/lowlevel_init.S b/arch/arm/cpu/arm920t/at91rm9200/lowlevel_init.S new file mode 100644 index 0000000000..d8bb96004b --- /dev/null +++ b/arch/arm/cpu/arm920t/at91rm9200/lowlevel_init.S @@ -0,0 +1,169 @@ +/* + * Memory Setup stuff - taken from blob memsetup.S + * + * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and + * Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl) + * + * Modified for the at91rm9200dk board by + * (C) Copyright 2004 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +#ifndef CONFIG_SKIP_LOWLEVEL_INIT +/* + * some parameters for the board + * + * This is based on rm9200dk.cfg for the BDI2000 from ABATRON which in + * turn is based on the boot.bin code from ATMEL + * + */ +#include + +_MTEXT_BASE: +#undef START_FROM_MEM +#ifdef START_FROM_MEM + .word TEXT_BASE-PHYS_FLASH_1 +#else + .word TEXT_BASE +#endif + +.globl lowlevel_init +lowlevel_init: + /* Get the CKGR Base Address */ + ldr r1, =AT91C_BASE_CKGR + /* Main oscillator Enable register */ +#ifdef CONFIG_SYS_USE_MAIN_OSCILLATOR + ldr r0, =0x0000FF01 /* Enable main oscillator, OSCOUNT = 0xFF */ +#else + ldr r0, =0x0000FF00 /* Disable main oscillator, OSCOUNT = 0xFF */ +#endif + str r0, [r1, #AT91C_CKGR_MOR] + /* Add loop to compensate Main Oscillator startup time */ + ldr r0, =0x00000010 +LoopOsc: + subs r0, r0, #1 + bhi LoopOsc + + /* memory control configuration */ + /* this isn't very elegant, but what the heck */ + ldr r0, =SMRDATA + ldr r1, _MTEXT_BASE + sub r0, r0, r1 + add r2, r0, #80 +0: + /* the address */ + ldr r1, [r0], #4 + /* the value */ + ldr r3, [r0], #4 + str r3, [r1] + cmp r2, r0 + bne 0b + /* delay - this is all done by guess */ + ldr r0, =0x00010000 + /* (vs reading PMC_SR for LOCKA, LOCKB ... or MOSCS earlier) */ +1: + subs r0, r0, #1 + bhi 1b + ldr r0, =SMRDATA1 + ldr r1, _MTEXT_BASE + sub r0, r0, r1 + add r2, r0, #176 +2: + /* the address */ + ldr r1, [r0], #4 + /* the value */ + ldr r3, [r0], #4 + str r3, [r1] + cmp r2, r0 + bne 2b + + /* switch from FastBus to Asynchronous clock mode */ + mrc p15, 0, r0, c1, c0, 0 + orr r0, r0, #0xC0000000 @ set bit 31 (iA) and 30 (nF) + mcr p15, 0, r0, c1, c0, 0 + + /* everything is fine now */ + mov pc, lr + + .ltorg + +SMRDATA: + .word AT91C_EBI_CFGR + .word CONFIG_SYS_EBI_CFGR_VAL + .word AT91C_SMC_CSR0 + .word CONFIG_SYS_SMC_CSR0_VAL + .word AT91C_PLLAR + .word CONFIG_SYS_PLLAR_VAL + .word AT91C_PLLBR + .word CONFIG_SYS_PLLBR_VAL + .word AT91C_MCKR + .word CONFIG_SYS_MCKR_VAL + /* here there's a delay */ +SMRDATA1: + .word AT91C_PIOC_ASR + .word CONFIG_SYS_PIOC_ASR_VAL + .word AT91C_PIOC_BSR + .word CONFIG_SYS_PIOC_BSR_VAL + .word AT91C_PIOC_PDR + .word CONFIG_SYS_PIOC_PDR_VAL + .word AT91C_EBI_CSA + .word CONFIG_SYS_EBI_CSA_VAL + .word AT91C_SDRC_CR + .word CONFIG_SYS_SDRC_CR_VAL + .word AT91C_SDRC_MR + .word CONFIG_SYS_SDRC_MR_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word AT91C_SDRC_MR + .word CONFIG_SYS_SDRC_MR_VAL1 + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word AT91C_SDRC_MR + .word CONFIG_SYS_SDRC_MR_VAL2 + .word CONFIG_SYS_SDRAM1 + .word CONFIG_SYS_SDRAM_VAL + .word AT91C_SDRC_TR + .word CONFIG_SYS_SDRC_TR_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word AT91C_SDRC_MR + .word CONFIG_SYS_SDRC_MR_VAL3 + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + /* SMRDATA1 is 176 bytes long */ +#endif /* CONFIG_SKIP_LOWLEVEL_INIT */ diff --git a/arch/arm/cpu/arm920t/at91rm9200/lxt972.c b/arch/arm/cpu/arm920t/at91rm9200/lxt972.c new file mode 100644 index 0000000000..260d393cf0 --- /dev/null +++ b/arch/arm/cpu/arm920t/at91rm9200/lxt972.c @@ -0,0 +1,192 @@ +/* + * + * (C) Copyright 2003 + * Author : Hamid Ikdoumi (Atmel) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * Adapted for KwikByte KB920x board: 22APR2005 + */ + +#include +#include +#include +#include +#include + +#ifdef CONFIG_DRIVER_ETHER + +#if defined(CONFIG_CMD_NET) + +/* + * Name: + * lxt972_IsPhyConnected + * Description: + * Reads the 2 PHY ID registers + * Arguments: + * p_mac - pointer to AT91S_EMAC struct + * Return value: + * TRUE - if id read successfully + * FALSE- if error + */ +unsigned int lxt972_IsPhyConnected (AT91PS_EMAC p_mac) +{ + unsigned short Id1, Id2; + + at91rm9200_EmacEnableMDIO (p_mac); + at91rm9200_EmacReadPhy(p_mac, PHY_PHYIDR1, &Id1); + at91rm9200_EmacReadPhy(p_mac, PHY_PHYIDR2, &Id2); + at91rm9200_EmacDisableMDIO (p_mac); + + if ((Id1 == (0x0013)) && ((Id2 & 0xFFF0) == 0x78E0)) + return TRUE; + + return FALSE; +} + +/* + * Name: + * lxt972_GetLinkSpeed + * Description: + * Link parallel detection status of MAC is checked and set in the + * MAC configuration registers + * Arguments: + * p_mac - pointer to MAC + * Return value: + * TRUE - if link status set succesfully + * FALSE - if link status not set + */ +UCHAR lxt972_GetLinkSpeed (AT91PS_EMAC p_mac) +{ + unsigned short stat1; + + if (!at91rm9200_EmacReadPhy (p_mac, PHY_LXT971_STAT2, &stat1)) + return FALSE; + + if (!(stat1 & PHY_LXT971_STAT2_LINK)) /* link status up? */ + return FALSE; + + if (stat1 & PHY_LXT971_STAT2_100BTX) { + + if (stat1 & PHY_LXT971_STAT2_DUPLEX_MODE) { + + /*set Emac for 100BaseTX and Full Duplex */ + p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD; + } else { + + /*set Emac for 100BaseTX and Half Duplex */ + p_mac->EMAC_CFG = (p_mac->EMAC_CFG & + ~(AT91C_EMAC_SPD | AT91C_EMAC_FD)) + | AT91C_EMAC_SPD; + } + + return TRUE; + + } else { + + if (stat1 & PHY_LXT971_STAT2_DUPLEX_MODE) { + + /*set MII for 10BaseT and Full Duplex */ + p_mac->EMAC_CFG = (p_mac->EMAC_CFG & + ~(AT91C_EMAC_SPD | AT91C_EMAC_FD)) + | AT91C_EMAC_FD; + } else { + + /*set MII for 10BaseT and Half Duplex */ + p_mac->EMAC_CFG &= ~(AT91C_EMAC_SPD | AT91C_EMAC_FD); + } + + return TRUE; + } + + return FALSE; +} + + +/* + * Name: + * lxt972_InitPhy + * Description: + * MAC starts checking its link by using parallel detection and + * Autonegotiation and the same is set in the MAC configuration registers + * Arguments: + * p_mac - pointer to struct AT91S_EMAC + * Return value: + * TRUE - if link status set succesfully + * FALSE - if link status not set + */ +UCHAR lxt972_InitPhy (AT91PS_EMAC p_mac) +{ + UCHAR ret = TRUE; + + at91rm9200_EmacEnableMDIO (p_mac); + + if (!lxt972_GetLinkSpeed (p_mac)) { + /* Try another time */ + ret = lxt972_GetLinkSpeed (p_mac); + } + + /* Disable PHY Interrupts */ + at91rm9200_EmacWritePhy (p_mac, PHY_LXT971_INT_ENABLE, 0); + + at91rm9200_EmacDisableMDIO (p_mac); + + return (ret); +} + + +/* + * Name: + * lxt972_AutoNegotiate + * Description: + * MAC Autonegotiates with the partner status of same is set in the + * MAC configuration registers + * Arguments: + * dev - pointer to struct net_device + * Return value: + * TRUE - if link status set successfully + * FALSE - if link status not set + */ +UCHAR lxt972_AutoNegotiate (AT91PS_EMAC p_mac, int *status) +{ + unsigned short value; + + /* Set lxt972 control register */ + if (!at91rm9200_EmacReadPhy (p_mac, PHY_BMCR, &value)) + return FALSE; + + /* Restart Auto_negotiation */ + value |= PHY_BMCR_RST_NEG; + if (!at91rm9200_EmacWritePhy (p_mac, PHY_BMCR, &value)) + return FALSE; + + /*check AutoNegotiate complete */ + udelay (10000); + at91rm9200_EmacReadPhy(p_mac, PHY_BMSR, &value); + if (!(value & PHY_BMSR_AUTN_COMP)) + return FALSE; + + return (lxt972_GetLinkSpeed (p_mac)); +} + +#endif + +#endif /* CONFIG_DRIVER_ETHER */ diff --git a/arch/arm/cpu/arm920t/at91rm9200/reset.c b/arch/arm/cpu/arm920t/at91rm9200/reset.c new file mode 100644 index 0000000000..945ea2c248 --- /dev/null +++ b/arch/arm/cpu/arm920t/at91rm9200/reset.c @@ -0,0 +1,71 @@ +/* + * (C) Copyright 2002 + * Lineo, Inc. + * Bernhard Kuhn + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +void board_reset(void) __attribute__((__weak__)); + +/* + * Reset the cpu by setting up the watchdog timer and let him time out + * or toggle a GPIO pin on the AT91RM9200DK board + */ +void reset_cpu (ulong ignored) +{ + +#if defined(CONFIG_AT91RM9200_USART) + /*shutdown the console to avoid strange chars during reset */ + serial_exit(); +#endif + + if (board_reset) + board_reset(); + + /* this is the way Linux does it */ + + /* FIXME: + * These defines should be moved into + * include/asm-arm/arch-at91rm9200/AT91RM9200.h + * as soon as the whitespace fix gets applied. + */ + #define AT91C_ST_RSTEN (0x1 << 16) + #define AT91C_ST_EXTEN (0x1 << 17) + #define AT91C_ST_WDRST (0x1 << 0) + #define ST_WDMR *((unsigned long *)0xfffffd08) /* watchdog mode register */ + #define ST_CR *((unsigned long *)0xfffffd00) /* system clock control register */ + + ST_WDMR = AT91C_ST_RSTEN | AT91C_ST_EXTEN | 1 ; + ST_CR = AT91C_ST_WDRST; + + while (1); + /* Never reached */ +} diff --git a/arch/arm/cpu/arm920t/at91rm9200/spi.c b/arch/arm/cpu/arm920t/at91rm9200/spi.c new file mode 100644 index 0000000000..f3cb5d8c2c --- /dev/null +++ b/arch/arm/cpu/arm920t/at91rm9200/spi.c @@ -0,0 +1,151 @@ +/* Driver for ATMEL DataFlash support + * Author : Hamid Ikdoumi (Atmel) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#include +#include +#include + +#ifdef CONFIG_HAS_DATAFLASH +#include + +#define AT91C_SPI_CLK 10000000 /* Max Value = 10MHz to be compliant to + the Continuous Array Read function */ + +/* AC Characteristics */ +/* DLYBS = tCSS = 250ns min and DLYBCT = tCSH = 250ns */ +#define DATAFLASH_TCSS (0xC << 16) +#define DATAFLASH_TCHS (0x1 << 24) + +#define AT91C_TIMEOUT_WRDY 200000 +#define AT91C_SPI_PCS0_SERIAL_DATAFLASH 0xE /* Chip Select 0: NPCS0%1110 */ +#define AT91C_SPI_PCS3_DATAFLASH_CARD 0x7 /* Chip Select 3: NPCS3%0111 */ + +/*-------------------------------------------------------------------*/ +/* SPI DataFlash Init */ +/*-------------------------------------------------------------------*/ +void AT91F_SpiInit(void) +{ + /* Configure PIOs */ + AT91C_BASE_PIOA->PIO_ASR = + AT91C_PA3_NPCS0 | AT91C_PA4_NPCS1 | AT91C_PA1_MOSI | + AT91C_PA5_NPCS2 | AT91C_PA6_NPCS3 | AT91C_PA0_MISO | + AT91C_PA2_SPCK; + AT91C_BASE_PIOA->PIO_PDR = + AT91C_PA3_NPCS0 | AT91C_PA4_NPCS1 | AT91C_PA1_MOSI | + AT91C_PA5_NPCS2 | AT91C_PA6_NPCS3 | AT91C_PA0_MISO | + AT91C_PA2_SPCK; + /* Enable CLock */ + AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_SPI; + + /* Reset the SPI */ + AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST; + + /* Configure SPI in Master Mode with No CS selected !!! */ + AT91C_BASE_SPI->SPI_MR = + AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | AT91C_SPI_PCS; + + /* Configure CS0 and CS3 */ + *(AT91C_SPI_CSR + 0) = + AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & DATAFLASH_TCSS) | + (AT91C_SPI_DLYBCT & DATAFLASH_TCHS) | + ((AT91C_MASTER_CLOCK / (2*AT91C_SPI_CLK)) << 8); + + *(AT91C_SPI_CSR + 3) = + AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & DATAFLASH_TCSS) | + (AT91C_SPI_DLYBCT & DATAFLASH_TCHS) | + ((AT91C_MASTER_CLOCK / (2*AT91C_SPI_CLK)) << 8); +} + +void AT91F_SpiEnable(int cs) +{ + switch(cs) { + case 0: /* Configure SPI CS0 for Serial DataFlash AT45DBxx */ + AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF; + AT91C_BASE_SPI->SPI_MR |= + ((AT91C_SPI_PCS0_SERIAL_DATAFLASH<<16) & + AT91C_SPI_PCS); + break; + case 3: /* Configure SPI CS3 for Serial DataFlash Card */ + /* Set up PIO SDC_TYPE to switch on DataFlash Card */ + /* and not MMC/SDCard */ + AT91C_BASE_PIOB->PIO_PER = + AT91C_PIO_PB7; /* Set in PIO mode */ + AT91C_BASE_PIOB->PIO_OER = + AT91C_PIO_PB7; /* Configure in output */ + /* Clear Output */ + AT91C_BASE_PIOB->PIO_CODR = AT91C_PIO_PB7; + /* Configure PCS */ + AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF; + AT91C_BASE_SPI->SPI_MR |= + ((AT91C_SPI_PCS3_DATAFLASH_CARD<<16) & AT91C_SPI_PCS); + break; + } + + /* SPI_Enable */ + AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN; } + +/*---------------------------------------------------------------------------*/ +/* \fn AT91F_SpiWrite */ +/* \brief Set the PDC registers for a transfert */ +/*---------------------------------------------------------------------------*/ +unsigned int AT91F_SpiWrite ( AT91PS_DataflashDesc pDesc ) +{ + unsigned int timeout; + + pDesc->state = BUSY; + + AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS; + + /* Initialize the Transmit and Receive Pointer */ + AT91C_BASE_SPI->SPI_RPR = (unsigned int)pDesc->rx_cmd_pt ; + AT91C_BASE_SPI->SPI_TPR = (unsigned int)pDesc->tx_cmd_pt ; + + /* Intialize the Transmit and Receive Counters */ + AT91C_BASE_SPI->SPI_RCR = pDesc->rx_cmd_size; + AT91C_BASE_SPI->SPI_TCR = pDesc->tx_cmd_size; + + if ( pDesc->tx_data_size != 0 ) { + /* Initialize the Next Transmit and Next Receive Pointer */ + AT91C_BASE_SPI->SPI_RNPR = (unsigned int)pDesc->rx_data_pt ; + AT91C_BASE_SPI->SPI_TNPR = (unsigned int)pDesc->tx_data_pt ; + + /* Intialize the Next Transmit and Next Receive Counters */ + AT91C_BASE_SPI->SPI_RNCR = pDesc->rx_data_size ; + AT91C_BASE_SPI->SPI_TNCR = pDesc->tx_data_size ; + } + + /* arm simple, non interrupt dependent timer */ + reset_timer_masked(); + timeout = 0; + + AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTEN + AT91C_PDC_RXTEN; + while(!(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RXBUFF) && + ((timeout = get_timer_masked() ) < CONFIG_SYS_SPI_WRITE_TOUT)); + AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS; + pDesc->state = IDLE; + + if (timeout >= CONFIG_SYS_SPI_WRITE_TOUT){ + printf("Error Timeout\n\r"); + return DATAFLASH_ERROR; + } + + return DATAFLASH_OK; +} +#endif diff --git a/arch/arm/cpu/arm920t/at91rm9200/timer.c b/arch/arm/cpu/arm920t/at91rm9200/timer.c new file mode 100644 index 0000000000..9c54bbedbe --- /dev/null +++ b/arch/arm/cpu/arm920t/at91rm9200/timer.c @@ -0,0 +1,160 @@ +/* + * (C) Copyright 2002 + * Lineo, Inc. + * Bernhard Kuhn + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +/*#include */ +#include +/*#include */ + +/* the number of clocks per CONFIG_SYS_HZ */ +#define TIMER_LOAD_VAL (CONFIG_SYS_HZ_CLOCK/CONFIG_SYS_HZ) + +/* macro to read the 16 bit timer */ +#define READ_TIMER (tmr->TC_CV & 0x0000ffff) +AT91PS_TC tmr; + +static ulong timestamp; +static ulong lastinc; + +int timer_init (void) +{ + tmr = AT91C_BASE_TC0; + + /* enables TC1.0 clock */ + *AT91C_PMC_PCER = 1 << AT91C_ID_TC0; /* enable clock */ + + *AT91C_TCB0_BCR = 0; + *AT91C_TCB0_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_NONE | AT91C_TCB_TC2XC2S_NONE; + tmr->TC_CCR = AT91C_TC_CLKDIS; +#define AT91C_TC_CMR_CPCTRG (1 << 14) + /* set to MCLK/2 and restart the timer when the vlaue in TC_RC is reached */ + tmr->TC_CMR = AT91C_TC_TIMER_DIV1_CLOCK | AT91C_TC_CMR_CPCTRG; + + tmr->TC_IDR = ~0ul; + tmr->TC_RC = TIMER_LOAD_VAL; + lastinc = 0; + tmr->TC_CCR = AT91C_TC_SWTRG | AT91C_TC_CLKEN; + timestamp = 0; + + return (0); +} + +/* + * timer without interrupts + */ + +void reset_timer (void) +{ + reset_timer_masked (); +} + +ulong get_timer (ulong base) +{ + return get_timer_masked () - base; +} + +void set_timer (ulong t) +{ + timestamp = t; +} + +void __udelay (unsigned long usec) +{ + udelay_masked(usec); +} + +void reset_timer_masked (void) +{ + /* reset time */ + lastinc = READ_TIMER; + timestamp = 0; +} + +ulong get_timer_raw (void) +{ + ulong now = READ_TIMER; + + if (now >= lastinc) { + /* normal mode */ + timestamp += now - lastinc; + } else { + /* we have an overflow ... */ + timestamp += now + TIMER_LOAD_VAL - lastinc; + } + lastinc = now; + + return timestamp; +} + +ulong get_timer_masked (void) +{ + return get_timer_raw()/TIMER_LOAD_VAL; +} + +void udelay_masked (unsigned long usec) +{ + ulong tmo; + ulong endtime; + signed long diff; + + tmo = CONFIG_SYS_HZ_CLOCK / 1000; + tmo *= usec; + tmo /= 1000; + + endtime = get_timer_raw () + tmo; + + do { + ulong now = get_timer_raw (); + diff = endtime - now; + } while (diff >= 0); +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk (void) +{ + ulong tbclk; + + tbclk = CONFIG_SYS_HZ; + return tbclk; +} diff --git a/arch/arm/cpu/arm920t/at91rm9200/usb.c b/arch/arm/cpu/arm920t/at91rm9200/usb.c new file mode 100644 index 0000000000..72355dcf9a --- /dev/null +++ b/arch/arm/cpu/arm920t/at91rm9200/usb.c @@ -0,0 +1,53 @@ +/* + * (C) Copyright 2006 + * DENX Software Engineering + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +#if defined(CONFIG_USB_OHCI_NEW) && defined(CONFIG_SYS_USB_OHCI_CPU_INIT) +# ifdef CONFIG_AT91RM9200 + +#include + +int usb_cpu_init(void) +{ + /* Enable USB host clock. */ + *AT91C_PMC_SCER = AT91C_PMC_UHP; /* 48MHz clock enabled for UHP */ + *AT91C_PMC_PCER = 1 << AT91C_ID_UHP; /* Peripheral Clock Enable Register */ + return 0; +} + +int usb_cpu_stop(void) +{ + /* Initialization failed */ + *AT91C_PMC_PCDR = 1 << AT91C_ID_UHP; /* Peripheral Clock Disable Register */ + *AT91C_PMC_SCDR = AT91C_PMC_UHP; /* 48MHz clock disabled for UHP */ + return 0; +} + +int usb_cpu_init_fail(void) +{ + return usb_cpu_stop(); +} + +# endif /* CONFIG_AT91RM9200 */ +#endif /* defined(CONFIG_USB_OHCI) && defined(CONFIG_SYS_USB_OHCI_CPU_INIT) */ diff --git a/arch/arm/cpu/arm920t/config.mk b/arch/arm/cpu/arm920t/config.mk new file mode 100644 index 0000000000..8f6c1a354c --- /dev/null +++ b/arch/arm/cpu/arm920t/config.mk @@ -0,0 +1,32 @@ +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float + +PLATFORM_CPPFLAGS += -march=armv4 +# ========================================================================= +# +# Supply options according to compiler version +# +# ========================================================================= +PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/arch/arm/cpu/arm920t/cpu.c b/arch/arm/cpu/arm920t/cpu.c new file mode 100644 index 0000000000..be82c87c7d --- /dev/null +++ b/arch/arm/cpu/arm920t/cpu.c @@ -0,0 +1,68 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * CPU specific code + */ + +#include +#include +#include + +#ifdef CONFIG_AT91_LEGACY +#warning Your board is using legacy AT91RM9200 SoC access. Please update! +#endif + +static void cache_flush(void); + +int cleanup_before_linux (void) +{ + /* + * this function is called just before we call linux + * it prepares the processor for linux + * + * we turn off caches etc ... + */ + + disable_interrupts (); + + /* turn off I/D-cache */ + icache_disable(); + dcache_disable(); + /* flush I/D-cache */ + cache_flush(); + + return 0; +} + +/* flush I/D-cache */ +static void cache_flush (void) +{ + unsigned long i = 0; + + asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); +} diff --git a/arch/arm/cpu/arm920t/ep93xx/Makefile b/arch/arm/cpu/arm920t/ep93xx/Makefile new file mode 100644 index 0000000000..01a2f5555a --- /dev/null +++ b/arch/arm/cpu/arm920t/ep93xx/Makefile @@ -0,0 +1,55 @@ +# +# Cirrus Logic EP93xx CPU-specific Makefile +# +# Copyright (C) 2009 Matthias Kaehlcke +# +# Copyright (C) 2004, 2005 +# Cory T. Tusar, Videon Central, Inc., +# +# Copyright (C) 2006 +# Dominic Rath +# +# Based on an original Makefile, which is +# +# (C) Copyright 2000, 2001, 2002 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this project. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 675 Mass Ave, Cambridge, MA 02139, USA. +# +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +COBJS = cpu.o led.o speed.o timer.o +SOBJS = lowlevel_init.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm920t/ep93xx/cpu.c b/arch/arm/cpu/arm920t/ep93xx/cpu.c new file mode 100644 index 0000000000..1abb9c6faa --- /dev/null +++ b/arch/arm/cpu/arm920t/ep93xx/cpu.c @@ -0,0 +1,51 @@ +/* + * Cirrus Logic EP93xx CPU-specific support. + * + * Copyright (C) 2009 Matthias Kaehlcke + * + * Copyright (C) 2004, 2005 + * Cory T. Tusar, Videon Central, Inc., + * + * See file CREDITS for list of people who contributed to this project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include + +/* We reset the CPU by generating a 1-->0 transition on DeviceCfg bit 31. */ +extern void reset_cpu(ulong addr) +{ + struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE; + uint32_t value; + + /* Unlock DeviceCfg and set SWRST */ + writel(0xAA, &syscon->sysswlock); + value = readl(&syscon->devicecfg); + value |= SYSCON_DEVICECFG_SWRST; + writel(value, &syscon->devicecfg); + + /* Unlock DeviceCfg and clear SWRST */ + writel(0xAA, &syscon->sysswlock); + value = readl(&syscon->devicecfg); + value &= ~SYSCON_DEVICECFG_SWRST; + writel(value, &syscon->devicecfg); + + /* Dying... */ + while (1) + ; /* noop */ +} diff --git a/arch/arm/cpu/arm920t/ep93xx/led.c b/arch/arm/cpu/arm920t/ep93xx/led.c new file mode 100644 index 0000000000..7e2c897757 --- /dev/null +++ b/arch/arm/cpu/arm920t/ep93xx/led.c @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2010, 2009 Matthias Kaehlcke + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include + +static uint8_t saved_state[2] = {STATUS_LED_OFF, STATUS_LED_OFF}; +static uint32_t gpio_pin[2] = {1 << STATUS_LED_GREEN, + 1 << STATUS_LED_RED}; + +inline void switch_LED_on(uint8_t led) +{ + register struct gpio_regs *gpio = (struct gpio_regs *)GPIO_BASE; + + writel(readl(&gpio->pedr) | gpio_pin[led], &gpio->pedr); + saved_state[led] = STATUS_LED_ON; +} + +inline void switch_LED_off(uint8_t led) +{ + register struct gpio_regs *gpio = (struct gpio_regs *)GPIO_BASE; + + writel(readl(&gpio->pedr) & ~gpio_pin[led], &gpio->pedr); + saved_state[led] = STATUS_LED_OFF; +} + +void red_LED_on(void) +{ + switch_LED_on(STATUS_LED_RED); +} + +void red_LED_off(void) +{ + switch_LED_off(STATUS_LED_RED); +} + +void green_LED_on(void) +{ + switch_LED_on(STATUS_LED_GREEN); +} + +void green_LED_off(void) +{ + switch_LED_off(STATUS_LED_GREEN); +} + +void __led_init(led_id_t mask, int state) +{ + __led_set(mask, state); +} + +void __led_toggle(led_id_t mask) +{ + if (STATUS_LED_RED == mask) { + if (STATUS_LED_ON == saved_state[STATUS_LED_RED]) + red_LED_off(); + else + red_LED_on(); + } else if (STATUS_LED_GREEN == mask) { + if (STATUS_LED_ON == saved_state[STATUS_LED_GREEN]) + green_LED_off(); + else + green_LED_on(); + } +} + +void __led_set(led_id_t mask, int state) +{ + if (STATUS_LED_RED == mask) { + if (STATUS_LED_ON == state) + red_LED_on(); + else + red_LED_off(); + } else if (STATUS_LED_GREEN == mask) { + if (STATUS_LED_ON == state) + green_LED_on(); + else + green_LED_off(); + } +} diff --git a/arch/arm/cpu/arm920t/ep93xx/lowlevel_init.S b/arch/arm/cpu/arm920t/ep93xx/lowlevel_init.S new file mode 100644 index 0000000000..a20ec894be --- /dev/null +++ b/arch/arm/cpu/arm920t/ep93xx/lowlevel_init.S @@ -0,0 +1,65 @@ +/* + * Low-level initialization for EP93xx + * + * Copyright (C) 2009 Matthias Kaehlcke + * + * Copyright (C) 2006 Dominic Rath + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +.globl lowlevel_init +lowlevel_init: + /* backup return address */ + ldr r1, =SYSCON_SCRATCH0 + str lr, [r1] + + /* Turn on both LEDs */ + bl red_LED_on + bl green_LED_on + + /* Configure flash wait states before we switch to the PLL */ + bl flash_cfg + + /* Set up PLL */ + bl pll_cfg + + /* Turn off the Green LED and leave the Red LED on */ + bl green_LED_off + + /* Setup SDRAM */ + bl sdram_cfg + + /* Turn on Green LED, Turn off the Red LED */ + bl green_LED_on + bl red_LED_off + + /* FIXME: we use async mode for now */ + mrc p15, 0, r0, c1, c0, 0 + orr r0, r0, #0xc0000000 + mcr p15, 0, r0, c1, c0, 0 + + /* restore return address */ + ldr r1, =SYSCON_SCRATCH0 + ldr lr, [r1] + + mov pc, lr diff --git a/arch/arm/cpu/arm920t/ep93xx/speed.c b/arch/arm/cpu/arm920t/ep93xx/speed.c new file mode 100644 index 0000000000..c83a3bb91d --- /dev/null +++ b/arch/arm/cpu/arm920t/ep93xx/speed.c @@ -0,0 +1,110 @@ +/* + * Cirrus Logic EP93xx PLL support. + * + * Copyright (C) 2009 Matthias Kaehlcke + * + * See file CREDITS for list of people who contributed to this project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +/* + * CONFIG_SYS_CLK_FREQ should be defined as the input frequency of the PLL. + * + * get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of + * the specified bus in HZ. + */ + +/* + * return the PLL output frequency + * + * PLL rate = CONFIG_SYS_CLK_FREQ * (X1FBD + 1) * (X2FBD + 1) + * / (X2IPD + 1) / 2^PS + */ +static ulong get_PLLCLK(uint32_t *pllreg) +{ + uint8_t i; + const uint32_t clkset = readl(pllreg); + uint64_t rate = CONFIG_SYS_CLK_FREQ; + rate *= ((clkset >> SYSCON_CLKSET_PLL_X1FBD1_SHIFT) & 0x1f) + 1; + rate *= ((clkset >> SYSCON_CLKSET_PLL_X2FBD2_SHIFT) & 0x3f) + 1; + do_div(rate, (clkset & 0x1f) + 1); /* X2IPD */ + for (i = 0; i < ((clkset >> SYSCON_CLKSET_PLL_PS_SHIFT) & 3); i++) + rate >>= 1; + + return (ulong)rate; +} + +/* return FCLK frequency */ +ulong get_FCLK() +{ + const uint8_t fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 }; + struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE; + + const uint32_t clkset1 = readl(&syscon->clkset1); + const uint8_t fclk_div = + fclk_divisors[(clkset1 >> SYSCON_CLKSET1_FCLK_DIV_SHIFT) & 7]; + const ulong fclk_rate = get_PLLCLK(&syscon->clkset1) / fclk_div; + + return fclk_rate; +} + +/* return HCLK frequency */ +ulong get_HCLK(void) +{ + const uint8_t hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 }; + struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE; + + const uint32_t clkset1 = readl(&syscon->clkset1); + const uint8_t hclk_div = + hclk_divisors[(clkset1 >> SYSCON_CLKSET1_HCLK_DIV_SHIFT) & 7]; + const ulong hclk_rate = get_PLLCLK(&syscon->clkset1) / hclk_div; + + return hclk_rate; +} + +/* return PCLK frequency */ +ulong get_PCLK(void) +{ + const uint8_t pclk_divisors[] = { 1, 2, 4, 8 }; + struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE; + + const uint32_t clkset1 = readl(&syscon->clkset1); + const uint8_t pclk_div = + pclk_divisors[(clkset1 >> SYSCON_CLKSET1_PCLK_DIV_SHIFT) & 3]; + const ulong pclk_rate = get_HCLK() / pclk_div; + + return pclk_rate; +} + +/* return UCLK frequency */ +ulong get_UCLK(void) +{ + struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE; + ulong uclk_rate; + + const uint32_t value = readl(&syscon->pwrcnt); + if (value & SYSCON_PWRCNT_UART_BAUD) + uclk_rate = CONFIG_SYS_CLK_FREQ; + else + uclk_rate = CONFIG_SYS_CLK_FREQ / 2; + + return uclk_rate; +} diff --git a/arch/arm/cpu/arm920t/ep93xx/timer.c b/arch/arm/cpu/arm920t/ep93xx/timer.c new file mode 100644 index 0000000000..4a0ce4da64 --- /dev/null +++ b/arch/arm/cpu/arm920t/ep93xx/timer.c @@ -0,0 +1,143 @@ +/* + * Cirrus Logic EP93xx timer support. + * + * Copyright (C) 2009, 2010 Matthias Kaehlcke + * + * Copyright (C) 2004, 2005 + * Cory T. Tusar, Videon Central, Inc., + * + * Based on the original intr.c Cirrus Logic EP93xx Rev D. interrupt support, + * author unknown. + * + * See file CREDITS for list of people who contributed to this project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include + +#define TIMER_CLKSEL (1 << 3) +#define TIMER_ENABLE (1 << 7) + +#define TIMER_FREQ 508469 /* ticks / second */ +#define TIMER_MAX_VAL 0xFFFFFFFF + +static struct ep93xx_timer +{ + unsigned long long ticks; + unsigned long last_read; +} timer; + +static inline unsigned long long usecs_to_ticks(unsigned long usecs) +{ + unsigned long long ticks = (unsigned long long)usecs * TIMER_FREQ; + do_div(ticks, 1000 * 1000); + + return ticks; +} + +static inline void read_timer(void) +{ + struct timer_regs *timer_regs = (struct timer_regs *)TIMER_BASE; + const unsigned long now = TIMER_MAX_VAL - readl(&timer_regs->timer3.value); + + if (now >= timer.last_read) + timer.ticks += now - timer.last_read; + else + /* an overflow occurred */ + timer.ticks += TIMER_MAX_VAL - timer.last_read + now; + + timer.last_read = now; +} + +/* + * Get the number of ticks (in CONFIG_SYS_HZ resolution) + */ +unsigned long long get_ticks(void) +{ + unsigned long long sys_ticks; + + read_timer(); + + sys_ticks = timer.ticks * CONFIG_SYS_HZ; + do_div(sys_ticks, TIMER_FREQ); + + return sys_ticks; +} + +unsigned long get_timer_masked(void) +{ + return get_ticks(); +} + +unsigned long get_timer(unsigned long base) +{ + return get_timer_masked() - base; +} + +void reset_timer_masked(void) +{ + read_timer(); + timer.ticks = 0; +} + +void reset_timer(void) +{ + reset_timer_masked(); +} + +void __udelay(unsigned long usec) +{ + unsigned long long target; + + read_timer(); + + target = timer.ticks + usecs_to_ticks(usec); + + while (timer.ticks < target) + read_timer(); +} + +int timer_init(void) +{ + struct timer_regs *timer_regs = (struct timer_regs *)TIMER_BASE; + + /* use timer 3 with 508KHz and free running, not enabled now */ + writel(TIMER_CLKSEL, &timer_regs->timer3.control); + + /* set initial timer value */ + writel(TIMER_MAX_VAL, &timer_regs->timer3.load); + + /* Enable the timer */ + writel(TIMER_ENABLE | TIMER_CLKSEL, + &timer_regs->timer3.control); + + reset_timer_masked(); + + return 0; +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +unsigned long get_tbclk(void) +{ + return CONFIG_SYS_HZ; +} diff --git a/arch/arm/cpu/arm920t/ep93xx/u-boot.lds b/arch/arm/cpu/arm920t/ep93xx/u-boot.lds new file mode 100644 index 0000000000..5bfcb02317 --- /dev/null +++ b/arch/arm/cpu/arm920t/ep93xx/u-boot.lds @@ -0,0 +1,59 @@ +/* + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + arch/arm/cpu/arm920t/start.o (.text) + /* the EP93xx expects to find the pattern 'CRUS' at 0x1000 */ + . = 0x1000; + LONG(0x53555243) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss) } + _end = .; +} diff --git a/arch/arm/cpu/arm920t/imx/Makefile b/arch/arm/cpu/arm920t/imx/Makefile new file mode 100644 index 0000000000..28945e22cb --- /dev/null +++ b/arch/arm/cpu/arm920t/imx/Makefile @@ -0,0 +1,47 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +COBJS += generic.o +COBJS += speed.o +COBJS += timer.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm920t/imx/generic.c b/arch/arm/cpu/arm920t/imx/generic.c new file mode 100644 index 0000000000..aa7c8c159d --- /dev/null +++ b/arch/arm/cpu/arm920t/imx/generic.c @@ -0,0 +1,90 @@ +/* + * arch/arm/mach-imx/generic.c + * + * author: Sascha Hauer + * Created: april 20th, 2004 + * Copyright: Synertronixx GmbH + * + * Common code for i.MX machines + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include + +#ifdef CONFIG_IMX + +#include + +void imx_gpio_mode(int gpio_mode) +{ + unsigned int pin = gpio_mode & GPIO_PIN_MASK; + unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> 5; + unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> 10; + unsigned int tmp; + + /* Pullup enable */ + if(gpio_mode & GPIO_PUEN) + PUEN(port) |= (1< + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + +#include +#if defined (CONFIG_IMX) + +#include + +/* ------------------------------------------------------------------------- */ +/* NOTE: This describes the proper use of this file. + * + * CONFIG_SYS_CLK_FREQ should be defined as the input frequency of the PLL. + * SH FIXME: 16780000 in our case + * get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of + * the specified bus in HZ. + */ +/* ------------------------------------------------------------------------- */ + +ulong get_systemPLLCLK(void) +{ + /* FIXME: We assume System_SEL = 0 here */ + u32 spctl0 = SPCTL0; + u32 mfi = (spctl0 >> 10) & 0xf; + u32 mfn = spctl0 & 0x3f; + u32 mfd = (spctl0 >> 16) & 0x3f; + u32 pd = (spctl0 >> 26) & 0xf; + + mfi = mfi<=5 ? 5 : mfi; + + return (2*(CONFIG_SYSPLL_CLK_FREQ>>10)*( (mfi<<10) + (mfn<<10)/(mfd+1)))/(pd+1); +} + +ulong get_mcuPLLCLK(void) +{ + /* FIXME: We assume System_SEL = 0 here */ + u32 mpctl0 = MPCTL0; + u32 mfi = (mpctl0 >> 10) & 0xf; + u32 mfn = mpctl0 & 0x3f; + u32 mfd = (mpctl0 >> 16) & 0x3f; + u32 pd = (mpctl0 >> 26) & 0xf; + + mfi = mfi<=5 ? 5 : mfi; + + return (2*(CONFIG_SYS_CLK_FREQ>>10)*( (mfi<<10) + (mfn<<10)/(mfd+1)))/(pd+1); +} + +ulong get_FCLK(void) +{ + return (( CSCR>>15)&1) ? get_mcuPLLCLK()>>1 : get_mcuPLLCLK(); +} + +/* return HCLK frequency */ +ulong get_HCLK(void) +{ + u32 bclkdiv = (( CSCR >> 10 ) & 0xf) + 1; + printf("bclkdiv: %d\n", bclkdiv); + return get_systemPLLCLK() / bclkdiv; +} + +/* return BCLK frequency */ +ulong get_BCLK(void) +{ + return get_HCLK(); +} + +ulong get_PERCLK1(void) +{ + return get_systemPLLCLK() / (((PCDR) & 0xf)+1); +} + +ulong get_PERCLK2(void) +{ + return get_systemPLLCLK() / (((PCDR>>4) & 0xf)+1); +} + +ulong get_PERCLK3(void) +{ + return get_systemPLLCLK() / (((PCDR>>16) & 0x7f)+1); +} + +#endif /* defined (CONFIG_IMX) */ diff --git a/arch/arm/cpu/arm920t/imx/timer.c b/arch/arm/cpu/arm920t/imx/timer.c new file mode 100644 index 0000000000..b06b518f03 --- /dev/null +++ b/arch/arm/cpu/arm920t/imx/timer.c @@ -0,0 +1,138 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#if defined (CONFIG_IMX) + +#include + +int timer_init (void) +{ + int i; + /* setup GP Timer 1 */ + TCTL1 = TCTL_SWR; + for ( i=0; i<100; i++) TCTL1 = 0; /* We have no udelay by now */ + TPRER1 = get_PERCLK1() / 1000000; /* 1 MHz */ + TCTL1 |= TCTL_FRR | (1<<1); /* Freerun Mode, PERCLK1 input */ + + reset_timer_masked(); + + return (0); +} + +/* + * timer without interrupts + */ + +void reset_timer (void) +{ + reset_timer_masked (); +} + +ulong get_timer (ulong base) +{ + return get_timer_masked() - base; +} + +void set_timer (ulong t) +{ + /* nop */ +} + +void reset_timer_masked (void) +{ + TCTL1 &= ~TCTL_TEN; + TCTL1 |= TCTL_TEN; /* Enable timer */ +} + +ulong get_timer_masked (void) +{ + return TCN1; +} + +void udelay_masked (unsigned long usec) +{ + ulong endtime = get_timer_masked() + usec; + signed long diff; + + do { + ulong now = get_timer_masked (); + diff = endtime - now; + } while (diff >= 0); +} + +void __udelay (unsigned long usec) +{ + udelay_masked(usec); +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk (void) +{ + ulong tbclk; + + tbclk = CONFIG_SYS_HZ; + + return tbclk; +} + +/* + * Reset the cpu by setting up the watchdog timer and let him time out + */ +void reset_cpu (ulong ignored) +{ + /* Disable watchdog and set Time-Out field to 0 */ + WCR = 0x00000000; + + /* Write Service Sequence */ + WSR = 0x00005555; + WSR = 0x0000AAAA; + + /* Enable watchdog */ + WCR = 0x00000001; + + while (1); + /*NOTREACHED*/ +} + +#endif /* defined (CONFIG_IMX) */ diff --git a/arch/arm/cpu/arm920t/interrupts.c b/arch/arm/cpu/arm920t/interrupts.c new file mode 100644 index 0000000000..561083ec73 --- /dev/null +++ b/arch/arm/cpu/arm920t/interrupts.c @@ -0,0 +1,43 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +#if defined (CONFIG_ARCH_INTEGRATOR) +void do_irq (struct pt_regs *pt_regs) +{ + /* ASSUMED to be a timer interrupt */ + /* Just clear it - count handled in */ + /* integratorap.c */ + *(volatile ulong *)(CONFIG_SYS_TIMERBASE + 0x0C) = 0; +} +#endif diff --git a/arch/arm/cpu/arm920t/ks8695/Makefile b/arch/arm/cpu/arm920t/ks8695/Makefile new file mode 100644 index 0000000000..f53fdc2b25 --- /dev/null +++ b/arch/arm/cpu/arm920t/ks8695/Makefile @@ -0,0 +1,47 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +SOBJS = lowlevel_init.o + +COBJS = timer.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm920t/ks8695/lowlevel_init.S b/arch/arm/cpu/arm920t/ks8695/lowlevel_init.S new file mode 100644 index 0000000000..e9f1227dd6 --- /dev/null +++ b/arch/arm/cpu/arm920t/ks8695/lowlevel_init.S @@ -0,0 +1,205 @@ +/* + * lowlevel_init.S - basic hardware initialization for the KS8695 CPU + * + * Copyright (c) 2004-2005, Greg Ungerer + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + +/* + ************************************************************************* + * + * Handy dandy macros + * + ************************************************************************* + */ + +/* Delay a bit */ +.macro DELAY_FOR cycles, reg0 + ldr \reg0, =\cycles + subs \reg0, \reg0, #1 + subne pc, pc, #0xc +.endm + +/* + ************************************************************************* + * + * Some local storage. + * + ************************************************************************* + */ + +/* Should we boot with an interactive console or not */ +.globl serial_console + +/* + ************************************************************************* + * + * Raw hardware initialization code. The important thing is to get + * SDRAM setup and running. We do some other basic things here too, + * like getting the PLL set for high speed, and init the LEDs. + * + ************************************************************************* + */ + +.globl lowlevel_init +lowlevel_init: + +#if DEBUG + /* + * enable UART for early debug trace + */ + ldr r1, =(KS8695_IO_BASE+KS8695_UART_DIVISOR) + mov r2, #0xd9 + str r2, [r1] /* 115200 baud */ + ldr r1, =(KS8695_IO_BASE+KS8695_UART_LINE_CTRL) + mov r2, #0x03 + str r2, [r1] /* 8 data bits, no parity, 1 stop */ + ldr r1, =(KS8695_IO_BASE+KS8695_UART_TX_HOLDING) + mov r2, #0x41 + str r2, [r1] /* write 'A' */ +#endif +#if DEBUG + ldr r1, =(KS8695_IO_BASE+KS8695_UART_TX_HOLDING) + mov r2, #0x42 + str r2, [r1] +#endif + + /* + * remap the memory and flash regions. we want to end up with + * ram from address 0, and flash at 32MB. + */ + ldr r1, =(KS8695_IO_BASE+KS8695_MEM_CTRL0) + ldr r2, =0xbfc00040 + str r2, [r1] /* large flash map */ + ldr pc, =(highflash+0x02000000-0x00f00000) /* jump to high flash address */ +highflash: + ldr r2, =0x8fe00040 + str r2, [r1] /* remap flash range */ + + /* + * remap the second select region to the 4MB immediately after + * the first region. This way if you have a larger flash (say 8Mb) + * then you can have it all mapped nicely. Has no effect if you + * only have a 4Mb or smaller flash. + */ + ldr r1, =(KS8695_IO_BASE+KS8695_MEM_CTRL1) + ldr r2, =0x9fe40040 + str r2, [r1] /* remap flash2 region, contiguous */ + ldr r1, =(KS8695_IO_BASE+KS8695_MEM_GENERAL) + ldr r2, =0x30000005 + str r2, [r1] /* enable both flash selects */ + +#ifdef CONFIG_CM41xx + /* + * map the second flash chip, using the external IO lines. + */ + ldr r1, =(KS8695_IO_BASE+KS8695_IO_CTRL0) + ldr r2, =0xafe80b6d + str r2, [r1] /* remap io0 region, contiguous */ + ldr r1, =(KS8695_IO_BASE+KS8695_IO_CTRL1) + ldr r2, =0xbfec0b6d + str r2, [r1] /* remap io1 region, contiguous */ + ldr r1, =(KS8695_IO_BASE+KS8695_MEM_GENERAL) + ldr r2, =0x30050005 + str r2, [r1] /* enable second flash */ +#endif + + /* + * before relocating, we have to setup RAM timing + */ + ldr r1, =(KS8695_IO_BASE+KS8695_SDRAM_CTRL0) +#if (PHYS_SDRAM_1_SIZE == 0x02000000) + ldr r2, =0x7fc0000e /* 32MB */ +#else + ldr r2, =0x3fc0000e /* 16MB */ +#endif + str r2, [r1] /* configure sdram bank0 setup */ + ldr r1, =(KS8695_IO_BASE+KS8695_SDRAM_CTRL1) + mov r2, #0 + str r2, [r1] /* configure sdram bank1 setup */ + + ldr r1, =(KS8695_IO_BASE+KS8695_SDRAM_GENERAL) + ldr r2, =0x0000000a + str r2, [r1] /* set RAS/CAS timing */ + + ldr r1, =(KS8695_IO_BASE+KS8695_SDRAM_BUFFER) + ldr r2, =0x00030000 + str r2, [r1] /* send NOP command */ + DELAY_FOR 0x100, r0 + ldr r2, =0x00010000 + str r2, [r1] /* send PRECHARGE-ALL */ + DELAY_FOR 0x100, r0 + + ldr r1, =(KS8695_IO_BASE+KS8695_SDRAM_REFRESH) + ldr r2, =0x00000020 + str r2, [r1] /* set for fast refresh */ + DELAY_FOR 0x100, r0 + ldr r2, =0x00000190 + str r2, [r1] /* set normal refresh timing */ + + ldr r1, =(KS8695_IO_BASE+KS8695_SDRAM_BUFFER) + ldr r2, =0x00020033 + str r2, [r1] /* send mode command */ + DELAY_FOR 0x100, r0 + ldr r2, =0x01f00000 + str r2, [r1] /* enable sdram fifos */ + + /* + * set pll to top speed + */ + ldr r1, =(KS8695_IO_BASE+KS8695_SYSTEN_BUS_CLOCK) + mov r2, #0 + str r2, [r1] /* set pll clock to 166MHz */ + + ldr r1, =(KS8695_IO_BASE+KS8695_SWITCH_CTRL0) + ldr r2, [r1] /* Get switch ctrl0 register */ + and r2, r2, #0x0fc00000 /* Mask out LED control bits */ + orr r2, r2, #0x01800000 /* Set Link/activity/speed actions */ + str r2, [r1] + +#ifdef CONFIG_CM4008 + ldr r1, =(KS8695_IO_BASE+KS8695_GPIO_MODE) + ldr r2, =0x0000fe30 + str r2, [r1] /* enable LED's as outputs */ + ldr r1, =(KS8695_IO_BASE+KS8695_GPIO_DATA) + ldr r2, =0x0000fe20 + str r2, [r1] /* turn on power LED */ +#endif +#if defined(CONFIG_CM4008) || defined(CONFIG_CM41xx) + ldr r2, [r1] /* get current GPIO input data */ + tst r2, #0x8 /* check if "erase" depressed */ + beq nobutton + mov r2, #0 /* be quiet on boot, no console */ + ldr r1, =serial_console + str r2, [r1] +nobutton: +#endif + + add lr, lr, #0x02000000 /* flash is now mapped high */ + add ip, ip, #0x02000000 /* this is a hack */ + mov pc, lr /* all done, return */ + +#endif /* CONFIG_SKIP_LOWLEVEL_INIT */ diff --git a/arch/arm/cpu/arm920t/ks8695/timer.c b/arch/arm/cpu/arm920t/ks8695/timer.c new file mode 100644 index 0000000000..886e370596 --- /dev/null +++ b/arch/arm/cpu/arm920t/ks8695/timer.c @@ -0,0 +1,108 @@ +/* + * (C) Copyright 2004-2005, Greg Ungerer + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +/* + * Handy KS8695 register access functions. + */ +#define ks8695_read(a) *((volatile ulong *) (KS8695_IO_BASE + (a))) +#define ks8695_write(a,v) *((volatile ulong *) (KS8695_IO_BASE + (a))) = (v) + +ulong timer_ticks; + +int timer_init (void) +{ + reset_timer(); + + return 0; +} + +/* + * Initial timer set constants. Nothing complicated, just set for a 1ms + * tick. + */ +#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_1) +#define TIMER_COUNT (TIMER_INTERVAL / 2) +#define TIMER_PULSE TIMER_COUNT + +void reset_timer_masked(void) +{ + /* Set the hadware timer for 1ms */ + ks8695_write(KS8695_TIMER1, TIMER_COUNT); + ks8695_write(KS8695_TIMER1_PCOUNT, TIMER_PULSE); + ks8695_write(KS8695_TIMER_CTRL, 0x2); + timer_ticks = 0; +} + +void reset_timer(void) +{ + reset_timer_masked(); +} + +ulong get_timer_masked(void) +{ + /* Check for timer wrap */ + if (ks8695_read(KS8695_INT_STATUS) & KS8695_INTMASK_TIMERINT1) { + /* Clear interrupt condition */ + ks8695_write(KS8695_INT_STATUS, KS8695_INTMASK_TIMERINT1); + timer_ticks++; + } + return timer_ticks; +} + +ulong get_timer(ulong base) +{ + return (get_timer_masked() - base); +} + +void set_timer(ulong t) +{ + timer_ticks = t; +} + +void __udelay(ulong usec) +{ + ulong start = get_timer_masked(); + ulong end; + + /* Only 1ms resolution :-( */ + end = usec / 1000; + while (get_timer(start) < end) + ; +} + +void reset_cpu (ulong ignored) +{ + ulong tc; + + /* Set timer0 to watchdog, and let it timeout */ + tc = ks8695_read(KS8695_TIMER_CTRL) & 0x2; + ks8695_write(KS8695_TIMER_CTRL, tc); + ks8695_write(KS8695_TIMER0, ((10 << 8) | 0xff)); + ks8695_write(KS8695_TIMER_CTRL, (tc | 0x1)); + + /* Should only wait here till watchdog resets */ + for (;;) + ; +} diff --git a/arch/arm/cpu/arm920t/s3c24x0/Makefile b/arch/arm/cpu/arm920t/s3c24x0/Makefile new file mode 100644 index 0000000000..7e8d6ed5f2 --- /dev/null +++ b/arch/arm/cpu/arm920t/s3c24x0/Makefile @@ -0,0 +1,50 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +COBJS-$(CONFIG_USE_IRQ) += interrupts.o +COBJS-y += speed.o +COBJS-y += timer.o +COBJS-y += usb.o +COBJS-y += usb_ohci.o + + +SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm920t/s3c24x0/interrupts.c b/arch/arm/cpu/arm920t/s3c24x0/interrupts.c new file mode 100644 index 0000000000..879fda66a9 --- /dev/null +++ b/arch/arm/cpu/arm920t/s3c24x0/interrupts.c @@ -0,0 +1,42 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +#include +#include + +void do_irq (struct pt_regs *pt_regs) +{ + struct s3c24x0_interrupt *irq = s3c24x0_get_base_interrupt(); + u_int32_t intpnd = readl(&irq->INTPND); + +} diff --git a/arch/arm/cpu/arm920t/s3c24x0/speed.c b/arch/arm/cpu/arm920t/s3c24x0/speed.c new file mode 100644 index 0000000000..b13283a798 --- /dev/null +++ b/arch/arm/cpu/arm920t/s3c24x0/speed.c @@ -0,0 +1,98 @@ +/* + * (C) Copyright 2001-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2002 + * David Mueller, ELSOFT AG, d.mueller@elsoft.ch + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* This code should work for both the S3C2400 and the S3C2410 + * as they seem to have the same PLL and clock machinery inside. + * The different address mapping is handled by the s3c24xx.h files below. + */ + +#include +#ifdef CONFIG_S3C24X0 + +#include +#include + +#define MPLL 0 +#define UPLL 1 + +/* ------------------------------------------------------------------------- */ +/* NOTE: This describes the proper use of this file. + * + * CONFIG_SYS_CLK_FREQ should be defined as the input frequency of the PLL. + * + * get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of + * the specified bus in HZ. + */ +/* ------------------------------------------------------------------------- */ + +static ulong get_PLLCLK(int pllreg) +{ + struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power(); + ulong r, m, p, s; + + if (pllreg == MPLL) + r = readl(&clk_power->MPLLCON); + else if (pllreg == UPLL) + r = readl(&clk_power->UPLLCON); + else + hang(); + + m = ((r & 0xFF000) >> 12) + 8; + p = ((r & 0x003F0) >> 4) + 2; + s = r & 0x3; + + return (CONFIG_SYS_CLK_FREQ * m) / (p << s); +} + +/* return FCLK frequency */ +ulong get_FCLK(void) +{ + return get_PLLCLK(MPLL); +} + +/* return HCLK frequency */ +ulong get_HCLK(void) +{ + struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power(); + + return (readl(&clk_power->CLKDIVN) & 2) ? get_FCLK() / 2 : get_FCLK(); +} + +/* return PCLK frequency */ +ulong get_PCLK(void) +{ + struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power(); + + return (readl(&clk_power->CLKDIVN) & 1) ? get_HCLK() / 2 : get_HCLK(); +} + +/* return UCLK frequency */ +ulong get_UCLK(void) +{ + return get_PLLCLK(UPLL); +} + +#endif /* CONFIG_S3C24X0 */ diff --git a/arch/arm/cpu/arm920t/s3c24x0/timer.c b/arch/arm/cpu/arm920t/s3c24x0/timer.c new file mode 100644 index 0000000000..7d47354381 --- /dev/null +++ b/arch/arm/cpu/arm920t/s3c24x0/timer.c @@ -0,0 +1,223 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#ifdef CONFIG_S3C24X0 + +#include +#include + +int timer_load_val = 0; +static ulong timer_clk; + +/* macro to read the 16 bit timer */ +static inline ulong READ_TIMER(void) +{ + struct s3c24x0_timers *timers = s3c24x0_get_base_timers(); + + return readl(&timers->TCNTO4) & 0xffff; +} + +static ulong timestamp; +static ulong lastdec; + +int timer_init(void) +{ + struct s3c24x0_timers *timers = s3c24x0_get_base_timers(); + ulong tmr; + + /* use PWM Timer 4 because it has no output */ + /* prescaler for Timer 4 is 16 */ + writel(0x0f00, &timers->TCFG0); + if (timer_load_val == 0) { + /* + * for 10 ms clock period @ PCLK with 4 bit divider = 1/2 + * (default) and prescaler = 16. Should be 10390 + * @33.25MHz and 15625 @ 50 MHz + */ + timer_load_val = get_PCLK() / (2 * 16 * 100); + timer_clk = get_PCLK() / (2 * 16); + } + /* load value for 10 ms timeout */ + lastdec = timer_load_val; + writel(timer_load_val, &timers->TCNTB4); + /* auto load, manual update of Timer 4 */ + tmr = (readl(&timers->TCON) & ~0x0700000) | 0x0600000; + writel(tmr, &timers->TCON); + /* auto load, start Timer 4 */ + tmr = (tmr & ~0x0700000) | 0x0500000; + writel(tmr, &timers->TCON); + timestamp = 0; + + return (0); +} + +/* + * timer without interrupts + */ + +void reset_timer(void) +{ + reset_timer_masked(); +} + +ulong get_timer(ulong base) +{ + return get_timer_masked() - base; +} + +void set_timer(ulong t) +{ + timestamp = t; +} + +void __udelay (unsigned long usec) +{ + ulong tmo; + ulong start = get_ticks(); + + tmo = usec / 1000; + tmo *= (timer_load_val * 100); + tmo /= 1000; + + while ((ulong) (get_ticks() - start) < tmo) + /*NOP*/; +} + +void reset_timer_masked(void) +{ + /* reset time */ + lastdec = READ_TIMER(); + timestamp = 0; +} + +ulong get_timer_masked(void) +{ + ulong tmr = get_ticks(); + + return tmr / (timer_clk / CONFIG_SYS_HZ); +} + +void udelay_masked(unsigned long usec) +{ + ulong tmo; + ulong endtime; + signed long diff; + + if (usec >= 1000) { + tmo = usec / 1000; + tmo *= (timer_load_val * 100); + tmo /= 1000; + } else { + tmo = usec * (timer_load_val * 100); + tmo /= (1000 * 1000); + } + + endtime = get_ticks() + tmo; + + do { + ulong now = get_ticks(); + diff = endtime - now; + } while (diff >= 0); +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + ulong now = READ_TIMER(); + + if (lastdec >= now) { + /* normal mode */ + timestamp += lastdec - now; + } else { + /* we have an overflow ... */ + timestamp += lastdec + timer_load_val - now; + } + lastdec = now; + + return timestamp; +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + ulong tbclk; + +#if defined(CONFIG_SMDK2400) || defined(CONFIG_TRAB) + tbclk = timer_load_val * 100; +#elif defined(CONFIG_SBC2410X) || \ + defined(CONFIG_SMDK2410) || \ + defined(CONFIG_VCMA9) + tbclk = CONFIG_SYS_HZ; +#else +# error "tbclk not configured" +#endif + + return tbclk; +} + +/* + * reset the cpu by setting up the watchdog timer and let him time out + */ +void reset_cpu(ulong ignored) +{ + struct s3c24x0_watchdog *watchdog; + +#ifdef CONFIG_TRAB + extern void disable_vfd(void); + + disable_vfd(); +#endif + + watchdog = s3c24x0_get_base_watchdog(); + + /* Disable watchdog */ + writel(0x0000, &watchdog->WTCON); + + /* Initialize watchdog timer count register */ + writel(0x0001, &watchdog->WTCNT); + + /* Enable watchdog timer; assert reset at timer timeout */ + writel(0x0021, &watchdog->WTCON); + + while (1) + /* loop forever and wait for reset to happen */; + + /*NOTREACHED*/ +} + +#endif /* CONFIG_S3C24X0 */ diff --git a/arch/arm/cpu/arm920t/s3c24x0/usb.c b/arch/arm/cpu/arm920t/s3c24x0/usb.c new file mode 100644 index 0000000000..e468ed08fc --- /dev/null +++ b/arch/arm/cpu/arm920t/s3c24x0/usb.c @@ -0,0 +1,71 @@ +/* + * (C) Copyright 2006 + * DENX Software Engineering + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +#if defined(CONFIG_USB_OHCI_NEW) && \ + defined(CONFIG_SYS_USB_OHCI_CPU_INIT) && \ + defined(CONFIG_S3C24X0) + +#include +#include + +int usb_cpu_init(void) +{ + struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power(); + struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio(); + + /* + * Set the 48 MHz UPLL clocking. Values are taken from + * "PLL value selection guide", 6-23, s3c2400_UM.pdf. + */ + writel((40 << 12) + (1 << 4) + 2, &clk_power->UPLLCON); + /* 1 = use pads related USB for USB host */ + writel(readl(&gpio->MISCCR) | 0x8, &gpio->MISCCR); + + /* + * Enable USB host clock. + */ + writel(readl(&clk_power->CLKCON) | (1 << 4), &clk_power->CLKCON); + + return 0; +} + +int usb_cpu_stop(void) +{ + struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power(); + /* may not want to do this */ + writel(readl(&clk_power->CLKCON) & ~(1 << 4), &clk_power->CLKCON); + return 0; +} + +int usb_cpu_init_fail(void) +{ + struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power(); + writel(readl(&clk_power->CLKCON) & ~(1 << 4), &clk_power->CLKCON); + return 0; +} + +#endif /* defined(CONFIG_USB_OHCI_NEW) && \ + defined(CONFIG_SYS_USB_OHCI_CPU_INIT) && \ + defined(CONFIG_S3C24X0) */ diff --git a/arch/arm/cpu/arm920t/s3c24x0/usb_ohci.c b/arch/arm/cpu/arm920t/s3c24x0/usb_ohci.c new file mode 100644 index 0000000000..5aa8d64a55 --- /dev/null +++ b/arch/arm/cpu/arm920t/s3c24x0/usb_ohci.c @@ -0,0 +1,1755 @@ +/* + * URB OHCI HCD (Host Controller Driver) for USB on the S3C2400. + * + * (C) Copyright 2003 + * Gary Jennejohn, DENX Software Engineering + * + * Note: Much of this code has been derived from Linux 2.4 + * (C) Copyright 1999 Roman Weissgaerber + * (C) Copyright 2000-2002 David Brownell + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ +/* + * IMPORTANT NOTES + * 1 - this driver is intended for use with USB Mass Storage Devices + * (BBB) ONLY. There is NO support for Interrupt or Isochronous pipes! + */ + +#include +/* #include no PCI on the S3C24X0 */ + +#if defined(CONFIG_USB_OHCI) && defined(CONFIG_S3C24X0) + +#include +#include +#include +#include +#include "usb_ohci.h" + +#define OHCI_USE_NPS /* force NoPowerSwitching mode */ +#undef OHCI_VERBOSE_DEBUG /* not always helpful */ + + +/* For initializing controller (mask in an HCFS mode too) */ +#define OHCI_CONTROL_INIT \ + (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE + +#define min_t(type, x, y) \ + ({ type __x = (x); type __y = (y); __x < __y ? __x : __y; }) + +#undef DEBUG +#ifdef DEBUG +#define dbg(format, arg...) printf("DEBUG: " format "\n", ## arg) +#else +#define dbg(format, arg...) do {} while(0) +#endif /* DEBUG */ +#define err(format, arg...) printf("ERROR: " format "\n", ## arg) +#undef SHOW_INFO +#ifdef SHOW_INFO +#define info(format, arg...) printf("INFO: " format "\n", ## arg) +#else +#define info(format, arg...) do {} while(0) +#endif + +#define m16_swap(x) swap_16(x) +#define m32_swap(x) swap_32(x) + +/* global struct ohci */ +static struct ohci gohci; +/* this must be aligned to a 256 byte boundary */ +struct ohci_hcca ghcca[1]; +/* a pointer to the aligned storage */ +struct ohci_hcca *phcca; +/* this allocates EDs for all possible endpoints */ +struct ohci_device ohci_dev; +/* urb_priv */ +struct urb_priv urb_priv; +/* RHSC flag */ +int got_rhsc; +/* device which was disconnected */ +struct usb_device *devgone; +/* flag guarding URB transation */ +int urb_finished = 0; + +/*-------------------------------------------------------------------------*/ + +/* AMD-756 (D2 rev) reports corrupt register contents in some cases. + * The erratum (#4) description is incorrect. AMD's workaround waits + * till some bits (mostly reserved) are clear; ok for all revs. + */ +#define OHCI_QUIRK_AMD756 0xabcd +#define read_roothub(hc, register, mask) ({ \ + u32 temp = readl (&hc->regs->roothub.register); \ + if (hc->flags & OHCI_QUIRK_AMD756) \ + while (temp & mask) \ + temp = readl (&hc->regs->roothub.register); \ + temp; }) + +static u32 roothub_a(struct ohci *hc) +{ + return read_roothub(hc, a, 0xfc0fe000); +} +static inline u32 roothub_b(struct ohci *hc) +{ + return readl(&hc->regs->roothub.b); +} +static inline u32 roothub_status(struct ohci *hc) +{ + return readl(&hc->regs->roothub.status); +} +static u32 roothub_portstatus(struct ohci *hc, int i) +{ + return read_roothub(hc, portstatus[i], 0xffe0fce0); +} + +/* forward declaration */ +static int hc_interrupt(void); +static void td_submit_job(struct usb_device *dev, unsigned long pipe, + void *buffer, int transfer_len, + struct devrequest *setup, struct urb_priv *urb, + int interval); + +/*-------------------------------------------------------------------------* + * URB support functions + *-------------------------------------------------------------------------*/ + +/* free HCD-private data associated with this URB */ + +static void urb_free_priv(struct urb_priv *urb) +{ + int i; + int last; + struct td *td; + + last = urb->length - 1; + if (last >= 0) { + for (i = 0; i <= last; i++) { + td = urb->td[i]; + if (td) { + td->usb_dev = NULL; + urb->td[i] = NULL; + } + } + } +} + +/*-------------------------------------------------------------------------*/ + +#ifdef DEBUG +static int sohci_get_current_frame_number(struct usb_device *dev); + +/* debug| print the main components of an URB + * small: 0) header + data packets 1) just header */ + +static void pkt_print(struct usb_device *dev, unsigned long pipe, void *buffer, + int transfer_len, struct devrequest *setup, char *str, + int small) +{ + struct urb_priv *purb = &urb_priv; + + dbg("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,len:%d/%d stat:%#lx", + str, + sohci_get_current_frame_number(dev), + usb_pipedevice(pipe), + usb_pipeendpoint(pipe), + usb_pipeout(pipe) ? 'O' : 'I', + usb_pipetype(pipe) < 2 ? + (usb_pipeint(pipe) ? "INTR" : "ISOC") : + (usb_pipecontrol(pipe) ? "CTRL" : "BULK"), + purb->actual_length, transfer_len, dev->status); +#ifdef OHCI_VERBOSE_DEBUG + if (!small) { + int i, len; + + if (usb_pipecontrol(pipe)) { + printf(__FILE__ ": cmd(8):"); + for (i = 0; i < 8; i++) + printf(" %02x", ((__u8 *) setup)[i]); + printf("\n"); + } + if (transfer_len > 0 && buffer) { + printf(__FILE__ ": data(%d/%d):", + purb->actual_length, transfer_len); + len = usb_pipeout(pipe) ? + transfer_len : purb->actual_length; + for (i = 0; i < 16 && i < len; i++) + printf(" %02x", ((__u8 *) buffer)[i]); + printf("%s\n", i < len ? "..." : ""); + } + } +#endif +} + +/* just for debugging; prints non-empty branches of the + int ed tree inclusive iso eds*/ +void ep_print_int_eds(struct ohci *ohci, char *str) +{ + int i, j; + __u32 *ed_p; + for (i = 0; i < 32; i++) { + j = 5; + ed_p = &(ohci->hcca->int_table[i]); + if (*ed_p == 0) + continue; + printf(__FILE__ ": %s branch int %2d(%2x):", str, i, i); + while (*ed_p != 0 && j--) { + struct ed *ed = (struct ed *) m32_swap(ed_p); + printf(" ed: %4x;", ed->hwINFO); + ed_p = &ed->hwNextED; + } + printf("\n"); + } +} + +static void ohci_dump_intr_mask(char *label, __u32 mask) +{ + dbg("%s: 0x%08x%s%s%s%s%s%s%s%s%s", + label, + mask, + (mask & OHCI_INTR_MIE) ? " MIE" : "", + (mask & OHCI_INTR_OC) ? " OC" : "", + (mask & OHCI_INTR_RHSC) ? " RHSC" : "", + (mask & OHCI_INTR_FNO) ? " FNO" : "", + (mask & OHCI_INTR_UE) ? " UE" : "", + (mask & OHCI_INTR_RD) ? " RD" : "", + (mask & OHCI_INTR_SF) ? " SF" : "", + (mask & OHCI_INTR_WDH) ? " WDH" : "", + (mask & OHCI_INTR_SO) ? " SO" : ""); +} + +static void maybe_print_eds(char *label, __u32 value) +{ + struct ed *edp = (struct ed *) value; + + if (value) { + dbg("%s %08x", label, value); + dbg("%08x", edp->hwINFO); + dbg("%08x", edp->hwTailP); + dbg("%08x", edp->hwHeadP); + dbg("%08x", edp->hwNextED); + } +} + +static char *hcfs2string(int state) +{ + switch (state) { + case OHCI_USB_RESET: + return "reset"; + case OHCI_USB_RESUME: + return "resume"; + case OHCI_USB_OPER: + return "operational"; + case OHCI_USB_SUSPEND: + return "suspend"; + } + return "?"; +} + +/* dump control and status registers */ +static void ohci_dump_status(struct ohci *controller) +{ + struct ohci_regs *regs = controller->regs; + __u32 temp; + + temp = readl(®s->revision) & 0xff; + if (temp != 0x10) + dbg("spec %d.%d", (temp >> 4), (temp & 0x0f)); + + temp = readl(®s->control); + dbg("control: 0x%08x%s%s%s HCFS=%s%s%s%s%s CBSR=%d", temp, + (temp & OHCI_CTRL_RWE) ? " RWE" : "", + (temp & OHCI_CTRL_RWC) ? " RWC" : "", + (temp & OHCI_CTRL_IR) ? " IR" : "", + hcfs2string(temp & OHCI_CTRL_HCFS), + (temp & OHCI_CTRL_BLE) ? " BLE" : "", + (temp & OHCI_CTRL_CLE) ? " CLE" : "", + (temp & OHCI_CTRL_IE) ? " IE" : "", + (temp & OHCI_CTRL_PLE) ? " PLE" : "", temp & OHCI_CTRL_CBSR); + + temp = readl(®s->cmdstatus); + dbg("cmdstatus: 0x%08x SOC=%d%s%s%s%s", temp, + (temp & OHCI_SOC) >> 16, + (temp & OHCI_OCR) ? " OCR" : "", + (temp & OHCI_BLF) ? " BLF" : "", + (temp & OHCI_CLF) ? " CLF" : "", (temp & OHCI_HCR) ? " HCR" : ""); + + ohci_dump_intr_mask("intrstatus", readl(®s->intrstatus)); + ohci_dump_intr_mask("intrenable", readl(®s->intrenable)); + + maybe_print_eds("ed_periodcurrent", readl(®s->ed_periodcurrent)); + + maybe_print_eds("ed_controlhead", readl(®s->ed_controlhead)); + maybe_print_eds("ed_controlcurrent", readl(®s->ed_controlcurrent)); + + maybe_print_eds("ed_bulkhead", readl(®s->ed_bulkhead)); + maybe_print_eds("ed_bulkcurrent", readl(®s->ed_bulkcurrent)); + + maybe_print_eds("donehead", readl(®s->donehead)); +} + +static void ohci_dump_roothub(struct ohci *controller, int verbose) +{ + __u32 temp, ndp, i; + + temp = roothub_a(controller); + ndp = (temp & RH_A_NDP); + + if (verbose) { + dbg("roothub.a: %08x POTPGT=%d%s%s%s%s%s NDP=%d", temp, + ((temp & RH_A_POTPGT) >> 24) & 0xff, + (temp & RH_A_NOCP) ? " NOCP" : "", + (temp & RH_A_OCPM) ? " OCPM" : "", + (temp & RH_A_DT) ? " DT" : "", + (temp & RH_A_NPS) ? " NPS" : "", + (temp & RH_A_PSM) ? " PSM" : "", ndp); + temp = roothub_b(controller); + dbg("roothub.b: %08x PPCM=%04x DR=%04x", + temp, (temp & RH_B_PPCM) >> 16, (temp & RH_B_DR) + ); + temp = roothub_status(controller); + dbg("roothub.status: %08x%s%s%s%s%s%s", + temp, + (temp & RH_HS_CRWE) ? " CRWE" : "", + (temp & RH_HS_OCIC) ? " OCIC" : "", + (temp & RH_HS_LPSC) ? " LPSC" : "", + (temp & RH_HS_DRWE) ? " DRWE" : "", + (temp & RH_HS_OCI) ? " OCI" : "", + (temp & RH_HS_LPS) ? " LPS" : ""); + } + + for (i = 0; i < ndp; i++) { + temp = roothub_portstatus(controller, i); + dbg("roothub.portstatus [%d] = 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s", + i, + temp, + (temp & RH_PS_PRSC) ? " PRSC" : "", + (temp & RH_PS_OCIC) ? " OCIC" : "", + (temp & RH_PS_PSSC) ? " PSSC" : "", + (temp & RH_PS_PESC) ? " PESC" : "", + (temp & RH_PS_CSC) ? " CSC" : "", + (temp & RH_PS_LSDA) ? " LSDA" : "", + (temp & RH_PS_PPS) ? " PPS" : "", + (temp & RH_PS_PRS) ? " PRS" : "", + (temp & RH_PS_POCI) ? " POCI" : "", + (temp & RH_PS_PSS) ? " PSS" : "", + (temp & RH_PS_PES) ? " PES" : "", + (temp & RH_PS_CCS) ? " CCS" : ""); + } +} + +static void ohci_dump(struct ohci *controller, int verbose) +{ + dbg("OHCI controller usb-%s state", controller->slot_name); + + /* dumps some of the state we know about */ + ohci_dump_status(controller); + if (verbose) + ep_print_int_eds(controller, "hcca"); + dbg("hcca frame #%04x", controller->hcca->frame_no); + ohci_dump_roothub(controller, 1); +} + +#endif /* DEBUG */ + +/*-------------------------------------------------------------------------* + * Interface functions (URB) + *-------------------------------------------------------------------------*/ + +/* get a transfer request */ + +int sohci_submit_job(struct usb_device *dev, unsigned long pipe, void *buffer, + int transfer_len, struct devrequest *setup, int interval) +{ + struct ohci *ohci; + struct ed *ed; + struct urb_priv *purb_priv; + int i, size = 0; + + ohci = &gohci; + + /* when controller's hung, permit only roothub cleanup attempts + * such as powering down ports */ + if (ohci->disabled) { + err("sohci_submit_job: EPIPE"); + return -1; + } + + /* if we have an unfinished URB from previous transaction let's + * fail and scream as quickly as possible so as not to corrupt + * further communication */ + if (!urb_finished) { + err("sohci_submit_job: URB NOT FINISHED"); + return -1; + } + /* we're about to begin a new transaction here + so mark the URB unfinished */ + urb_finished = 0; + + /* every endpoint has a ed, locate and fill it */ + ed = ep_add_ed(dev, pipe); + if (!ed) { + err("sohci_submit_job: ENOMEM"); + return -1; + } + + /* for the private part of the URB we need the number of TDs (size) */ + switch (usb_pipetype(pipe)) { + case PIPE_BULK: + /* one TD for every 4096 Byte */ + size = (transfer_len - 1) / 4096 + 1; + break; + case PIPE_CONTROL: + /* 1 TD for setup, 1 for ACK and 1 for every 4096 B */ + size = (transfer_len == 0) ? 2 : (transfer_len - 1) / 4096 + 3; + break; + } + + if (size >= (N_URB_TD - 1)) { + err("need %d TDs, only have %d", size, N_URB_TD); + return -1; + } + purb_priv = &urb_priv; + purb_priv->pipe = pipe; + + /* fill the private part of the URB */ + purb_priv->length = size; + purb_priv->ed = ed; + purb_priv->actual_length = 0; + + /* allocate the TDs */ + /* note that td[0] was allocated in ep_add_ed */ + for (i = 0; i < size; i++) { + purb_priv->td[i] = td_alloc(dev); + if (!purb_priv->td[i]) { + purb_priv->length = i; + urb_free_priv(purb_priv); + err("sohci_submit_job: ENOMEM"); + return -1; + } + } + + if (ed->state == ED_NEW || (ed->state & ED_DEL)) { + urb_free_priv(purb_priv); + err("sohci_submit_job: EINVAL"); + return -1; + } + + /* link the ed into a chain if is not already */ + if (ed->state != ED_OPER) + ep_link(ohci, ed); + + /* fill the TDs and link it to the ed */ + td_submit_job(dev, pipe, buffer, transfer_len, setup, purb_priv, + interval); + + return 0; +} + +/*-------------------------------------------------------------------------*/ + +#ifdef DEBUG +/* tell us the current USB frame number */ + +static int sohci_get_current_frame_number(struct usb_device *usb_dev) +{ + struct ohci *ohci = &gohci; + + return m16_swap(ohci->hcca->frame_no); +} +#endif + +/*-------------------------------------------------------------------------* + * ED handling functions + *-------------------------------------------------------------------------*/ + +/* link an ed into one of the HC chains */ + +static int ep_link(struct ohci *ohci, struct ed *edi) +{ + struct ed *ed = edi; + + ed->state = ED_OPER; + + switch (ed->type) { + case PIPE_CONTROL: + ed->hwNextED = 0; + if (ohci->ed_controltail == NULL) { + writel((u32)ed, &ohci->regs->ed_controlhead); + } else { + ohci->ed_controltail->hwNextED = (__u32) m32_swap(ed); + } + ed->ed_prev = ohci->ed_controltail; + if (!ohci->ed_controltail && !ohci->ed_rm_list[0] && + !ohci->ed_rm_list[1] && !ohci->sleeping) { + ohci->hc_control |= OHCI_CTRL_CLE; + writel(ohci->hc_control, &ohci->regs->control); + } + ohci->ed_controltail = edi; + break; + + case PIPE_BULK: + ed->hwNextED = 0; + if (ohci->ed_bulktail == NULL) { + writel((u32)ed, &ohci->regs->ed_bulkhead); + } else { + ohci->ed_bulktail->hwNextED = (__u32) m32_swap(ed); + } + ed->ed_prev = ohci->ed_bulktail; + if (!ohci->ed_bulktail && !ohci->ed_rm_list[0] && + !ohci->ed_rm_list[1] && !ohci->sleeping) { + ohci->hc_control |= OHCI_CTRL_BLE; + writel(ohci->hc_control, &ohci->regs->control); + } + ohci->ed_bulktail = edi; + break; + } + return 0; +} + +/*-------------------------------------------------------------------------*/ + +/* unlink an ed from one of the HC chains. + * just the link to the ed is unlinked. + * the link from the ed still points to another operational ed or 0 + * so the HC can eventually finish the processing of the unlinked ed */ + +static int ep_unlink(struct ohci *ohci, struct ed *ed) +{ + struct ed *next; + ed->hwINFO |= m32_swap(OHCI_ED_SKIP); + + switch (ed->type) { + case PIPE_CONTROL: + if (ed->ed_prev == NULL) { + if (!ed->hwNextED) { + ohci->hc_control &= ~OHCI_CTRL_CLE; + writel(ohci->hc_control, &ohci->regs->control); + } + writel(m32_swap(*((__u32 *) &ed->hwNextED)), + &ohci->regs->ed_controlhead); + } else { + ed->ed_prev->hwNextED = ed->hwNextED; + } + if (ohci->ed_controltail == ed) { + ohci->ed_controltail = ed->ed_prev; + } else { + next = (struct ed *)m32_swap(*((__u32 *)&ed->hwNextED)); + next->ed_prev = ed->ed_prev; + } + break; + + case PIPE_BULK: + if (ed->ed_prev == NULL) { + if (!ed->hwNextED) { + ohci->hc_control &= ~OHCI_CTRL_BLE; + writel(ohci->hc_control, &ohci->regs->control); + } + writel(m32_swap(*((__u32 *) &ed->hwNextED)), + &ohci->regs->ed_bulkhead); + } else { + ed->ed_prev->hwNextED = ed->hwNextED; + } + if (ohci->ed_bulktail == ed) { + ohci->ed_bulktail = ed->ed_prev; + } else { + next = (struct ed *)m32_swap(*((__u32 *)&ed->hwNextED)); + next->ed_prev = ed->ed_prev; + } + break; + } + ed->state = ED_UNLINK; + return 0; +} + +/*-------------------------------------------------------------------------*/ + +/* add/reinit an endpoint; this should be done once at the usb_set_configuration + * command, but the USB stack is a little bit stateless so we do it at every + * transaction. If the state of the ed is ED_NEW then a dummy td is added and + * the state is changed to ED_UNLINK. In all other cases the state is left + * unchanged. The ed info fields are setted anyway even though most of them + * should not change */ + +static struct ed *ep_add_ed(struct usb_device *usb_dev, unsigned long pipe) +{ + struct td *td; + struct ed *ed_ret; + struct ed *ed; + + ed = ed_ret = &ohci_dev.ed[(usb_pipeendpoint(pipe) << 1) | + (usb_pipecontrol(pipe) ? 0 : + usb_pipeout(pipe))]; + + if ((ed->state & ED_DEL) || (ed->state & ED_URB_DEL)) { + err("ep_add_ed: pending delete"); + /* pending delete request */ + return NULL; + } + + if (ed->state == ED_NEW) { + ed->hwINFO = m32_swap(OHCI_ED_SKIP); /* skip ed */ + /* dummy td; end of td list for ed */ + td = td_alloc(usb_dev); + ed->hwTailP = (__u32) m32_swap(td); + ed->hwHeadP = ed->hwTailP; + ed->state = ED_UNLINK; + ed->type = usb_pipetype(pipe); + ohci_dev.ed_cnt++; + } + + ed->hwINFO = m32_swap(usb_pipedevice(pipe) + | usb_pipeendpoint(pipe) << 7 + | (usb_pipeisoc(pipe) ? 0x8000 : 0) + | (usb_pipecontrol(pipe) ? 0 : + (usb_pipeout(pipe) ? 0x800 : 0x1000)) + | usb_pipeslow(pipe) << 13 | + usb_maxpacket(usb_dev, pipe) << 16); + + return ed_ret; +} + +/*-------------------------------------------------------------------------* + * TD handling functions + *-------------------------------------------------------------------------*/ + +/* enqueue next TD for this URB (OHCI spec 5.2.8.2) */ + +static void td_fill(struct ohci *ohci, unsigned int info, void *data, int len, + struct usb_device *dev, int index, + struct urb_priv *urb_priv) +{ + struct td *td, *td_pt; +#ifdef OHCI_FILL_TRACE + int i; +#endif + + if (index > urb_priv->length) { + err("index > length"); + return; + } + /* use this td as the next dummy */ + td_pt = urb_priv->td[index]; + td_pt->hwNextTD = 0; + + /* fill the old dummy TD */ + td = urb_priv->td[index] = + (struct td *) (m32_swap(urb_priv->ed->hwTailP) & ~0xf); + + td->ed = urb_priv->ed; + td->next_dl_td = NULL; + td->index = index; + td->data = (__u32) data; +#ifdef OHCI_FILL_TRACE + if (usb_pipebulk(urb_priv->pipe) && usb_pipeout(urb_priv->pipe)) { + for (i = 0; i < len; i++) + printf("td->data[%d] %#2x ", i, + ((unsigned char *)td->data)[i]); + printf("\n"); + } +#endif + if (!len) + data = 0; + + td->hwINFO = (__u32) m32_swap(info); + td->hwCBP = (__u32) m32_swap(data); + if (data) + td->hwBE = (__u32) m32_swap(data + len - 1); + else + td->hwBE = 0; + td->hwNextTD = (__u32) m32_swap(td_pt); + + /* append to queue */ + td->ed->hwTailP = td->hwNextTD; +} + +/*-------------------------------------------------------------------------*/ + +/* prepare all TDs of a transfer */ + +static void td_submit_job(struct usb_device *dev, unsigned long pipe, + void *buffer, int transfer_len, + struct devrequest *setup, struct urb_priv *urb, + int interval) +{ + struct ohci *ohci = &gohci; + int data_len = transfer_len; + void *data; + int cnt = 0; + __u32 info = 0; + unsigned int toggle = 0; + + /* OHCI handles the DATA-toggles itself, we just + use the USB-toggle bits for reseting */ + if (usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe))) { + toggle = TD_T_TOGGLE; + } else { + toggle = TD_T_DATA0; + usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), + 1); + } + urb->td_cnt = 0; + if (data_len) + data = buffer; + else + data = 0; + + switch (usb_pipetype(pipe)) { + case PIPE_BULK: + info = usb_pipeout(pipe) ? TD_CC | TD_DP_OUT : TD_CC | TD_DP_IN; + while (data_len > 4096) { + td_fill(ohci, info | (cnt ? TD_T_TOGGLE : toggle), data, + 4096, dev, cnt, urb); + data += 4096; + data_len -= 4096; + cnt++; + } + info = usb_pipeout(pipe) ? + TD_CC | TD_DP_OUT : + TD_CC | TD_R | TD_DP_IN; + td_fill(ohci, info | (cnt ? TD_T_TOGGLE : toggle), data, + data_len, dev, cnt, urb); + cnt++; + + if (!ohci->sleeping) + /* start bulk list */ + writel(OHCI_BLF, &ohci->regs->cmdstatus); + break; + + case PIPE_CONTROL: + info = TD_CC | TD_DP_SETUP | TD_T_DATA0; + td_fill(ohci, info, setup, 8, dev, cnt++, urb); + if (data_len > 0) { + info = usb_pipeout(pipe) ? + TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1 : + TD_CC | TD_R | TD_DP_IN | TD_T_DATA1; + /* NOTE: mishandles transfers >8K, some >4K */ + td_fill(ohci, info, data, data_len, dev, cnt++, urb); + } + info = usb_pipeout(pipe) ? + TD_CC | TD_DP_IN | TD_T_DATA1 : + TD_CC | TD_DP_OUT | TD_T_DATA1; + td_fill(ohci, info, data, 0, dev, cnt++, urb); + if (!ohci->sleeping) + /* start Control list */ + writel(OHCI_CLF, &ohci->regs->cmdstatus); + break; + } + if (urb->length != cnt) + dbg("TD LENGTH %d != CNT %d", urb->length, cnt); +} + +/*-------------------------------------------------------------------------* + * Done List handling functions + *-------------------------------------------------------------------------*/ + + +/* calculate the transfer length and update the urb */ + +static void dl_transfer_length(struct td *td) +{ + __u32 tdINFO, tdBE, tdCBP; + struct urb_priv *lurb_priv = &urb_priv; + + tdINFO = m32_swap(td->hwINFO); + tdBE = m32_swap(td->hwBE); + tdCBP = m32_swap(td->hwCBP); + + if (!(usb_pipecontrol(lurb_priv->pipe) && + ((td->index == 0) || (td->index == lurb_priv->length - 1)))) { + if (tdBE != 0) { + if (td->hwCBP == 0) + lurb_priv->actual_length += tdBE - td->data + 1; + else + lurb_priv->actual_length += tdCBP - td->data; + } + } +} + +/*-------------------------------------------------------------------------*/ + +/* replies to the request have to be on a FIFO basis so + * we reverse the reversed done-list */ + +static struct td *dl_reverse_done_list(struct ohci *ohci) +{ + __u32 td_list_hc; + __u32 tmp; + struct td *td_rev = NULL; + struct td *td_list = NULL; + struct urb_priv *lurb_priv = NULL; + + td_list_hc = m32_swap(ohci->hcca->done_head) & 0xfffffff0; + ohci->hcca->done_head = 0; + + while (td_list_hc) { + td_list = (struct td *) td_list_hc; + + if (TD_CC_GET(m32_swap(td_list->hwINFO))) { + lurb_priv = &urb_priv; + dbg(" USB-error/status: %x : %p", + TD_CC_GET(m32_swap(td_list->hwINFO)), td_list); + if (td_list->ed->hwHeadP & m32_swap(0x1)) { + if (lurb_priv && + ((td_list->index+1) < lurb_priv->length)) { + tmp = lurb_priv->length - 1; + td_list->ed->hwHeadP = + (lurb_priv->td[tmp]->hwNextTD & + m32_swap(0xfffffff0)) | + (td_list->ed->hwHeadP & + m32_swap(0x2)); + lurb_priv->td_cnt += lurb_priv->length - + td_list->index - 1; + } else + td_list->ed->hwHeadP &= + m32_swap(0xfffffff2); + } + } + + td_list->next_dl_td = td_rev; + td_rev = td_list; + td_list_hc = m32_swap(td_list->hwNextTD) & 0xfffffff0; + } + + return td_list; +} + +/*-------------------------------------------------------------------------*/ + +/* td done list */ +static int dl_done_list(struct ohci *ohci, struct td *td_list) +{ + struct td *td_list_next = NULL; + struct ed *ed; + int cc = 0; + int stat = 0; + /* urb_t *urb; */ + struct urb_priv *lurb_priv; + __u32 tdINFO, edHeadP, edTailP; + + while (td_list) { + td_list_next = td_list->next_dl_td; + + lurb_priv = &urb_priv; + tdINFO = m32_swap(td_list->hwINFO); + + ed = td_list->ed; + + dl_transfer_length(td_list); + + /* error code of transfer */ + cc = TD_CC_GET(tdINFO); + if (cc != 0) { + dbg("ConditionCode %#x", cc); + stat = cc_to_error[cc]; + } + + /* see if this done list makes for all TD's of current URB, + * and mark the URB finished if so */ + if (++(lurb_priv->td_cnt) == lurb_priv->length) { + if ((ed->state & (ED_OPER | ED_UNLINK))) + urb_finished = 1; + else + dbg("dl_done_list: strange.., ED state %x, " + "ed->state\n"); + } else + dbg("dl_done_list: processing TD %x, len %x\n", + lurb_priv->td_cnt, lurb_priv->length); + + if (ed->state != ED_NEW) { + edHeadP = m32_swap(ed->hwHeadP) & 0xfffffff0; + edTailP = m32_swap(ed->hwTailP); + + /* unlink eds if they are not busy */ + if ((edHeadP == edTailP) && (ed->state == ED_OPER)) + ep_unlink(ohci, ed); + } + + td_list = td_list_next; + } + return stat; +} + +/*-------------------------------------------------------------------------* + * Virtual Root Hub + *-------------------------------------------------------------------------*/ + +/* Device descriptor */ +static __u8 root_hub_dev_des[] = { + 0x12, /* __u8 bLength; */ + 0x01, /* __u8 bDescriptorType; Device */ + 0x10, /* __u16 bcdUSB; v1.1 */ + 0x01, + 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ + 0x00, /* __u8 bDeviceSubClass; */ + 0x00, /* __u8 bDeviceProtocol; */ + 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */ + 0x00, /* __u16 idVendor; */ + 0x00, + 0x00, /* __u16 idProduct; */ + 0x00, + 0x00, /* __u16 bcdDevice; */ + 0x00, + 0x00, /* __u8 iManufacturer; */ + 0x01, /* __u8 iProduct; */ + 0x00, /* __u8 iSerialNumber; */ + 0x01 /* __u8 bNumConfigurations; */ +}; + +/* Configuration descriptor */ +static __u8 root_hub_config_des[] = { + 0x09, /* __u8 bLength; */ + 0x02, /* __u8 bDescriptorType; Configuration */ + 0x19, /* __u16 wTotalLength; */ + 0x00, + 0x01, /* __u8 bNumInterfaces; */ + 0x01, /* __u8 bConfigurationValue; */ + 0x00, /* __u8 iConfiguration; */ + 0x40, /* __u8 bmAttributes; + Bit 7: Bus-powered, 6: Self-powered, + 5 Remote-wakwup, 4..0: resvd */ + 0x00, /* __u8 MaxPower; */ + + /* interface */ + 0x09, /* __u8 if_bLength; */ + 0x04, /* __u8 if_bDescriptorType; Interface */ + 0x00, /* __u8 if_bInterfaceNumber; */ + 0x00, /* __u8 if_bAlternateSetting; */ + 0x01, /* __u8 if_bNumEndpoints; */ + 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */ + 0x00, /* __u8 if_bInterfaceSubClass; */ + 0x00, /* __u8 if_bInterfaceProtocol; */ + 0x00, /* __u8 if_iInterface; */ + + /* endpoint */ + 0x07, /* __u8 ep_bLength; */ + 0x05, /* __u8 ep_bDescriptorType; Endpoint */ + 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */ + 0x03, /* __u8 ep_bmAttributes; Interrupt */ + 0x02, /* __u16 ep_wMaxPacketSize; ((MAX_ROOT_PORTS + 1) / 8 */ + 0x00, + 0xff /* __u8 ep_bInterval; 255 ms */ +}; + +static unsigned char root_hub_str_index0[] = { + 0x04, /* __u8 bLength; */ + 0x03, /* __u8 bDescriptorType; String-descriptor */ + 0x09, /* __u8 lang ID */ + 0x04, /* __u8 lang ID */ +}; + +static unsigned char root_hub_str_index1[] = { + 28, /* __u8 bLength; */ + 0x03, /* __u8 bDescriptorType; String-descriptor */ + 'O', /* __u8 Unicode */ + 0, /* __u8 Unicode */ + 'H', /* __u8 Unicode */ + 0, /* __u8 Unicode */ + 'C', /* __u8 Unicode */ + 0, /* __u8 Unicode */ + 'I', /* __u8 Unicode */ + 0, /* __u8 Unicode */ + ' ', /* __u8 Unicode */ + 0, /* __u8 Unicode */ + 'R', /* __u8 Unicode */ + 0, /* __u8 Unicode */ + 'o', /* __u8 Unicode */ + 0, /* __u8 Unicode */ + 'o', /* __u8 Unicode */ + 0, /* __u8 Unicode */ + 't', /* __u8 Unicode */ + 0, /* __u8 Unicode */ + ' ', /* __u8 Unicode */ + 0, /* __u8 Unicode */ + 'H', /* __u8 Unicode */ + 0, /* __u8 Unicode */ + 'u', /* __u8 Unicode */ + 0, /* __u8 Unicode */ + 'b', /* __u8 Unicode */ + 0, /* __u8 Unicode */ +}; + +/* Hub class-specific descriptor is constructed dynamically */ + + +/*-------------------------------------------------------------------------*/ + +#define OK(x) len = (x); break +#ifdef DEBUG +#define WR_RH_STAT(x) \ +{ \ + info("WR:status %#8x", (x)); \ + writel((x), &gohci.regs->roothub.status); \ +} +#define WR_RH_PORTSTAT(x) \ +{ \ + info("WR:portstatus[%d] %#8x", wIndex-1, (x)); \ + writel((x), &gohci.regs->roothub.portstatus[wIndex-1]); \ +} +#else +#define WR_RH_STAT(x) \ + writel((x), &gohci.regs->roothub.status) +#define WR_RH_PORTSTAT(x)\ + writel((x), &gohci.regs->roothub.portstatus[wIndex-1]) +#endif +#define RD_RH_STAT roothub_status(&gohci) +#define RD_RH_PORTSTAT roothub_portstatus(&gohci, wIndex-1) + +/* request to virtual root hub */ + +int rh_check_port_status(struct ohci *controller) +{ + __u32 temp, ndp, i; + int res; + + res = -1; + temp = roothub_a(controller); + ndp = (temp & RH_A_NDP); + for (i = 0; i < ndp; i++) { + temp = roothub_portstatus(controller, i); + /* check for a device disconnect */ + if (((temp & (RH_PS_PESC | RH_PS_CSC)) == + (RH_PS_PESC | RH_PS_CSC)) && ((temp & RH_PS_CCS) == 0)) { + res = i; + break; + } + } + return res; +} + +static int ohci_submit_rh_msg(struct usb_device *dev, unsigned long pipe, + void *buffer, int transfer_len, + struct devrequest *cmd) +{ + void *data = buffer; + int leni = transfer_len; + int len = 0; + int stat = 0; + __u32 datab[4]; + __u8 *data_buf = (__u8 *) datab; + __u16 bmRType_bReq; + __u16 wValue; + __u16 wIndex; + __u16 wLength; + +#ifdef DEBUG + urb_priv.actual_length = 0; + pkt_print(dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", + usb_pipein(pipe)); +#else + wait_ms(1); +#endif + if (usb_pipeint(pipe)) { + info("Root-Hub submit IRQ: NOT implemented"); + return 0; + } + + bmRType_bReq = cmd->requesttype | (cmd->request << 8); + wValue = m16_swap(cmd->value); + wIndex = m16_swap(cmd->index); + wLength = m16_swap(cmd->length); + + info("Root-Hub: adr: %2x cmd(%1x): %08x %04x %04x %04x", + dev->devnum, 8, bmRType_bReq, wValue, wIndex, wLength); + + switch (bmRType_bReq) { + /* Request Destination: + without flags: Device, + RH_INTERFACE: interface, + RH_ENDPOINT: endpoint, + RH_CLASS means HUB here, + RH_OTHER | RH_CLASS almost ever means HUB_PORT here + */ + + case RH_GET_STATUS: + *(__u16 *) data_buf = m16_swap(1); + OK(2); + case RH_GET_STATUS | RH_INTERFACE: + *(__u16 *) data_buf = m16_swap(0); + OK(2); + case RH_GET_STATUS | RH_ENDPOINT: + *(__u16 *) data_buf = m16_swap(0); + OK(2); + case RH_GET_STATUS | RH_CLASS: + *(__u32 *) data_buf = + m32_swap(RD_RH_STAT & ~(RH_HS_CRWE | RH_HS_DRWE)); + OK(4); + case RH_GET_STATUS | RH_OTHER | RH_CLASS: + *(__u32 *) data_buf = m32_swap(RD_RH_PORTSTAT); + OK(4); + + case RH_CLEAR_FEATURE | RH_ENDPOINT: + switch (wValue) { + case (RH_ENDPOINT_STALL): + OK(0); + } + break; + + case RH_CLEAR_FEATURE | RH_CLASS: + switch (wValue) { + case RH_C_HUB_LOCAL_POWER: + OK(0); + case (RH_C_HUB_OVER_CURRENT): + WR_RH_STAT(RH_HS_OCIC); + OK(0); + } + break; + + case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS: + switch (wValue) { + case (RH_PORT_ENABLE): + WR_RH_PORTSTAT(RH_PS_CCS); + OK(0); + case (RH_PORT_SUSPEND): + WR_RH_PORTSTAT(RH_PS_POCI); + OK(0); + case (RH_PORT_POWER): + WR_RH_PORTSTAT(RH_PS_LSDA); + OK(0); + case (RH_C_PORT_CONNECTION): + WR_RH_PORTSTAT(RH_PS_CSC); + OK(0); + case (RH_C_PORT_ENABLE): + WR_RH_PORTSTAT(RH_PS_PESC); + OK(0); + case (RH_C_PORT_SUSPEND): + WR_RH_PORTSTAT(RH_PS_PSSC); + OK(0); + case (RH_C_PORT_OVER_CURRENT): + WR_RH_PORTSTAT(RH_PS_OCIC); + OK(0); + case (RH_C_PORT_RESET): + WR_RH_PORTSTAT(RH_PS_PRSC); + OK(0); + } + break; + + case RH_SET_FEATURE | RH_OTHER | RH_CLASS: + switch (wValue) { + case (RH_PORT_SUSPEND): + WR_RH_PORTSTAT(RH_PS_PSS); + OK(0); + case (RH_PORT_RESET): /* BUG IN HUP CODE ******** */ + if (RD_RH_PORTSTAT & RH_PS_CCS) + WR_RH_PORTSTAT(RH_PS_PRS); + OK(0); + case (RH_PORT_POWER): + WR_RH_PORTSTAT(RH_PS_PPS); + OK(0); + case (RH_PORT_ENABLE): /* BUG IN HUP CODE ******** */ + if (RD_RH_PORTSTAT & RH_PS_CCS) + WR_RH_PORTSTAT(RH_PS_PES); + OK(0); + } + break; + + case RH_SET_ADDRESS: + gohci.rh.devnum = wValue; + OK(0); + + case RH_GET_DESCRIPTOR: + switch ((wValue & 0xff00) >> 8) { + case (0x01): /* device descriptor */ + len = min_t(unsigned int, + leni, + min_t(unsigned int, + sizeof(root_hub_dev_des), wLength)); + data_buf = root_hub_dev_des; + OK(len); + case (0x02): /* configuration descriptor */ + len = min_t(unsigned int, + leni, + min_t(unsigned int, + sizeof(root_hub_config_des), + wLength)); + data_buf = root_hub_config_des; + OK(len); + case (0x03): /* string descriptors */ + if (wValue == 0x0300) { + len = min_t(unsigned int, + leni, + min_t(unsigned int, + sizeof(root_hub_str_index0), + wLength)); + data_buf = root_hub_str_index0; + OK(len); + } + if (wValue == 0x0301) { + len = min_t(unsigned int, + leni, + min_t(unsigned int, + sizeof(root_hub_str_index1), + wLength)); + data_buf = root_hub_str_index1; + OK(len); + } + default: + stat = USB_ST_STALLED; + } + break; + + case RH_GET_DESCRIPTOR | RH_CLASS: + { + __u32 temp = roothub_a(&gohci); + + data_buf[0] = 9; /* min length; */ + data_buf[1] = 0x29; + data_buf[2] = temp & RH_A_NDP; + data_buf[3] = 0; + if (temp & RH_A_PSM) + /* per-port power switching? */ + data_buf[3] |= 0x1; + if (temp & RH_A_NOCP) + /* no overcurrent reporting? */ + data_buf[3] |= 0x10; + else if (temp & RH_A_OCPM) + /* per-port overcurrent reporting? */ + data_buf[3] |= 0x8; + + /* corresponds to data_buf[4-7] */ + datab[1] = 0; + data_buf[5] = (temp & RH_A_POTPGT) >> 24; + temp = roothub_b(&gohci); + data_buf[7] = temp & RH_B_DR; + if (data_buf[2] < 7) { + data_buf[8] = 0xff; + } else { + data_buf[0] += 2; + data_buf[8] = (temp & RH_B_DR) >> 8; + data_buf[10] = data_buf[9] = 0xff; + } + + len = min_t(unsigned int, leni, + min_t(unsigned int, data_buf[0], wLength)); + OK(len); + } + + case RH_GET_CONFIGURATION: + *(__u8 *) data_buf = 0x01; + OK(1); + + case RH_SET_CONFIGURATION: + WR_RH_STAT(0x10000); + OK(0); + + default: + dbg("unsupported root hub command"); + stat = USB_ST_STALLED; + } + +#ifdef DEBUG + ohci_dump_roothub(&gohci, 1); +#else + wait_ms(1); +#endif + + len = min_t(int, len, leni); + if (data != data_buf) + memcpy(data, data_buf, len); + dev->act_len = len; + dev->status = stat; + +#ifdef DEBUG + if (transfer_len) + urb_priv.actual_length = transfer_len; + pkt_print(dev, pipe, buffer, transfer_len, cmd, "RET(rh)", + 0 /*usb_pipein(pipe) */); +#else + wait_ms(1); +#endif + + return stat; +} + +/*-------------------------------------------------------------------------*/ + +/* common code for handling submit messages - used for all but root hub */ +/* accesses. */ +int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer, + int transfer_len, struct devrequest *setup, int interval) +{ + int stat = 0; + int maxsize = usb_maxpacket(dev, pipe); + int timeout; + + /* device pulled? Shortcut the action. */ + if (devgone == dev) { + dev->status = USB_ST_CRC_ERR; + return 0; + } +#ifdef DEBUG + urb_priv.actual_length = 0; + pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB", + usb_pipein(pipe)); +#else + wait_ms(1); +#endif + if (!maxsize) { + err("submit_common_message: pipesize for pipe %lx is zero", + pipe); + return -1; + } + + if (sohci_submit_job(dev, pipe, buffer, transfer_len, setup, interval) < + 0) { + err("sohci_submit_job failed"); + return -1; + } + + wait_ms(10); + /* ohci_dump_status(&gohci); */ + + /* allow more time for a BULK device to react - some are slow */ +#define BULK_TO 5000 /* timeout in milliseconds */ + if (usb_pipebulk(pipe)) + timeout = BULK_TO; + else + timeout = 100; + + /* wait for it to complete */ + for (;;) { + /* check whether the controller is done */ + stat = hc_interrupt(); + + if (stat < 0) { + stat = USB_ST_CRC_ERR; + break; + } + + /* NOTE: since we are not interrupt driven in U-Boot and always + * handle only one URB at a time, we cannot assume the + * transaction finished on the first successful return from + * hc_interrupt().. unless the flag for current URB is set, + * meaning that all TD's to/from device got actually + * transferred and processed. If the current URB is not + * finished we need to re-iterate this loop so as + * hc_interrupt() gets called again as there needs to be some + * more TD's to process still */ + if ((stat >= 0) && (stat != 0xff) && (urb_finished)) { + /* 0xff is returned for an SF-interrupt */ + break; + } + + if (--timeout) { + wait_ms(1); + if (!urb_finished) + dbg("\%"); + + } else { + err("CTL:TIMEOUT "); + dbg("submit_common_msg: TO status %x\n", stat); + stat = USB_ST_CRC_ERR; + urb_finished = 1; + break; + } + } + +#if 0 + /* we got an Root Hub Status Change interrupt */ + if (got_rhsc) { +#ifdef DEBUG + ohci_dump_roothub(&gohci, 1); +#endif + got_rhsc = 0; + /* abuse timeout */ + timeout = rh_check_port_status(&gohci); + if (timeout >= 0) { +#if 0 /* this does nothing useful, but leave it here + in case that changes */ + /* the called routine adds 1 to the passed value */ + usb_hub_port_connect_change(gohci.rh.dev, timeout - 1); +#endif + /* + * XXX + * This is potentially dangerous because it assumes + * that only one device is ever plugged in! + */ + devgone = dev; + } + } +#endif + + dev->status = stat; + dev->act_len = transfer_len; + +#ifdef DEBUG + pkt_print(dev, pipe, buffer, transfer_len, setup, "RET(ctlr)", + usb_pipein(pipe)); +#else + wait_ms(1); +#endif + + /* free TDs in urb_priv */ + urb_free_priv(&urb_priv); + return 0; +} + +/* submit routines called from usb.c */ +int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer, + int transfer_len) +{ + info("submit_bulk_msg"); + return submit_common_msg(dev, pipe, buffer, transfer_len, NULL, 0); +} + +int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, + int transfer_len, struct devrequest *setup) +{ + int maxsize = usb_maxpacket(dev, pipe); + + info("submit_control_msg"); +#ifdef DEBUG + urb_priv.actual_length = 0; + pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB", + usb_pipein(pipe)); +#else + wait_ms(1); +#endif + if (!maxsize) { + err("submit_control_message: pipesize for pipe %lx is zero", + pipe); + return -1; + } + if (((pipe >> 8) & 0x7f) == gohci.rh.devnum) { + gohci.rh.dev = dev; + /* root hub - redirect */ + return ohci_submit_rh_msg(dev, pipe, buffer, transfer_len, + setup); + } + + return submit_common_msg(dev, pipe, buffer, transfer_len, setup, 0); +} + +int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, + int transfer_len, int interval) +{ + info("submit_int_msg"); + return -1; +} + +/*-------------------------------------------------------------------------* + * HC functions + *-------------------------------------------------------------------------*/ + +/* reset the HC and BUS */ + +static int hc_reset(struct ohci *ohci) +{ + int timeout = 30; + int smm_timeout = 50; /* 0,5 sec */ + + if (readl(&ohci->regs->control) & OHCI_CTRL_IR) { + /* SMM owns the HC - request ownership */ + writel(OHCI_OCR, &ohci->regs->cmdstatus); + info("USB HC TakeOver from SMM"); + while (readl(&ohci->regs->control) & OHCI_CTRL_IR) { + wait_ms(10); + if (--smm_timeout == 0) { + err("USB HC TakeOver failed!"); + return -1; + } + } + } + + /* Disable HC interrupts */ + writel(OHCI_INTR_MIE, &ohci->regs->intrdisable); + + dbg("USB HC reset_hc usb-%s: ctrl = 0x%X ;", + ohci->slot_name, readl(&ohci->regs->control)); + + /* Reset USB (needed by some controllers) */ + writel(0, &ohci->regs->control); + + /* HC Reset requires max 10 us delay */ + writel(OHCI_HCR, &ohci->regs->cmdstatus); + while ((readl(&ohci->regs->cmdstatus) & OHCI_HCR) != 0) { + if (--timeout == 0) { + err("USB HC reset timed out!"); + return -1; + } + udelay(1); + } + return 0; +} + +/*-------------------------------------------------------------------------*/ + +/* Start an OHCI controller, set the BUS operational + * enable interrupts + * connect the virtual root hub */ + +static int hc_start(struct ohci *ohci) +{ + __u32 mask; + unsigned int fminterval; + + ohci->disabled = 1; + + /* Tell the controller where the control and bulk lists are + * The lists are empty now. */ + + writel(0, &ohci->regs->ed_controlhead); + writel(0, &ohci->regs->ed_bulkhead); + + /* a reset clears this */ + writel((__u32) ohci->hcca, &ohci->regs->hcca); + + fminterval = 0x2edf; + writel((fminterval * 9) / 10, &ohci->regs->periodicstart); + fminterval |= ((((fminterval - 210) * 6) / 7) << 16); + writel(fminterval, &ohci->regs->fminterval); + writel(0x628, &ohci->regs->lsthresh); + + /* start controller operations */ + ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER; + ohci->disabled = 0; + writel(ohci->hc_control, &ohci->regs->control); + + /* disable all interrupts */ + mask = (OHCI_INTR_SO | OHCI_INTR_WDH | OHCI_INTR_SF | OHCI_INTR_RD | + OHCI_INTR_UE | OHCI_INTR_FNO | OHCI_INTR_RHSC | + OHCI_INTR_OC | OHCI_INTR_MIE); + writel(mask, &ohci->regs->intrdisable); + /* clear all interrupts */ + mask &= ~OHCI_INTR_MIE; + writel(mask, &ohci->regs->intrstatus); + /* Choose the interrupts we care about now - but w/o MIE */ + mask = OHCI_INTR_RHSC | OHCI_INTR_UE | OHCI_INTR_WDH | OHCI_INTR_SO; + writel(mask, &ohci->regs->intrenable); + +#ifdef OHCI_USE_NPS + /* required for AMD-756 and some Mac platforms */ + writel((roothub_a(ohci) | RH_A_NPS) & ~RH_A_PSM, + &ohci->regs->roothub.a); + writel(RH_HS_LPSC, &ohci->regs->roothub.status); +#endif /* OHCI_USE_NPS */ + +#define mdelay(n) ({unsigned long msec=(n); while (msec--) udelay(1000);}) + /* POTPGT delay is bits 24-31, in 2 ms units. */ + mdelay((roothub_a(ohci) >> 23) & 0x1fe); + + /* connect the virtual root hub */ + ohci->rh.devnum = 0; + + return 0; +} + +/*-------------------------------------------------------------------------*/ + +/* an interrupt happens */ + +static int hc_interrupt(void) +{ + struct ohci *ohci = &gohci; + struct ohci_regs *regs = ohci->regs; + int ints; + int stat = -1; + + if ((ohci->hcca->done_head != 0) && + !(m32_swap(ohci->hcca->done_head) & 0x01)) { + + ints = OHCI_INTR_WDH; + + } else { + ints = readl(®s->intrstatus); + if (ints == ~(u32) 0) { + ohci->disabled++; + err("%s device removed!", ohci->slot_name); + return -1; + } + ints &= readl(®s->intrenable); + if (ints == 0) { + dbg("hc_interrupt: returning..\n"); + return 0xff; + } + } + + /* dbg("Interrupt: %x frame: %x", ints, + le16_to_cpu(ohci->hcca->frame_no)); */ + + if (ints & OHCI_INTR_RHSC) { + got_rhsc = 1; + stat = 0xff; + } + + if (ints & OHCI_INTR_UE) { + ohci->disabled++; + err("OHCI Unrecoverable Error, controller usb-%s disabled", + ohci->slot_name); + /* e.g. due to PCI Master/Target Abort */ + +#ifdef DEBUG + ohci_dump(ohci, 1); +#else + wait_ms(1); +#endif + /* FIXME: be optimistic, hope that bug won't repeat often. */ + /* Make some non-interrupt context restart the controller. */ + /* Count and limit the retries though; either hardware or */ + /* software errors can go forever... */ + hc_reset(ohci); + return -1; + } + + if (ints & OHCI_INTR_WDH) { + wait_ms(1); + + writel(OHCI_INTR_WDH, ®s->intrdisable); + stat = dl_done_list(&gohci, dl_reverse_done_list(&gohci)); + writel(OHCI_INTR_WDH, ®s->intrenable); + } + + if (ints & OHCI_INTR_SO) { + dbg("USB Schedule overrun\n"); + writel(OHCI_INTR_SO, ®s->intrenable); + stat = -1; + } + + /* FIXME: this assumes SOF (1/ms) interrupts don't get lost... */ + if (ints & OHCI_INTR_SF) { + unsigned int frame = m16_swap(ohci->hcca->frame_no) & 1; + wait_ms(1); + writel(OHCI_INTR_SF, ®s->intrdisable); + if (ohci->ed_rm_list[frame] != NULL) + writel(OHCI_INTR_SF, ®s->intrenable); + stat = 0xff; + } + + writel(ints, ®s->intrstatus); + return stat; +} + +/*-------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------*/ + +/* De-allocate all resources.. */ + +static void hc_release_ohci(struct ohci *ohci) +{ + dbg("USB HC release ohci usb-%s", ohci->slot_name); + + if (!ohci->disabled) + hc_reset(ohci); +} + +/*-------------------------------------------------------------------------*/ + +/* + * low level initalisation routine, called from usb.c + */ +static char ohci_inited = 0; + +int usb_lowlevel_init(void) +{ + struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power(); + struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio(); + + /* + * Set the 48 MHz UPLL clocking. Values are taken from + * "PLL value selection guide", 6-23, s3c2400_UM.pdf. + */ + clk_power->UPLLCON = ((40 << 12) + (1 << 4) + 2); + gpio->MISCCR |= 0x8; /* 1 = use pads related USB for USB host */ + + /* + * Enable USB host clock. + */ + clk_power->CLKCON |= (1 << 4); + + memset(&gohci, 0, sizeof(struct ohci)); + memset(&urb_priv, 0, sizeof(struct urb_priv)); + + /* align the storage */ + if ((__u32) &ghcca[0] & 0xff) { + err("HCCA not aligned!!"); + return -1; + } + phcca = &ghcca[0]; + info("aligned ghcca %p", phcca); + memset(&ohci_dev, 0, sizeof(struct ohci_device)); + if ((__u32) &ohci_dev.ed[0] & 0x7) { + err("EDs not aligned!!"); + return -1; + } + memset(gtd, 0, sizeof(struct td) * (NUM_TD + 1)); + if ((__u32) gtd & 0x7) { + err("TDs not aligned!!"); + return -1; + } + ptd = gtd; + gohci.hcca = phcca; + memset(phcca, 0, sizeof(struct ohci_hcca)); + + gohci.disabled = 1; + gohci.sleeping = 0; + gohci.irq = -1; + gohci.regs = (struct ohci_regs *)S3C24X0_USB_HOST_BASE; + + gohci.flags = 0; + gohci.slot_name = "s3c2400"; + + if (hc_reset(&gohci) < 0) { + hc_release_ohci(&gohci); + /* Initialization failed */ + clk_power->CLKCON &= ~(1 << 4); + return -1; + } + + /* FIXME this is a second HC reset; why?? */ + gohci.hc_control = OHCI_USB_RESET; + writel(gohci.hc_control, &gohci.regs->control); + wait_ms(10); + + if (hc_start(&gohci) < 0) { + err("can't start usb-%s", gohci.slot_name); + hc_release_ohci(&gohci); + /* Initialization failed */ + clk_power->CLKCON &= ~(1 << 4); + return -1; + } +#ifdef DEBUG + ohci_dump(&gohci, 1); +#else + wait_ms(1); +#endif + ohci_inited = 1; + urb_finished = 1; + + return 0; +} + +int usb_lowlevel_stop(void) +{ + struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power(); + + /* this gets called really early - before the controller has */ + /* even been initialized! */ + if (!ohci_inited) + return 0; + /* TODO release any interrupts, etc. */ + /* call hc_release_ohci() here ? */ + hc_reset(&gohci); + /* may not want to do this */ + clk_power->CLKCON &= ~(1 << 4); + return 0; +} + +#endif /* defined(CONFIG_USB_OHCI) && defined(CONFIG_S3C24X0) */ diff --git a/arch/arm/cpu/arm920t/s3c24x0/usb_ohci.h b/arch/arm/cpu/arm920t/s3c24x0/usb_ohci.h new file mode 100644 index 0000000000..f272d78859 --- /dev/null +++ b/arch/arm/cpu/arm920t/s3c24x0/usb_ohci.h @@ -0,0 +1,409 @@ +/* + * URB OHCI HCD (Host Controller Driver) for USB. + * + * (C) Copyright 1999 Roman Weissgaerber + * (C) Copyright 2000-2001 David Brownell + * + * usb-ohci.h + */ + + +static int cc_to_error[16] = { + +/* mapping of the OHCI CC status to error codes */ + /* No Error */ 0, + /* CRC Error */ USB_ST_CRC_ERR, + /* Bit Stuff */ USB_ST_BIT_ERR, + /* Data Togg */ USB_ST_CRC_ERR, + /* Stall */ USB_ST_STALLED, + /* DevNotResp */ -1, + /* PIDCheck */ USB_ST_BIT_ERR, + /* UnExpPID */ USB_ST_BIT_ERR, + /* DataOver */ USB_ST_BUF_ERR, + /* DataUnder */ USB_ST_BUF_ERR, + /* reservd */ -1, + /* reservd */ -1, + /* BufferOver */ USB_ST_BUF_ERR, + /* BuffUnder */ USB_ST_BUF_ERR, + /* Not Access */ -1, + /* Not Access */ -1 +}; + +/* ED States */ +#define ED_NEW 0x00 +#define ED_UNLINK 0x01 +#define ED_OPER 0x02 +#define ED_DEL 0x04 +#define ED_URB_DEL 0x08 + +/* usb_ohci_ed */ +struct ed { + __u32 hwINFO; + __u32 hwTailP; + __u32 hwHeadP; + __u32 hwNextED; + + struct ed *ed_prev; + __u8 int_period; + __u8 int_branch; + __u8 int_load; + __u8 int_interval; + __u8 state; + __u8 type; + __u16 last_iso; + struct ed *ed_rm_list; + + struct usb_device *usb_dev; + __u32 unused[3]; +} __attribute__ ((aligned(16))); + +/* TD info field */ +#define TD_CC 0xf0000000 +#define TD_CC_GET(td_p) (((td_p) >> 28) & 0x0f) +#define TD_CC_SET(td_p, cc) \ + {(td_p) = ((td_p) & 0x0fffffff) | (((cc) & 0x0f) << 28)} +#define TD_EC 0x0C000000 +#define TD_T 0x03000000 +#define TD_T_DATA0 0x02000000 +#define TD_T_DATA1 0x03000000 +#define TD_T_TOGGLE 0x00000000 +#define TD_R 0x00040000 +#define TD_DI 0x00E00000 +#define TD_DI_SET(X) (((X) & 0x07)<< 21) +#define TD_DP 0x00180000 +#define TD_DP_SETUP 0x00000000 +#define TD_DP_IN 0x00100000 +#define TD_DP_OUT 0x00080000 + +#define TD_ISO 0x00010000 +#define TD_DEL 0x00020000 + +/* CC Codes */ +#define TD_CC_NOERROR 0x00 +#define TD_CC_CRC 0x01 +#define TD_CC_BITSTUFFING 0x02 +#define TD_CC_DATATOGGLEM 0x03 +#define TD_CC_STALL 0x04 +#define TD_DEVNOTRESP 0x05 +#define TD_PIDCHECKFAIL 0x06 +#define TD_UNEXPECTEDPID 0x07 +#define TD_DATAOVERRUN 0x08 +#define TD_DATAUNDERRUN 0x09 +#define TD_BUFFEROVERRUN 0x0C +#define TD_BUFFERUNDERRUN 0x0D +#define TD_NOTACCESSED 0x0F + + +#define MAXPSW 1 + +struct td { + __u32 hwINFO; + __u32 hwCBP; /* Current Buffer Pointer */ + __u32 hwNextTD; /* Next TD Pointer */ + __u32 hwBE; /* Memory Buffer End Pointer */ + + __u8 unused; + __u8 index; + struct ed *ed; + struct td *next_dl_td; + struct usb_device *usb_dev; + int transfer_len; + __u32 data; + + __u32 unused2[2]; +} __attribute__ ((aligned(32))); + +#define OHCI_ED_SKIP (1 << 14) + +/* + * The HCCA (Host Controller Communications Area) is a 256 byte + * structure defined in the OHCI spec. that the host controller is + * told the base address of. It must be 256-byte aligned. + */ + +#define NUM_INTS 32 /* part of the OHCI standard */ +struct ohci_hcca { + __u32 int_table[NUM_INTS]; /* Interrupt ED table */ + __u16 frame_no; /* current frame number */ + __u16 pad1; /* set to 0 on each frame_no change */ + __u32 done_head; /* info returned for an interrupt */ + u8 reserved_for_hc[116]; +} __attribute__ ((aligned(256))); + +/* + * Maximum number of root hub ports. + */ +#define MAX_ROOT_PORTS 15 /* maximum OHCI root hub ports */ + +/* + * This is the structure of the OHCI controller's memory mapped I/O + * region. This is Memory Mapped I/O. You must use the readl() and + * writel() macros defined in asm/io.h to access these!! + */ +struct ohci_regs { + /* control and status registers */ + __u32 revision; + __u32 control; + __u32 cmdstatus; + __u32 intrstatus; + __u32 intrenable; + __u32 intrdisable; + /* memory pointers */ + __u32 hcca; + __u32 ed_periodcurrent; + __u32 ed_controlhead; + __u32 ed_controlcurrent; + __u32 ed_bulkhead; + __u32 ed_bulkcurrent; + __u32 donehead; + /* frame counters */ + __u32 fminterval; + __u32 fmremaining; + __u32 fmnumber; + __u32 periodicstart; + __u32 lsthresh; + /* Root hub ports */ + struct ohci_roothub_regs { + __u32 a; + __u32 b; + __u32 status; + __u32 portstatus[MAX_ROOT_PORTS]; + } roothub; +} __attribute__ ((aligned(32))); + +/* OHCI CONTROL AND STATUS REGISTER MASKS */ + +/* + * HcControl (control) register masks + */ +#define OHCI_CTRL_CBSR (3 << 0) /* control/bulk service ratio */ +#define OHCI_CTRL_PLE (1 << 2) /* periodic list enable */ +#define OHCI_CTRL_IE (1 << 3) /* isochronous enable */ +#define OHCI_CTRL_CLE (1 << 4) /* control list enable */ +#define OHCI_CTRL_BLE (1 << 5) /* bulk list enable */ +#define OHCI_CTRL_HCFS (3 << 6) /* host controller functional state */ +#define OHCI_CTRL_IR (1 << 8) /* interrupt routing */ +#define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */ +#define OHCI_CTRL_RWE (1 << 10) /* remote wakeup enable */ + +/* pre-shifted values for HCFS */ +# define OHCI_USB_RESET (0 << 6) +# define OHCI_USB_RESUME (1 << 6) +# define OHCI_USB_OPER (2 << 6) +# define OHCI_USB_SUSPEND (3 << 6) + +/* + * HcCommandStatus (cmdstatus) register masks + */ +#define OHCI_HCR (1 << 0) /* host controller reset */ +#define OHCI_CLF (1 << 1) /* control list filled */ +#define OHCI_BLF (1 << 2) /* bulk list filled */ +#define OHCI_OCR (1 << 3) /* ownership change request */ +#define OHCI_SOC (3 << 16) /* scheduling overrun count */ + +/* + * masks used with interrupt registers: + * HcInterruptStatus (intrstatus) + * HcInterruptEnable (intrenable) + * HcInterruptDisable (intrdisable) + */ +#define OHCI_INTR_SO (1 << 0) /* scheduling overrun */ +#define OHCI_INTR_WDH (1 << 1) /* writeback of done_head */ +#define OHCI_INTR_SF (1 << 2) /* start frame */ +#define OHCI_INTR_RD (1 << 3) /* resume detect */ +#define OHCI_INTR_UE (1 << 4) /* unrecoverable error */ +#define OHCI_INTR_FNO (1 << 5) /* frame number overflow */ +#define OHCI_INTR_RHSC (1 << 6) /* root hub status change */ +#define OHCI_INTR_OC (1 << 30) /* ownership change */ +#define OHCI_INTR_MIE (1 << 31) /* master interrupt enable */ + +/* Virtual Root HUB */ +struct virt_root_hub { + int devnum; /* Address of Root Hub endpoint */ + void *dev; /* was urb */ + void *int_addr; + int send; + int interval; +}; + +/* USB HUB CONSTANTS (not OHCI-specific; see hub.h) */ + +/* destination of request */ +#define RH_INTERFACE 0x01 +#define RH_ENDPOINT 0x02 +#define RH_OTHER 0x03 + +#define RH_CLASS 0x20 +#define RH_VENDOR 0x40 + +/* Requests: bRequest << 8 | bmRequestType */ +#define RH_GET_STATUS 0x0080 +#define RH_CLEAR_FEATURE 0x0100 +#define RH_SET_FEATURE 0x0300 +#define RH_SET_ADDRESS 0x0500 +#define RH_GET_DESCRIPTOR 0x0680 +#define RH_SET_DESCRIPTOR 0x0700 +#define RH_GET_CONFIGURATION 0x0880 +#define RH_SET_CONFIGURATION 0x0900 +#define RH_GET_STATE 0x0280 +#define RH_GET_INTERFACE 0x0A80 +#define RH_SET_INTERFACE 0x0B00 +#define RH_SYNC_FRAME 0x0C80 +/* Our Vendor Specific Request */ +#define RH_SET_EP 0x2000 + + +/* Hub port features */ +#define RH_PORT_CONNECTION 0x00 +#define RH_PORT_ENABLE 0x01 +#define RH_PORT_SUSPEND 0x02 +#define RH_PORT_OVER_CURRENT 0x03 +#define RH_PORT_RESET 0x04 +#define RH_PORT_POWER 0x08 +#define RH_PORT_LOW_SPEED 0x09 + +#define RH_C_PORT_CONNECTION 0x10 +#define RH_C_PORT_ENABLE 0x11 +#define RH_C_PORT_SUSPEND 0x12 +#define RH_C_PORT_OVER_CURRENT 0x13 +#define RH_C_PORT_RESET 0x14 + +/* Hub features */ +#define RH_C_HUB_LOCAL_POWER 0x00 +#define RH_C_HUB_OVER_CURRENT 0x01 + +#define RH_DEVICE_REMOTE_WAKEUP 0x00 +#define RH_ENDPOINT_STALL 0x01 + +#define RH_ACK 0x01 +#define RH_REQ_ERR -1 +#define RH_NACK 0x00 + + +/* OHCI ROOT HUB REGISTER MASKS */ + +/* roothub.portstatus [i] bits */ +#define RH_PS_CCS 0x00000001 /* current connect status */ +#define RH_PS_PES 0x00000002 /* port enable status */ +#define RH_PS_PSS 0x00000004 /* port suspend status */ +#define RH_PS_POCI 0x00000008 /* port over current indicator */ +#define RH_PS_PRS 0x00000010 /* port reset status */ +#define RH_PS_PPS 0x00000100 /* port power status */ +#define RH_PS_LSDA 0x00000200 /* low speed device attached */ +#define RH_PS_CSC 0x00010000 /* connect status change */ +#define RH_PS_PESC 0x00020000 /* port enable status change */ +#define RH_PS_PSSC 0x00040000 /* port suspend status change */ +#define RH_PS_OCIC 0x00080000 /* over current indicator change */ +#define RH_PS_PRSC 0x00100000 /* port reset status change */ + +/* roothub.status bits */ +#define RH_HS_LPS 0x00000001 /* local power status */ +#define RH_HS_OCI 0x00000002 /* over current indicator */ +#define RH_HS_DRWE 0x00008000 /* device remote wakeup enable */ +#define RH_HS_LPSC 0x00010000 /* local power status change */ +#define RH_HS_OCIC 0x00020000 /* over current indicator change */ +#define RH_HS_CRWE 0x80000000 /* clear remote wakeup enable */ + +/* roothub.b masks */ +#define RH_B_DR 0x0000ffff /* device removable flags */ +#define RH_B_PPCM 0xffff0000 /* port power control mask */ + +/* roothub.a masks */ +#define RH_A_NDP (0xff << 0) /* number of downstream ports */ +#define RH_A_PSM (1 << 8) /* power switching mode */ +#define RH_A_NPS (1 << 9) /* no power switching */ +#define RH_A_DT (1 << 10) /* device type (mbz) */ +#define RH_A_OCPM (1 << 11) /* over current protection mode */ +#define RH_A_NOCP (1 << 12) /* no over current protection */ +#define RH_A_POTPGT (0xff << 24) /* power on to power good time */ + +/* urb */ +#define N_URB_TD 48 +struct urb_priv { + struct ed *ed; + __u16 length; /* number of tds associated with this request */ + __u16 td_cnt; /* number of tds already serviced */ + int state; + unsigned long pipe; + int actual_length; + struct td *td[N_URB_TD]; /* list pointer to all corresponding TDs + associated with this request */ +}; +#define URB_DEL 1 + +/* + * This is the full ohci controller description + * + * Note how the "proper" USB information is just + * a subset of what the full implementation needs. (Linus) + */ + + +struct ohci { + struct ohci_hcca *hcca; /* hcca */ + /*dma_addr_t hcca_dma; */ + + int irq; + int disabled; /* e.g. got a UE, we're hung */ + int sleeping; + unsigned long flags; /* for HC bugs */ + + struct ohci_regs *regs; /* OHCI controller's memory */ + + struct ed *ed_rm_list[2]; /* lists of all endpoints to be removed */ + struct ed *ed_bulktail; /* last endpoint of bulk list */ + struct ed *ed_controltail; /* last endpoint of control list */ + int intrstatus; + __u32 hc_control; /* copy of the hc control reg */ + struct usb_device *dev[32]; + struct virt_root_hub rh; + + const char *slot_name; +}; + +#define NUM_EDS 8 /* num of preallocated endpoint descriptors */ + +struct ohci_device { + struct ed ed[NUM_EDS]; + int ed_cnt; +}; + +/* hcd */ +/* endpoint */ +static int ep_link(struct ohci *ohci, struct ed *ed); +static int ep_unlink(struct ohci *ohci, struct ed *ed); +static struct ed *ep_add_ed(struct usb_device *usb_dev, unsigned long pipe); + +/*-------------------------------------------------------------------------*/ + +/* we need more TDs than EDs */ +#define NUM_TD 64 + +/* +1 so we can align the storage */ +struct td gtd[NUM_TD + 1]; + +/* pointers to aligned storage */ +struct td *ptd; + +/* TDs ... */ +static inline struct td *td_alloc(struct usb_device *usb_dev) +{ + int i; + struct td *td; + + td = NULL; + for (i = 0; i < NUM_TD; i++) { + if (ptd[i].usb_dev == NULL) { + td = &ptd[i]; + td->usb_dev = usb_dev; + break; + } + } + + return td; +} + +static inline void ed_free(struct ed *ed) +{ + ed->usb_dev = NULL; +} diff --git a/arch/arm/cpu/arm920t/start.S b/arch/arm/cpu/arm920t/start.S new file mode 100644 index 0000000000..779f192e51 --- /dev/null +++ b/arch/arm/cpu/arm920t/start.S @@ -0,0 +1,436 @@ +/* + * armboot - Startup Code for ARM920 CPU-core + * + * Copyright (c) 2001 Marius Gröger + * Copyright (c) 2002 Alex Züpke + * Copyright (c) 2002 Gary Jennejohn + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +/* + ************************************************************************* + * + * Jump vector table as in table 3.1 in [1] + * + ************************************************************************* + */ + + +.globl _start +_start: b start_code + 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 + +_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 (called from the ARM reset exception vector) + * + * do important init only if we don't start from memory! + * relocate armboot to ram + * setup stack + * jump to second stage + * + ************************************************************************* + */ + +_TEXT_BASE: + .word TEXT_BASE + +.globl _armboot_start +_armboot_start: + .word _start + +/* + * These are defined in the board-specific linker script. + */ +.globl _bss_start +_bss_start: + .word __bss_start + +.globl _bss_end +_bss_end: + .word _end + +#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 + + +/* + * the actual start code + */ + +start_code: + /* + * set the cpu to SVC32 mode + */ + mrs r0, cpsr + bic r0, r0, #0x1f + orr r0, r0, #0xd3 + msr cpsr, r0 + + bl coloured_LED_init + bl red_LED_on + +#if defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK) + /* + * relocate exception table + */ + ldr r0, =_start + ldr r1, =0x0 + mov r2, #16 +copyex: + subs r2, r2, #1 + ldr r3, [r0], #4 + str r3, [r1], #4 + bne copyex +#endif + +#ifdef CONFIG_S3C24X0 + /* turn off the watchdog */ + +# if defined(CONFIG_S3C2400) +# define pWTCON 0x15300000 +# define INTMSK 0x14400008 /* Interupt-Controller base addresses */ +# define CLKDIVN 0x14800014 /* clock divisor register */ +#else +# define pWTCON 0x53000000 +# define INTMSK 0x4A000008 /* Interupt-Controller base addresses */ +# define INTSUBMSK 0x4A00001C +# define CLKDIVN 0x4C000014 /* clock divisor register */ +# endif + + ldr r0, =pWTCON + mov r1, #0x0 + str r1, [r0] + + /* + * mask all IRQs by setting all bits in the INTMR - default + */ + mov r1, #0xffffffff + ldr r0, =INTMSK + str r1, [r0] +# if defined(CONFIG_S3C2410) + ldr r1, =0x3ff + ldr r0, =INTSUBMSK + str r1, [r0] +# endif + + /* FCLK:HCLK:PCLK = 1:2:4 */ + /* default FCLK is 120 MHz ! */ + ldr r0, =CLKDIVN + mov r1, #3 + str r1, [r0] +#endif /* CONFIG_S3C24X0 */ + + /* + * we do sys-critical inits only at reboot, + * not when booting from ram! + */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl cpu_init_crit +#endif + +#ifndef CONFIG_SKIP_RELOCATE_UBOOT +relocate: /* relocate U-Boot to RAM */ + adr r0, _start /* r0 <- current position of code */ + ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ + cmp r0, r1 /* don't reloc during debug */ + beq stack_setup + + ldr r2, _armboot_start + ldr r3, _bss_start + sub r2, r3, r2 /* r2 <- size of armboot */ + add r2, r0, r2 /* r2 <- source end address */ + +copy_loop: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end addreee [r2] */ + ble copy_loop +#endif /* CONFIG_SKIP_RELOCATE_UBOOT */ + + /* Set up the stack */ +stack_setup: + ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ + sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */ + sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ +#ifdef CONFIG_USE_IRQ + sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) +#endif + sub sp, r0, #12 /* leave 3 words for abort-stack */ + +clear_bss: + ldr r0, _bss_start /* find start of bss segment */ + ldr r1, _bss_end /* stop here */ + mov r2, #0x00000000 /* clear */ + +clbss_l:str r2, [r0] /* clear loop... */ + add r0, r0, #4 + cmp r0, r1 + ble clbss_l + + ldr pc, _start_armboot + +_start_armboot: .word start_armboot + + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + ************************************************************************* + */ + + +#ifndef CONFIG_SKIP_LOWLEVEL_INIT +cpu_init_crit: + /* + * flush v4 I/D caches + */ + mov r0, #0 + mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ + mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ + + /* + * disable MMU stuff and caches + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) + bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) + orr r0, r0, #0x00000002 @ set bit 2 (A) Align + orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache + mcr p15, 0, r0, c1, c0, 0 + + /* + * before relocating, we have to setup RAM timing + * because memory timing is board-dependend, you will + * find a lowlevel_init.S in your board directory. + */ + mov ip, lr + + bl lowlevel_init + + mov lr, ip + mov pc, lr +#endif /* CONFIG_SKIP_LOWLEVEL_INIT */ + +/* + ************************************************************************* + * + * 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 +#define I_BIT 0x80 + +/* + * use bad_save_user_regs for abort/prefetch/undef/swi ... + * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling + */ + + .macro bad_save_user_regs + sub sp, sp, #S_FRAME_SIZE + stmia sp, {r0 - r12} @ Calling r0-r12 + ldr r2, _armboot_start + sub r2, r2, #(CONFIG_STACKSIZE) + sub r2, r2, #(CONFIG_SYS_MALLOC_LEN) + /* set base 2 words into abort stack */ + sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) + ldmia r2, {r2 - r3} @ get pc, cpsr + add r0, sp, #S_FRAME_SIZE @ restore sp_SVC + + add r5, sp, #S_SP + mov r1, lr + stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr + mov r0, sp + .endm + + .macro irq_save_user_regs + sub sp, sp, #S_FRAME_SIZE + stmia sp, {r0 - r12} @ Calling r0-r12 + add r7, sp, #S_PC + stmdb r7, {sp, lr}^ @ Calling SP, LR + str lr, [r7, #0] @ Save calling PC + mrs r6, spsr + str r6, [r7, #4] @ Save CPSR + str r0, [r7, #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 + /* return & move spsr_svc into cpsr */ + subs pc, lr, #4 + .endm + + .macro get_bad_stack + ldr r13, _armboot_start @ setup our mode stack + sub r13, r13, #(CONFIG_STACKSIZE) + sub r13, r13, #(CONFIG_SYS_MALLOC_LEN) + /* reserve a couple spots in abort stack */ + sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) + + 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 + msr spsr, 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 + /* someone ought to write a more effiction fiq_save_user_regs */ + irq_save_user_regs + bl do_fiq + 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 diff --git a/arch/arm/cpu/arm920t/u-boot.lds b/arch/arm/cpu/arm920t/u-boot.lds new file mode 100644 index 0000000000..a7decfcd7d --- /dev/null +++ b/arch/arm/cpu/arm920t/u-boot.lds @@ -0,0 +1,64 @@ +/* + * (c) Copyright 2004 + * Techware Information Technology, Inc. + * Ming-Len Wu + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + arch/arm/cpu/arm920t/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = ALIGN(4); + __bss_start = .; + .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } + _end = .; +} diff --git a/arch/arm/cpu/arm925t/Makefile b/arch/arm/cpu/arm925t/Makefile new file mode 100644 index 0000000000..8d0e88f902 --- /dev/null +++ b/arch/arm/cpu/arm925t/Makefile @@ -0,0 +1,50 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(CPU).a + +START = start.o + +COBJS += cpu.o +COBJS += omap925.o +COBJS += timer.o + +SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm925t/config.mk b/arch/arm/cpu/arm925t/config.mk new file mode 100644 index 0000000000..8f6c1a354c --- /dev/null +++ b/arch/arm/cpu/arm925t/config.mk @@ -0,0 +1,32 @@ +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float + +PLATFORM_CPPFLAGS += -march=armv4 +# ========================================================================= +# +# Supply options according to compiler version +# +# ========================================================================= +PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/arch/arm/cpu/arm925t/cpu.c b/arch/arm/cpu/arm925t/cpu.c new file mode 100644 index 0000000000..71700bb175 --- /dev/null +++ b/arch/arm/cpu/arm925t/cpu.c @@ -0,0 +1,66 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * CPU specific code + */ + +#include +#include +#include +#include + +static void cache_flush(void); + +int cleanup_before_linux (void) +{ + /* + * this function is called just before we call linux + * it prepares the processor for linux + * + * we turn off caches etc ... + */ + + disable_interrupts (); + + + /* turn off I/D-cache */ + icache_disable(); + dcache_disable(); + /* flush I/D-cache */ + cache_flush(); + + return 0; +} + +/* flush I/D-cache */ +static void cache_flush (void) +{ + unsigned long i = 0; + + asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); +} diff --git a/arch/arm/cpu/arm925t/omap925.c b/arch/arm/cpu/arm925t/omap925.c new file mode 100644 index 0000000000..65dab9f88d --- /dev/null +++ b/arch/arm/cpu/arm925t/omap925.c @@ -0,0 +1,39 @@ +/* + * (C) Copyright 2003 + * Texas Instruments + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +#define MIF_CONFIG_REG 0xFFFECC0C +#define FLASH_GLOBAL_CTRL_NWP 1 + +void archflashwp (void *archdata, int wp) +{ + ulong *fgc = (ulong *) MIF_CONFIG_REG; + + if (wp == 1) + *fgc &= ~FLASH_GLOBAL_CTRL_NWP; + else + *fgc |= FLASH_GLOBAL_CTRL_NWP; +} diff --git a/arch/arm/cpu/arm925t/start.S b/arch/arm/cpu/arm925t/start.S new file mode 100644 index 0000000000..567e80479e --- /dev/null +++ b/arch/arm/cpu/arm925t/start.S @@ -0,0 +1,429 @@ +/* + * armboot - Startup Code for ARM925 CPU-core + * + * Copyright (c) 2003 Texas Instruments + * + * ----- Adapted for OMAP1510 from ARM920 code ------ + * + * Copyright (c) 2001 Marius Gröger + * Copyright (c) 2002 Alex Züpke + * Copyright (c) 2002 Gary Jennejohn + * Copyright (c) 2003 Richard Woodruff + * Copyright (c) 2003 Kshitij + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + +#include +#include + +#if defined(CONFIG_OMAP1510) +#include <./configs/omap1510.h> +#endif + +/* + ************************************************************************* + * + * Jump vector table as in table 3.1 in [1] + * + ************************************************************************* + */ + + +.globl _start +_start: b 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 + +_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! + * setup Memory and board specific bits prior to relocation. + * relocate armboot to ram + * setup stack + * + ************************************************************************* + */ + +_TEXT_BASE: + .word TEXT_BASE + +.globl _armboot_start +_armboot_start: + .word _start + +/* + * These are defined in the board-specific linker script. + */ +.globl _bss_start +_bss_start: + .word __bss_start + +.globl _bss_end +_bss_end: + .word _end + +#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 + + +/* + * the actual reset code + */ + +reset: + /* + * set the cpu to SVC32 mode + */ + mrs r0,cpsr + bic r0,r0,#0x1f + orr r0,r0,#0xd3 + msr cpsr,r0 + + /* + * Set up 925T mode + */ + mov r1, #0x81 /* Set ARM925T configuration. */ + mcr p15, 0, r1, c15, c1, 0 /* Write ARM925T configuration register. */ + + /* + * turn off the watchdog, unlock/diable sequence + */ + mov r1, #0xF5 + ldr r0, =WDTIM_MODE + strh r1, [r0] + mov r1, #0xA0 + strh r1, [r0] + + /* + * mask all IRQs by setting all bits in the INTMR - default + */ + mov r1, #0xffffffff + ldr r0, =REG_IHL1_MIR + str r1, [r0] + ldr r0, =REG_IHL2_MIR + str r1, [r0] + + /* + * wait for dpll to lock + */ + ldr r0, =CK_DPLL1 + mov r1, #0x10 + strh r1, [r0] +poll1: + ldrh r1, [r0] + ands r1, r1, #0x01 + beq poll1 + + /* + * we do sys-critical inits only at reboot, + * not when booting from ram! + */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl cpu_init_crit +#endif + +#ifndef CONFIG_SKIP_RELOCATE_UBOOT +relocate: /* relocate U-Boot to RAM */ + adr r0, _start /* r0 <- current position of code */ + ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ + cmp r0, r1 /* don't reloc during debug */ + beq stack_setup + + ldr r2, _armboot_start + ldr r3, _bss_start + sub r2, r3, r2 /* r2 <- size of armboot */ + add r2, r0, r2 /* r2 <- source end address */ + +copy_loop: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end addreee [r2] */ + ble copy_loop +#endif /* CONFIG_SKIP_RELOCATE_UBOOT */ + + /* Set up the stack */ +stack_setup: + ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ + sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */ + sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ +#ifdef CONFIG_USE_IRQ + sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) +#endif + sub sp, r0, #12 /* leave 3 words for abort-stack */ + +clear_bss: + ldr r0, _bss_start /* find start of bss segment */ + ldr r1, _bss_end /* stop here */ + mov r2, #0x00000000 /* clear */ + +clbss_l:str r2, [r0] /* clear loop... */ + add r0, r0, #4 + cmp r0, r1 + ble clbss_l + + ldr pc, _start_armboot + +_start_armboot: .word start_armboot + + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + ************************************************************************* + */ + + +cpu_init_crit: + /* + * flush v4 I/D caches + */ + mov r0, #0 + mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ + mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ + + /* + * disable MMU stuff and caches + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) + bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) + orr r0, r0, #0x00000002 @ set bit 2 (A) Align + orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache + mcr p15, 0, r0, c1, c0, 0 + + /* + * Go setup Memory and board specific bits prior to relocation. + */ + mov ip, lr /* perserve link reg across call */ + bl lowlevel_init /* go setup pll,mux,memory */ + mov lr, ip /* restore link */ + mov pc, lr /* back to my caller */ +/* + ************************************************************************* + * + * 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 +#define I_BIT 0x80 + +/* + * use bad_save_user_regs for abort/prefetch/undef/swi ... + * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling + */ + + .macro bad_save_user_regs + sub sp, sp, #S_FRAME_SIZE @ carve out a frame on current user stack + stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12 + + ldr r2, _armboot_start + sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) + sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack + ldmia r2, {r2 - r3} @ get values for "aborted" pc and cpsr (into parm regs) + add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack + + add r5, sp, #S_SP + mov r1, lr + stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr + mov r0, sp @ save current stack into r0 (param register) + .endm + + .macro irq_save_user_regs + sub sp, sp, #S_FRAME_SIZE + stmia sp, {r0 - r12} @ Calling r0-r12 + add r8, sp, #S_PC @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good. + 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, _armboot_start @ setup our mode stack + sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) + sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack + + str lr, [r13] @ save caller lr in position 0 of saved stack + mrs lr, spsr @ get the spsr + str lr, [r13, #4] @ save spsr in position 1 of saved stack + + mov r13, #MODE_SVC @ prepare SVC-Mode + @ msr spsr_c, r13 + msr spsr, r13 @ switch modes, make sure moves will execute + mov lr, pc @ capture return pc + movs pc, lr @ jump to next instruction & switch modes. + .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 + /* someone ought to write a more effiction fiq_save_user_regs */ + irq_save_user_regs + bl do_fiq + 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 + + .align 5 +.globl reset_cpu +reset_cpu: + ldr r1, rstctl1 /* get clkm1 reset ctl */ + mov r3, #0x3 /* dsp_en + arm_rst = global reset */ + strh r3, [r1] /* force reset */ + mov r0, r0 +_loop_forever: + b _loop_forever +rstctl1: + .word 0xfffece10 diff --git a/arch/arm/cpu/arm925t/timer.c b/arch/arm/cpu/arm925t/timer.c new file mode 100644 index 0000000000..7dfe2b5646 --- /dev/null +++ b/arch/arm/cpu/arm925t/timer.c @@ -0,0 +1,137 @@ +/* + * (C) Copyright 2009 + * 2N Telekomunikace, + * + * (C) Copyright 2003 + * Texas Instruments, + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include + +#define TIMER_LOAD_VAL 0xffffffff +#define TIMER_CLOCK (CONFIG_SYS_CLK_FREQ / (2 << CONFIG_SYS_PTV)) + +static uint32_t timestamp; +static uint32_t lastdec; + +/* nothing really to do with interrupts, just starts up a counter. */ +int timer_init (void) +{ + /* Start the decrementer ticking down from 0xffffffff */ + __raw_writel(TIMER_LOAD_VAL, CONFIG_SYS_TIMERBASE + LOAD_TIM); + __raw_writel(MPUTIM_ST | MPUTIM_AR | MPUTIM_CLOCK_ENABLE | + (CONFIG_SYS_PTV << MPUTIM_PTV_BIT), + CONFIG_SYS_TIMERBASE + CNTL_TIMER); + + /* init the timestamp and lastdec value */ + reset_timer_masked(); + + return 0; +} + +/* + * timer without interrupts + */ + +void reset_timer (void) +{ + reset_timer_masked (); +} + +ulong get_timer (ulong base) +{ + return get_timer_masked () - base; +} + +void set_timer (ulong t) +{ + timestamp = t; +} + +/* delay x useconds AND preserve advance timestamp value */ +void __udelay (unsigned long usec) +{ + int32_t tmo = usec * (TIMER_CLOCK / 1000) / 1000; + uint32_t now, last = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM); + + while (tmo > 0) { + now = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM); + if (last < now) /* count down timer underflow */ + tmo -= TIMER_LOAD_VAL - now + last; + else + tmo -= last - now; + last = now; + } +} + +void reset_timer_masked (void) +{ + /* reset time */ + lastdec = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM) / + (TIMER_CLOCK / CONFIG_SYS_HZ); + timestamp = 0; /* start "advancing" time stamp from 0 */ +} + +ulong get_timer_masked (void) +{ + uint32_t now = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM) / + (TIMER_CLOCK / CONFIG_SYS_HZ); + if (lastdec < now) /* count down timer underflow */ + timestamp += TIMER_LOAD_VAL / (TIMER_CLOCK / CONFIG_SYS_HZ) - + now + lastdec; + else + timestamp += lastdec - now; + lastdec = now; + + return timestamp; +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk (void) +{ + return CONFIG_SYS_HZ; +} diff --git a/arch/arm/cpu/arm925t/u-boot.lds b/arch/arm/cpu/arm925t/u-boot.lds new file mode 100644 index 0000000000..e21d6dc5a7 --- /dev/null +++ b/arch/arm/cpu/arm925t/u-boot.lds @@ -0,0 +1,59 @@ +/* + * (C) Copyright 2004 + * Wolfgang Denk, DENX Software Engineering, + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + arch/arm/cpu/arm925t/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = ALIGN(4); + __bss_start = .; + .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } + _end = .; +} diff --git a/arch/arm/cpu/arm926ejs/Makefile b/arch/arm/cpu/arm926ejs/Makefile new file mode 100644 index 0000000000..7701b03bbe --- /dev/null +++ b/arch/arm/cpu/arm926ejs/Makefile @@ -0,0 +1,47 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(CPU).a + +START = start.o +COBJS = cpu.o + +SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm926ejs/at91/Makefile b/arch/arm/cpu/arm926ejs/at91/Makefile new file mode 100644 index 0000000000..4f467be91c --- /dev/null +++ b/arch/arm/cpu/arm926ejs/at91/Makefile @@ -0,0 +1,62 @@ +# +# (C) Copyright 2000-2008 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +COBJS-$(CONFIG_AT91CAP9) += at91cap9_devices.o +COBJS-$(CONFIG_AT91SAM9260) += at91sam9260_devices.o +COBJS-$(CONFIG_AT91SAM9G20) += at91sam9260_devices.o +COBJS-$(CONFIG_AT91SAM9261) += at91sam9261_devices.o +COBJS-$(CONFIG_AT91SAM9G10) += at91sam9261_devices.o +COBJS-$(CONFIG_AT91SAM9263) += at91sam9263_devices.o +COBJS-$(CONFIG_AT91SAM9RL) += at91sam9rl_devices.o +COBJS-$(CONFIG_AT91SAM9M10G45) += at91sam9m10g45_devices.o +COBJS-$(CONFIG_AT91SAM9G45) += at91sam9m10g45_devices.o +COBJS-$(CONFIG_AT91_LED) += led.o +COBJS-y += clock.o +COBJS-y += cpu.o +COBJS-y += reset.o +COBJS-y += timer.o + +ifndef CONFIG_SKIP_LOWLEVEL_INIT +SOBJS-y := lowlevel_init.o +endif + +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm926ejs/at91/at91cap9_devices.c b/arch/arm/cpu/arm926ejs/at91/at91cap9_devices.c new file mode 100644 index 0000000000..2d878fdde6 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/at91/at91cap9_devices.c @@ -0,0 +1,205 @@ +/* + * (C) Copyright 2007-2008 + * Stelian Pop + * Lead Tech Design + * + * (C) Copyright 2009 + * Daniel Gorsulowski + * esd electronic system design gmbh + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include + +void at91_serial0_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTA, 22, 1); /* TXD0 */ + at91_set_a_periph(AT91_PIO_PORTA, 23, 0); /* RXD0 */ + writel(1 << AT91CAP9_ID_US0, &pmc->pcer); +} + +void at91_serial1_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTD, 0, 1); /* TXD1 */ + at91_set_a_periph(AT91_PIO_PORTD, 1, 0); /* RXD1 */ + writel(1 << AT91CAP9_ID_US1, &pmc->pcer); +} + +void at91_serial2_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTD, 2, 1); /* TXD2 */ + at91_set_a_periph(AT91_PIO_PORTD, 3, 0); /* RXD2 */ + writel(1 << AT91CAP9_ID_US2, &pmc->pcer); +} + +void at91_serial3_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTC, 30, 0); /* DRXD */ + at91_set_a_periph(AT91_PIO_PORTC, 31, 1); /* DTXD */ + writel(1 << AT91_ID_SYS, &pmc->pcer); +} + +void at91_serial_hw_init(void) +{ +#ifdef CONFIG_USART0 + at91_serial0_hw_init(); +#endif + +#ifdef CONFIG_USART1 + at91_serial1_hw_init(); +#endif + +#ifdef CONFIG_USART2 + at91_serial2_hw_init(); +#endif + +#ifdef CONFIG_USART3 /* DBGU */ + at91_serial3_hw_init(); +#endif +} + +#ifdef CONFIG_HAS_DATAFLASH +void at91_spi0_hw_init(unsigned long cs_mask) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_b_periph(AT91_PIO_PORTA, 0, 0); /* SPI0_MISO */ + at91_set_b_periph(AT91_PIO_PORTA, 1, 0); /* SPI0_MOSI */ + at91_set_b_periph(AT91_PIO_PORTA, 2, 0); /* SPI0_SPCK */ + + /* Enable clock */ + writel(1 << AT91CAP9_ID_SPI0, &pmc->pcer); + + if (cs_mask & (1 << 0)) { + at91_set_b_periph(AT91_PIO_PORTA, 5, 1); + } + if (cs_mask & (1 << 1)) { + at91_set_b_periph(AT91_PIO_PORTA, 3, 1); + } + if (cs_mask & (1 << 2)) { + at91_set_b_periph(AT91_PIO_PORTD, 0, 1); + } + if (cs_mask & (1 << 3)) { + at91_set_b_periph(AT91_PIO_PORTD, 1, 1); + } + if (cs_mask & (1 << 4)) { + at91_set_pio_output(AT91_PIO_PORTA, 5, 1); + } + if (cs_mask & (1 << 5)) { + at91_set_pio_output(AT91_PIO_PORTA, 3, 1); + } + if (cs_mask & (1 << 6)) { + at91_set_pio_output(AT91_PIO_PORTD, 0, 1); + } + if (cs_mask & (1 << 7)) { + at91_set_pio_output(AT91_PIO_PORTD, 1, 1); + } +} + +void at91_spi1_hw_init(unsigned long cs_mask) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTB, 12, 0); /* SPI1_MISO */ + at91_set_a_periph(AT91_PIO_PORTB, 13, 0); /* SPI1_MOSI */ + at91_set_a_periph(AT91_PIO_PORTB, 14, 0); /* SPI1_SPCK */ + + /* Enable clock */ + writel(1 << AT91CAP9_ID_SPI1, &pmc->pcer); + + if (cs_mask & (1 << 0)) { + at91_set_a_periph(AT91_PIO_PORTB, 15, 1); + } + if (cs_mask & (1 << 1)) { + at91_set_a_periph(AT91_PIO_PORTB, 16, 1); + } + if (cs_mask & (1 << 2)) { + at91_set_a_periph(AT91_PIO_PORTB, 17, 1); + } + if (cs_mask & (1 << 3)) { + at91_set_a_periph(AT91_PIO_PORTB, 18, 1); + } + if (cs_mask & (1 << 4)) { + at91_set_pio_output(AT91_PIO_PORTB, 15, 1); + } + if (cs_mask & (1 << 5)) { + at91_set_pio_output(AT91_PIO_PORTB, 16, 1); + } + if (cs_mask & (1 << 6)) { + at91_set_pio_output(AT91_PIO_PORTB, 17, 1); + } + if (cs_mask & (1 << 7)) { + at91_set_pio_output(AT91_PIO_PORTB, 18, 1); + } + +} +#endif + +#ifdef CONFIG_MACB +void at91_macb_hw_init(void) +{ + at91_set_a_periph(AT91_PIO_PORTB, 21, 0); /* ETXCK_EREFCK */ + at91_set_a_periph(AT91_PIO_PORTB, 22, 0); /* ERXDV */ + at91_set_a_periph(AT91_PIO_PORTB, 25, 0); /* ERX0 */ + at91_set_a_periph(AT91_PIO_PORTB, 26, 0); /* ERX1 */ + at91_set_a_periph(AT91_PIO_PORTB, 27, 0); /* ERXER */ + at91_set_a_periph(AT91_PIO_PORTB, 28, 0); /* ETXEN */ + at91_set_a_periph(AT91_PIO_PORTB, 23, 0); /* ETX0 */ + at91_set_a_periph(AT91_PIO_PORTB, 24, 0); /* ETX1 */ + at91_set_a_periph(AT91_PIO_PORTB, 30, 0); /* EMDIO */ + at91_set_a_periph(AT91_PIO_PORTB, 29, 0); /* EMDC */ + +#ifndef CONFIG_RMII + at91_set_b_periph(AT91_PIO_PORTC, 25, 0); /* ECRS */ + at91_set_b_periph(AT91_PIO_PORTC, 26, 0); /* ECOL */ + at91_set_b_periph(AT91_PIO_PORTC, 22, 0); /* ERX2 */ + at91_set_b_periph(AT91_PIO_PORTC, 23, 0); /* ERX3 */ + at91_set_b_periph(AT91_PIO_PORTC, 27, 0); /* ERXCK */ + at91_set_b_periph(AT91_PIO_PORTC, 20, 0); /* ETX2 */ + at91_set_b_periph(AT91_PIO_PORTC, 21, 0); /* ETX3 */ + at91_set_b_periph(AT91_PIO_PORTC, 24, 0); /* ETXER */ +#endif +} +#endif + +#ifdef CONFIG_AT91_CAN +void at91_can_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTA, 12, 0); /* CAN_TX */ + at91_set_a_periph(AT91_PIO_PORTA, 13, 1); /* CAN_RX */ + + /* Enable clock */ + writel(1 << AT91CAP9_ID_CAN, &pmc->pcer); +} +#endif diff --git a/arch/arm/cpu/arm926ejs/at91/at91sam9260_devices.c b/arch/arm/cpu/arm926ejs/at91/at91sam9260_devices.c new file mode 100644 index 0000000000..77d49ab1c7 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/at91/at91sam9260_devices.c @@ -0,0 +1,196 @@ +/* + * (C) Copyright 2007-2008 + * Stelian Pop + * Lead Tech Design + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include + +void at91_serial0_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTB, 4, 1); /* TXD0 */ + at91_set_a_periph(AT91_PIO_PORTB, 5, 0); /* RXD0 */ + writel(1 << AT91SAM9260_ID_US0, &pmc->pcer); +} + +void at91_serial1_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTB, 6, 1); /* TXD1 */ + at91_set_a_periph(AT91_PIO_PORTB, 7, 0); /* RXD1 */ + writel(1 << AT91SAM9260_ID_US1, &pmc->pcer); +} + +void at91_serial2_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTB, 8, 1); /* TXD2 */ + at91_set_a_periph(AT91_PIO_PORTB, 9, 0); /* RXD2 */ + writel(1 << AT91SAM9260_ID_US2, &pmc->pcer); +} + +void at91_serial3_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTB, 14, 0); /* DRXD */ + at91_set_a_periph(AT91_PIO_PORTB, 15, 1); /* DTXD */ + writel(1 << AT91_ID_SYS, &pmc->pcer); +} + +void at91_serial_hw_init(void) +{ +#ifdef CONFIG_USART0 + at91_serial0_hw_init(); +#endif + +#ifdef CONFIG_USART1 + at91_serial1_hw_init(); +#endif + +#ifdef CONFIG_USART2 + at91_serial2_hw_init(); +#endif + +#ifdef CONFIG_USART3 /* DBGU */ + at91_serial3_hw_init(); +#endif +} + +#if defined(CONFIG_HAS_DATAFLASH) || defined(CONFIG_ATMEL_SPI) +void at91_spi0_hw_init(unsigned long cs_mask) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTA, 0, 0); /* SPI0_MISO */ + at91_set_a_periph(AT91_PIO_PORTA, 1, 0); /* SPI0_MOSI */ + at91_set_a_periph(AT91_PIO_PORTA, 2, 0); /* SPI0_SPCK */ + + /* Enable clock */ + writel(1 << AT91SAM9260_ID_SPI0, &pmc->pcer); + + if (cs_mask & (1 << 0)) { + at91_set_a_periph(AT91_PIO_PORTA, 3, 1); + } + if (cs_mask & (1 << 1)) { + at91_set_b_periph(AT91_PIO_PORTC, 11, 1); + } + if (cs_mask & (1 << 2)) { + at91_set_b_periph(AT91_PIO_PORTC, 16, 1); + } + if (cs_mask & (1 << 3)) { + at91_set_b_periph(AT91_PIO_PORTC, 17, 1); + } + if (cs_mask & (1 << 4)) { + at91_set_pio_output(AT91_PIO_PORTA, 3, 1); + } + if (cs_mask & (1 << 5)) { + at91_set_pio_output(AT91_PIO_PORTC, 11, 1); + } + if (cs_mask & (1 << 6)) { + at91_set_pio_output(AT91_PIO_PORTC, 16, 1); + } + if (cs_mask & (1 << 7)) { + at91_set_pio_output(AT91_PIO_PORTC, 17, 1); + } +} + +void at91_spi1_hw_init(unsigned long cs_mask) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTB, 0, 0); /* SPI1_MISO */ + at91_set_a_periph(AT91_PIO_PORTB, 1, 0); /* SPI1_MOSI */ + at91_set_a_periph(AT91_PIO_PORTB, 2, 0); /* SPI1_SPCK */ + + /* Enable clock */ + writel(1 << AT91SAM9260_ID_SPI1, &pmc->pcer); + + if (cs_mask & (1 << 0)) { + at91_set_a_periph(AT91_PIO_PORTB, 3, 1); + } + if (cs_mask & (1 << 1)) { + at91_set_b_periph(AT91_PIO_PORTC, 5, 1); + } + if (cs_mask & (1 << 2)) { + at91_set_b_periph(AT91_PIO_PORTC, 4, 1); + } + if (cs_mask & (1 << 3)) { + at91_set_pio_output(AT91_PIO_PORTC, 3, 1); + } + if (cs_mask & (1 << 4)) { + at91_set_pio_output(AT91_PIO_PORTB, 3, 1); + } + if (cs_mask & (1 << 5)) { + at91_set_pio_output(AT91_PIO_PORTC, 5, 1); + } + if (cs_mask & (1 << 6)) { + at91_set_pio_output(AT91_PIO_PORTC, 4, 1); + } + if (cs_mask & (1 << 7)) { + at91_set_pio_output(AT91_PIO_PORTC, 3, 1); + } +} +#endif + +#ifdef CONFIG_MACB +void at91_macb_hw_init(void) +{ + at91_set_a_periph(AT91_PIO_PORTA, 19, 0); /* ETXCK_EREFCK */ + at91_set_a_periph(AT91_PIO_PORTA, 17, 0); /* ERXDV */ + at91_set_a_periph(AT91_PIO_PORTA, 14, 0); /* ERX0 */ + at91_set_a_periph(AT91_PIO_PORTA, 15, 0); /* ERX1 */ + at91_set_a_periph(AT91_PIO_PORTA, 18, 0); /* ERXER */ + at91_set_a_periph(AT91_PIO_PORTA, 16, 0); /* ETXEN */ + at91_set_a_periph(AT91_PIO_PORTA, 12, 0); /* ETX0 */ + at91_set_a_periph(AT91_PIO_PORTA, 13, 0); /* ETX1 */ + at91_set_a_periph(AT91_PIO_PORTA, 21, 0); /* EMDIO */ + at91_set_a_periph(AT91_PIO_PORTA, 20, 0); /* EMDC */ + +#ifndef CONFIG_RMII + at91_set_b_periph(AT91_PIO_PORTA, 28, 0); /* ECRS */ + at91_set_b_periph(AT91_PIO_PORTA, 29, 0); /* ECOL */ + at91_set_b_periph(AT91_PIO_PORTA, 25, 0); /* ERX2 */ + at91_set_b_periph(AT91_PIO_PORTA, 26, 0); /* ERX3 */ + at91_set_b_periph(AT91_PIO_PORTA, 27, 0); /* ERXCK */ +#if defined(CONFIG_AT91SAM9260EK) || defined(CONFIG_AFEB9260) + /* + * use PA10, PA11 for ETX2, ETX3. + * PA23 and PA24 are for TWI EEPROM + */ + at91_set_b_periph(AT91_PIO_PORTA, 10, 0); /* ETX2 */ + at91_set_b_periph(AT91_PIO_PORTA, 11, 0); /* ETX3 */ +#else + at91_set_b_periph(AT91_PIO_PORTA, 23, 0); /* ETX2 */ + at91_set_b_periph(AT91_PIO_PORTA, 24, 0); /* ETX3 */ +#endif + at91_set_b_periph(AT91_PIO_PORTA, 22, 0); /* ETXER */ +#endif +} +#endif diff --git a/arch/arm/cpu/arm926ejs/at91/at91sam9261_devices.c b/arch/arm/cpu/arm926ejs/at91/at91sam9261_devices.c new file mode 100644 index 0000000000..b4353ef5cb --- /dev/null +++ b/arch/arm/cpu/arm926ejs/at91/at91sam9261_devices.c @@ -0,0 +1,160 @@ +/* + * (C) Copyright 2007-2008 + * Stelian Pop + * Lead Tech Design + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include + +void at91_serial0_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTC, 8, 1); /* TXD0 */ + at91_set_a_periph(AT91_PIO_PORTC, 9, 0); /* RXD0 */ + writel(1 << AT91SAM9261_ID_US0, &pmc->pcer); +} + +void at91_serial1_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTC, 12, 1); /* TXD1 */ + at91_set_a_periph(AT91_PIO_PORTC, 13, 0); /* RXD1 */ + writel(1 << AT91SAM9261_ID_US1, &pmc->pcer); +} + +void at91_serial2_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTC, 14, 1); /* TXD2 */ + at91_set_a_periph(AT91_PIO_PORTC, 15, 0); /* RXD2 */ + writel(1 << AT91SAM9261_ID_US2, &pmc->pcer); +} + +void at91_serial3_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTA, 9, 0); /* DRXD */ + at91_set_a_periph(AT91_PIO_PORTA, 10, 1); /* DTXD */ + writel(1 << AT91_ID_SYS, &pmc->pcer); +} + +void at91_serial_hw_init(void) +{ +#ifdef CONFIG_USART0 + at91_serial0_hw_init(); +#endif + +#ifdef CONFIG_USART1 + at91_serial1_hw_init(); +#endif + +#ifdef CONFIG_USART2 + at91_serial2_hw_init(); +#endif + +#ifdef CONFIG_USART3 /* DBGU */ + at91_serial3_hw_init(); +#endif +} + +#ifdef CONFIG_HAS_DATAFLASH +void at91_spi0_hw_init(unsigned long cs_mask) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTA, 0, 0); /* SPI0_MISO */ + at91_set_a_periph(AT91_PIO_PORTA, 1, 0); /* SPI0_MOSI */ + at91_set_a_periph(AT91_PIO_PORTA, 2, 0); /* SPI0_SPCK */ + + /* Enable clock */ + writel(1 << AT91SAM9261_ID_SPI0, &pmc->pcer); + + if (cs_mask & (1 << 0)) { + at91_set_a_periph(AT91_PIO_PORTA, 3, 1); + } + if (cs_mask & (1 << 1)) { + at91_set_a_periph(AT91_PIO_PORTA, 4, 1); + } + if (cs_mask & (1 << 2)) { + at91_set_a_periph(AT91_PIO_PORTA, 5, 1); + } + if (cs_mask & (1 << 3)) { + at91_set_a_periph(AT91_PIO_PORTA, 6, 1); + } + if (cs_mask & (1 << 4)) { + at91_set_pio_output(AT91_PIO_PORTA, 3, 1); + } + if (cs_mask & (1 << 5)) { + at91_set_pio_output(AT91_PIO_PORTA, 4, 1); + } + if (cs_mask & (1 << 6)) { + at91_set_pio_output(AT91_PIO_PORTA, 5, 1); + } + if (cs_mask & (1 << 7)) { + at91_set_pio_output(AT91_PIO_PORTA, 6, 1); + } +} + +void at91_spi1_hw_init(unsigned long cs_mask) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTB, 30, 0); /* SPI1_MISO */ + at91_set_a_periph(AT91_PIO_PORTB, 31, 0); /* SPI1_MOSI */ + at91_set_a_periph(AT91_PIO_PORTB, 29, 0); /* SPI1_SPCK */ + + /* Enable clock */ + writel(1 << AT91SAM9261_ID_SPI1, &pmc->pcer); + + if (cs_mask & (1 << 0)) { + at91_set_a_periph(AT91_PIO_PORTB, 28, 1); + } + if (cs_mask & (1 << 1)) { + at91_set_b_periph(AT91_PIO_PORTA, 24, 1); + } + if (cs_mask & (1 << 2)) { + at91_set_b_periph(AT91_PIO_PORTA, 25, 1); + } + if (cs_mask & (1 << 3)) { + at91_set_a_periph(AT91_PIO_PORTA, 26, 1); + } + if (cs_mask & (1 << 4)) { + at91_set_pio_output(AT91_PIO_PORTB, 28, 1); + } + if (cs_mask & (1 << 5)) { + at91_set_pio_output(AT91_PIO_PORTA, 24, 1); + } + if (cs_mask & (1 << 6)) { + at91_set_pio_output(AT91_PIO_PORTA, 25, 1); + } + if (cs_mask & (1 << 7)) { + at91_set_pio_output(AT91_PIO_PORTA, 26, 1); + } +} +#endif diff --git a/arch/arm/cpu/arm926ejs/at91/at91sam9263_devices.c b/arch/arm/cpu/arm926ejs/at91/at91sam9263_devices.c new file mode 100644 index 0000000000..deda3e54d9 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/at91/at91sam9263_devices.c @@ -0,0 +1,214 @@ +/* + * (C) Copyright 2007-2008 + * Stelian Pop + * Lead Tech Design + * + * (C) Copyright 2009 + * Daniel Gorsulowski + * esd electronic system design gmbh + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include + +void at91_serial0_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTA, 26, 1); /* TXD0 */ + at91_set_a_periph(AT91_PIO_PORTA, 27, 0); /* RXD0 */ + writel(1 << AT91SAM9263_ID_US0, &pmc->pcer); +} + +void at91_serial1_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTD, 0, 1); /* TXD1 */ + at91_set_a_periph(AT91_PIO_PORTD, 1, 0); /* RXD1 */ + writel(1 << AT91SAM9263_ID_US1, &pmc->pcer); +} + +void at91_serial2_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTD, 2, 1); /* TXD2 */ + at91_set_a_periph(AT91_PIO_PORTD, 3, 0); /* RXD2 */ + writel(1 << AT91SAM9263_ID_US2, &pmc->pcer); +} + +void at91_serial3_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTC, 30, 0); /* DRXD */ + at91_set_a_periph(AT91_PIO_PORTC, 31, 1); /* DTXD */ + writel(1 << AT91_ID_SYS, &pmc->pcer); +} + +void at91_serial_hw_init(void) +{ +#ifdef CONFIG_USART0 + at91_serial0_hw_init(); +#endif + +#ifdef CONFIG_USART1 + at91_serial1_hw_init(); +#endif + +#ifdef CONFIG_USART2 + at91_serial2_hw_init(); +#endif + +#ifdef CONFIG_USART3 /* DBGU */ + at91_serial3_hw_init(); +#endif +} + +#ifdef CONFIG_HAS_DATAFLASH +void at91_spi0_hw_init(unsigned long cs_mask) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_b_periph(AT91_PIO_PORTA, 0, 0); /* SPI0_MISO */ + at91_set_b_periph(AT91_PIO_PORTA, 1, 0); /* SPI0_MOSI */ + at91_set_b_periph(AT91_PIO_PORTA, 2, 0); /* SPI0_SPCK */ + + /* Enable clock */ + writel(1 << AT91SAM9263_ID_SPI0, &pmc->pcer); + + if (cs_mask & (1 << 0)) { + at91_set_b_periph(AT91_PIO_PORTA, 5, 1); + } + if (cs_mask & (1 << 1)) { + at91_set_b_periph(AT91_PIO_PORTA, 3, 1); + } + if (cs_mask & (1 << 2)) { + at91_set_b_periph(AT91_PIO_PORTA, 4, 1); + } + if (cs_mask & (1 << 3)) { + at91_set_b_periph(AT91_PIO_PORTB, 11, 1); + } + if (cs_mask & (1 << 4)) { + at91_set_pio_output(AT91_PIO_PORTA, 5, 1); + } + if (cs_mask & (1 << 5)) { + at91_set_pio_output(AT91_PIO_PORTA, 3, 1); + } + if (cs_mask & (1 << 6)) { + at91_set_pio_output(AT91_PIO_PORTA, 4, 1); + } + if (cs_mask & (1 << 7)) { + at91_set_pio_output(AT91_PIO_PORTB, 11, 1); + } +} + +void at91_spi1_hw_init(unsigned long cs_mask) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTB, 12, 0); /* SPI1_MISO */ + at91_set_a_periph(AT91_PIO_PORTB, 13, 0); /* SPI1_MOSI */ + at91_set_a_periph(AT91_PIO_PORTB, 14, 0); /* SPI1_SPCK */ + + /* Enable clock */ + writel(1 << AT91SAM9263_ID_SPI1, &pmc->pcer); + + if (cs_mask & (1 << 0)) { + at91_set_a_periph(AT91_PIO_PORTB, 15, 1); + } + if (cs_mask & (1 << 1)) { + at91_set_a_periph(AT91_PIO_PORTB, 16, 1); + } + if (cs_mask & (1 << 2)) { + at91_set_a_periph(AT91_PIO_PORTB, 17, 1); + } + if (cs_mask & (1 << 3)) { + at91_set_a_periph(AT91_PIO_PORTB, 18, 1); + } + if (cs_mask & (1 << 4)) { + at91_set_pio_output(AT91_PIO_PORTB, 15, 1); + } + if (cs_mask & (1 << 5)) { + at91_set_pio_output(AT91_PIO_PORTB, 16, 1); + } + if (cs_mask & (1 << 6)) { + at91_set_pio_output(AT91_PIO_PORTB, 17, 1); + } + if (cs_mask & (1 << 7)) { + at91_set_pio_output(AT91_PIO_PORTB, 18, 1); + } +} +#endif + +#ifdef CONFIG_MACB +void at91_macb_hw_init(void) +{ + at91_set_a_periph(AT91_PIO_PORTE, 21, 0); /* ETXCK_EREFCK */ + at91_set_b_periph(AT91_PIO_PORTC, 25, 0); /* ERXDV */ + at91_set_a_periph(AT91_PIO_PORTE, 25, 0); /* ERX0 */ + at91_set_a_periph(AT91_PIO_PORTE, 26, 0); /* ERX1 */ + at91_set_a_periph(AT91_PIO_PORTE, 27, 0); /* ERXER */ + at91_set_a_periph(AT91_PIO_PORTE, 28, 0); /* ETXEN */ + at91_set_a_periph(AT91_PIO_PORTE, 23, 0); /* ETX0 */ + at91_set_a_periph(AT91_PIO_PORTE, 24, 0); /* ETX1 */ + at91_set_a_periph(AT91_PIO_PORTE, 30, 0); /* EMDIO */ + at91_set_a_periph(AT91_PIO_PORTE, 29, 0); /* EMDC */ + +#ifndef CONFIG_RMII + at91_set_a_periph(AT91_PIO_PORTE, 22, 0); /* ECRS */ + at91_set_b_periph(AT91_PIO_PORTC, 26, 0); /* ECOL */ + at91_set_b_periph(AT91_PIO_PORTC, 22, 0); /* ERX2 */ + at91_set_b_periph(AT91_PIO_PORTC, 23, 0); /* ERX3 */ + at91_set_b_periph(AT91_PIO_PORTC, 27, 0); /* ERXCK */ + at91_set_b_periph(AT91_PIO_PORTC, 20, 0); /* ETX2 */ + at91_set_b_periph(AT91_PIO_PORTC, 21, 0); /* ETX3 */ + at91_set_b_periph(AT91_PIO_PORTC, 24, 0); /* ETXER */ +#endif +} +#endif + +#ifdef CONFIG_USB_OHCI_NEW +void at91_uhp_hw_init(void) +{ + /* Enable VBus on UHP ports */ + at91_set_pio_output(AT91_PIO_PORTA, 21, 0); + at91_set_pio_output(AT91_PIO_PORTA, 24, 0); +} +#endif + +#ifdef CONFIG_AT91_CAN +void at91_can_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTA, 13, 0); /* CAN_TX */ + at91_set_a_periph(AT91_PIO_PORTA, 14, 1); /* CAN_RX */ + + /* Enable clock */ + writel(1 << AT91SAM9263_ID_CAN, &pmc->pcer); +} +#endif diff --git a/arch/arm/cpu/arm926ejs/at91/at91sam9m10g45_devices.c b/arch/arm/cpu/arm926ejs/at91/at91sam9m10g45_devices.c new file mode 100644 index 0000000000..4ad9b1fcc9 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/at91/at91sam9m10g45_devices.c @@ -0,0 +1,187 @@ +/* + * (C) Copyright 2007-2008 + * Stelian Pop + * Lead Tech Design + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include + +void at91_serial0_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTB, 19, 1); /* TXD0 */ + at91_set_a_periph(AT91_PIO_PORTB, 18, 0); /* RXD0 */ + writel(1 << AT91SAM9G45_ID_US0, &pmc->pcer); +} + +void at91_serial1_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTB, 4, 1); /* TXD1 */ + at91_set_a_periph(AT91_PIO_PORTB, 5, 0); /* RXD1 */ + writel(1 << AT91SAM9G45_ID_US1, &pmc->pcer); +} + +void at91_serial2_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTD, 6, 1); /* TXD2 */ + at91_set_a_periph(AT91_PIO_PORTD, 7, 0); /* RXD2 */ + writel(1 << AT91SAM9G45_ID_US2, &pmc->pcer); +} + +void at91_serial3_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTB, 12, 0); /* DRXD */ + at91_set_a_periph(AT91_PIO_PORTB, 13, 1); /* DTXD */ + writel(1 << AT91_ID_SYS, &pmc->pcer); +} + +void at91_serial_hw_init(void) +{ +#ifdef CONFIG_USART0 + at91_serial0_hw_init(); +#endif + +#ifdef CONFIG_USART1 + at91_serial1_hw_init(); +#endif + +#ifdef CONFIG_USART2 + at91_serial2_hw_init(); +#endif + +#ifdef CONFIG_USART3 /* DBGU */ + at91_serial3_hw_init(); +#endif +} + +#ifdef CONFIG_ATMEL_SPI +void at91_spi0_hw_init(unsigned long cs_mask) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTB, 0, 0); /* SPI0_MISO */ + at91_set_a_periph(AT91_PIO_PORTB, 1, 0); /* SPI0_MOSI */ + at91_set_a_periph(AT91_PIO_PORTB, 2, 0); /* SPI0_SPCK */ + + /* Enable clock */ + writel(1 << AT91SAM9G45_ID_SPI0, &pmc->pcer); + + if (cs_mask & (1 << 0)) { + at91_set_a_periph(AT91_PIO_PORTB, 3, 0); + } + if (cs_mask & (1 << 1)) { + at91_set_b_periph(AT91_PIO_PORTB, 18, 0); + } + if (cs_mask & (1 << 2)) { + at91_set_b_periph(AT91_PIO_PORTB, 19, 0); + } + if (cs_mask & (1 << 3)) { + at91_set_b_periph(AT91_PIO_PORTD, 27, 0); + } + if (cs_mask & (1 << 4)) { + at91_set_pio_output(AT91_PIO_PORTB, 3, 0); + } + if (cs_mask & (1 << 5)) { + at91_set_pio_output(AT91_PIO_PORTB, 18, 0); + } + if (cs_mask & (1 << 6)) { + at91_set_pio_output(AT91_PIO_PORTB, 19, 0); + } + if (cs_mask & (1 << 7)) { + at91_set_pio_output(AT91_PIO_PORTD, 27, 0); + } +} + +void at91_spi1_hw_init(unsigned long cs_mask) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTB, 14, 0); /* SPI1_MISO */ + at91_set_a_periph(AT91_PIO_PORTB, 15, 0); /* SPI1_MOSI */ + at91_set_a_periph(AT91_PIO_PORTB, 16, 0); /* SPI1_SPCK */ + + /* Enable clock */ + writel(1 << AT91SAM9G45_ID_SPI1, &pmc->pcer); + + if (cs_mask & (1 << 0)) { + at91_set_a_periph(AT91_PIO_PORTB, 17, 0); + } + if (cs_mask & (1 << 1)) { + at91_set_b_periph(AT91_PIO_PORTD, 28, 0); + } + if (cs_mask & (1 << 2)) { + at91_set_a_periph(AT91_PIO_PORTD, 18, 0); + } + if (cs_mask & (1 << 3)) { + at91_set_a_periph(AT91_PIO_PORTD, 19, 0); + } + if (cs_mask & (1 << 4)) { + at91_set_pio_output(AT91_PIO_PORTB, 17, 0); + } + if (cs_mask & (1 << 5)) { + at91_set_pio_output(AT91_PIO_PORTD, 28, 0); + } + if (cs_mask & (1 << 6)) { + at91_set_pio_output(AT91_PIO_PORTD, 18, 0); + } + if (cs_mask & (1 << 7)) { + at91_set_pio_output(AT91_PIO_PORTD, 19, 0); + } + +} +#endif + +#ifdef CONFIG_MACB +void at91_macb_hw_init(void) +{ + at91_set_a_periph(AT91_PIO_PORTA, 17, 0); /* ETXCK_EREFCK */ + at91_set_a_periph(AT91_PIO_PORTA, 15, 0); /* ERXDV */ + at91_set_a_periph(AT91_PIO_PORTA, 12, 0); /* ERX0 */ + at91_set_a_periph(AT91_PIO_PORTA, 13, 0); /* ERX1 */ + at91_set_a_periph(AT91_PIO_PORTA, 16, 0); /* ERXER */ + at91_set_a_periph(AT91_PIO_PORTA, 14, 0); /* ETXEN */ + at91_set_a_periph(AT91_PIO_PORTA, 10, 0); /* ETX0 */ + at91_set_a_periph(AT91_PIO_PORTA, 11, 0); /* ETX1 */ + at91_set_a_periph(AT91_PIO_PORTA, 19, 0); /* EMDIO */ + at91_set_a_periph(AT91_PIO_PORTA, 18, 0); /* EMDC */ +#ifndef CONFIG_RMII + at91_set_b_periph(AT91_PIO_PORTA, 29, 0); /* ECRS */ + at91_set_b_periph(AT91_PIO_PORTA, 30, 0); /* ECOL */ + at91_set_b_periph(AT91_PIO_PORTA, 8, 0); /* ERX2 */ + at91_set_b_periph(AT91_PIO_PORTA, 9, 0); /* ERX3 */ + at91_set_b_periph(AT91_PIO_PORTA, 28, 0); /* ERXCK */ + at91_set_b_periph(AT91_PIO_PORTA, 6, 0); /* ETX2 */ + at91_set_b_periph(AT91_PIO_PORTA, 7, 0); /* ETX3 */ + at91_set_b_periph(AT91_PIO_PORTA, 27, 0); /* ETXER */ +#endif +} +#endif diff --git a/arch/arm/cpu/arm926ejs/at91/at91sam9rl_devices.c b/arch/arm/cpu/arm926ejs/at91/at91sam9rl_devices.c new file mode 100644 index 0000000000..4f570f4fb5 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/at91/at91sam9rl_devices.c @@ -0,0 +1,123 @@ +/* + * (C) Copyright 2007-2008 + * Stelian Pop + * Lead Tech Design + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include + +void at91_serial0_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTA, 6, 1); /* TXD0 */ + at91_set_a_periph(AT91_PIO_PORTA, 7, 0); /* RXD0 */ + writel(1 << AT91SAM9RL_ID_US0, &pmc->pcer); +} + +void at91_serial1_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTA, 11, 1); /* TXD1 */ + at91_set_a_periph(AT91_PIO_PORTA, 12, 0); /* RXD1 */ + writel(1 << AT91SAM9RL_ID_US1, &pmc->pcer); +} + +void at91_serial2_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTA, 13, 1); /* TXD2 */ + at91_set_a_periph(AT91_PIO_PORTA, 14, 0); /* RXD2 */ + writel(1 << AT91SAM9RL_ID_US2, &pmc->pcer); +} + +void at91_serial3_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTA, 21, 0); /* DRXD */ + at91_set_a_periph(AT91_PIO_PORTA, 22, 1); /* DTXD */ + writel(1 << AT91_ID_SYS, &pmc->pcer); +} + +void at91_serial_hw_init(void) +{ +#ifdef CONFIG_USART0 + at91_serial0_hw_init(); +#endif + +#ifdef CONFIG_USART1 + at91_serial1_hw_init(); +#endif + +#ifdef CONFIG_USART2 + at91_serial2_hw_init(); +#endif + +#ifdef CONFIG_USART3 /* DBGU */ + at91_serial3_hw_init(); +#endif +} + +#ifdef CONFIG_HAS_DATAFLASH +void at91_spi0_hw_init(unsigned long cs_mask) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + + at91_set_a_periph(AT91_PIO_PORTA, 25, 0); /* SPI0_MISO */ + at91_set_a_periph(AT91_PIO_PORTA, 26, 0); /* SPI0_MOSI */ + at91_set_a_periph(AT91_PIO_PORTA, 27, 0); /* SPI0_SPCK */ + + /* Enable clock */ + writel(1 << AT91SAM9RL_ID_SPI, &pmc->pcer); + + if (cs_mask & (1 << 0)) { + at91_set_a_periph(AT91_PIO_PORTA, 28, 1); + } + if (cs_mask & (1 << 1)) { + at91_set_b_periph(AT91_PIO_PORTB, 7, 1); + } + if (cs_mask & (1 << 2)) { + at91_set_a_periph(AT91_PIO_PORTD, 8, 1); + } + if (cs_mask & (1 << 3)) { + at91_set_b_periph(AT91_PIO_PORTD, 9, 1); + } + if (cs_mask & (1 << 4)) { + at91_set_pio_output(AT91_PIO_PORTA, 28, 1); + } + if (cs_mask & (1 << 5)) { + at91_set_pio_output(AT91_PIO_PORTB, 7, 1); + } + if (cs_mask & (1 << 6)) { + at91_set_pio_output(AT91_PIO_PORTD, 8, 1); + } + if (cs_mask & (1 << 7)) { + at91_set_pio_output(AT91_PIO_PORTD, 9, 1); + } +} +#endif diff --git a/arch/arm/cpu/arm926ejs/at91/clock.c b/arch/arm/cpu/arm926ejs/at91/clock.c new file mode 100644 index 0000000000..ecf91f5187 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/at91/clock.c @@ -0,0 +1,216 @@ +/* + * [origin: Linux kernel linux/arch/arm/mach-at91/clock.c] + * + * Copyright (C) 2005 David Brownell + * Copyright (C) 2005 Ivan Kokshaysky + * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include + +static unsigned long cpu_clk_rate_hz; +static unsigned long main_clk_rate_hz; +static unsigned long mck_rate_hz; +static unsigned long plla_rate_hz; +static unsigned long pllb_rate_hz; +static u32 at91_pllb_usb_init; + +unsigned long get_cpu_clk_rate(void) +{ + return cpu_clk_rate_hz; +} + +unsigned long get_main_clk_rate(void) +{ + return main_clk_rate_hz; +} + +unsigned long get_mck_clk_rate(void) +{ + return mck_rate_hz; +} + +unsigned long get_plla_clk_rate(void) +{ + return plla_rate_hz; +} + +unsigned long get_pllb_clk_rate(void) +{ + return pllb_rate_hz; +} + +u32 get_pllb_init(void) +{ + return at91_pllb_usb_init; +} + +static unsigned long at91_css_to_rate(unsigned long css) +{ + switch (css) { + case AT91_PMC_MCKR_CSS_SLOW: + return AT91_SLOW_CLOCK; + case AT91_PMC_MCKR_CSS_MAIN: + return main_clk_rate_hz; + case AT91_PMC_MCKR_CSS_PLLA: + return plla_rate_hz; + case AT91_PMC_MCKR_CSS_PLLB: + return pllb_rate_hz; + } + + return 0; +} + +#ifdef CONFIG_USB_ATMEL +static unsigned at91_pll_calc(unsigned main_freq, unsigned out_freq) +{ + unsigned i, div = 0, mul = 0, diff = 1 << 30; + unsigned ret = (out_freq > 155000000) ? 0xbe00 : 0x3e00; + + /* PLL output max 240 MHz (or 180 MHz per errata) */ + if (out_freq > 240000000) + goto fail; + + for (i = 1; i < 256; i++) { + int diff1; + unsigned input, mul1; + + /* + * PLL input between 1MHz and 32MHz per spec, but lower + * frequences seem necessary in some cases so allow 100K. + * Warning: some newer products need 2MHz min. + */ + input = main_freq / i; +#if defined(CONFIG_AT91SAM9G20) + if (input < 2000000) + continue; +#endif + if (input < 100000) + continue; + if (input > 32000000) + continue; + + mul1 = out_freq / input; +#if defined(CONFIG_AT91SAM9G20) + if (mul > 63) + continue; +#endif + if (mul1 > 2048) + continue; + if (mul1 < 2) + goto fail; + + diff1 = out_freq - input * mul1; + if (diff1 < 0) + diff1 = -diff1; + if (diff > diff1) { + diff = diff1; + div = i; + mul = mul1; + if (diff == 0) + break; + } + } + if (i == 256 && diff > (out_freq >> 5)) + goto fail; + return ret | ((mul - 1) << 16) | div; +fail: + return 0; +} +#endif + +static u32 at91_pll_rate(u32 freq, u32 reg) +{ + unsigned mul, div; + + div = reg & 0xff; + mul = (reg >> 16) & 0x7ff; + if (div && mul) { + freq /= div; + freq *= mul + 1; + } else + freq = 0; + + return freq; +} + +int at91_clock_init(unsigned long main_clock) +{ + unsigned freq, mckr; + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; +#ifndef CONFIG_SYS_AT91_MAIN_CLOCK + unsigned tmp; + /* + * When the bootloader initialized the main oscillator correctly, + * there's no problem using the cycle counter. But if it didn't, + * or when using oscillator bypass mode, we must be told the speed + * of the main clock. + */ + if (!main_clock) { + do { + tmp = readl(&pmc->mcfr); + } while (!(tmp & AT91_PMC_MCFR_MAINRDY)); + tmp &= AT91_PMC_MCFR_MAINF_MASK; + main_clock = tmp * (AT91_SLOW_CLOCK / 16); + } +#endif + main_clk_rate_hz = main_clock; + + /* report if PLLA is more than mildly overclocked */ + plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar)); + +#ifdef CONFIG_USB_ATMEL + /* + * USB clock init: choose 48 MHz PLLB value, + * disable 48MHz clock during usb peripheral suspend. + * + * REVISIT: assumes MCK doesn't derive from PLLB! + */ + at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | + AT91_PMC_PLLBR_USBDIV_2; + pllb_rate_hz = at91_pll_rate(main_clock, at91_pllb_usb_init); +#endif + + /* + * MCK and CPU derive from one of those primary clocks. + * For now, assume this parentage won't change. + */ + mckr = readl(&pmc->mckr); +#if defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) + /* plla divisor by 2 */ + plla_rate_hz /= (1 << ((mckr & 1 << 12) >> 12)); +#endif + mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK); + freq = mck_rate_hz; + + freq /= (1 << ((mckr & AT91_PMC_MCKR_PRES_MASK) >> 2)); /* prescale */ +#if defined(CONFIG_AT91RM9200) + /* mdiv */ + mck_rate_hz = freq / (1 + ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8)); +#elif defined(CONFIG_AT91SAM9G20) + /* mdiv ; (x >> 7) = ((x >> 8) * 2) */ + mck_rate_hz = (mckr & AT91_PMC_MCKR_MDIV_MASK) ? + freq / ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 7) : freq; + if (mckr & AT91_PMC_MCKR_MDIV_MASK) + freq /= 2; /* processor clock division */ +#elif defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) + mck_rate_hz = (mckr & AT91_PMC_MCKR_MDIV_MASK) == + (AT91_PMC_MCKR_MDIV_2 | AT91_PMC_MCKR_MDIV_4) + ? freq / 3 + : freq / (1 << ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8)); +#else + mck_rate_hz = freq / (1 << ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8)); +#endif + cpu_clk_rate_hz = freq; + + return 0; +} diff --git a/arch/arm/cpu/arm926ejs/at91/config.mk b/arch/arm/cpu/arm926ejs/at91/config.mk new file mode 100644 index 0000000000..19296fdba2 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/at91/config.mk @@ -0,0 +1 @@ +PLATFORM_CPPFLAGS += $(call cc-option,-mtune=arm926ejs,) diff --git a/arch/arm/cpu/arm926ejs/at91/cpu.c b/arch/arm/cpu/arm926ejs/at91/cpu.c new file mode 100644 index 0000000000..141a7d1ec6 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/at91/cpu.c @@ -0,0 +1,92 @@ +/* + * (C) Copyright 2009 + * Jean-Christophe PLAGNIOL-VILLARD + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#ifdef CONFIG_AT91_LEGACY +#warning Your board is using legacy SoC access. Please update! +#endif + +#include +#include +#include +#include + +#ifndef CONFIG_SYS_AT91_MAIN_CLOCK +#define CONFIG_SYS_AT91_MAIN_CLOCK 0 +#endif + +/* + * The at91sam9260 has 4 GPBR (0-3), we'll use the last one, nr 3, + * to keep track of the bootcount. + */ +#define AT91_GPBR_BOOTCOUNT_REGISTER 3 +#define AT91_BOOTCOUNT_ADDRESS (AT91_GPBR + 4*AT91_GPBR_BOOTCOUNT_REGISTER) + +int arch_cpu_init(void) +{ + return at91_clock_init(CONFIG_SYS_AT91_MAIN_CLOCK); +} + +#if defined(CONFIG_DISPLAY_CPUINFO) +int print_cpuinfo(void) +{ + char buf[32]; + + printf("CPU: %s\n", CONFIG_SYS_AT91_CPU_NAME); + printf("Crystal frequency: %8s MHz\n", + strmhz(buf, get_main_clk_rate())); + printf("CPU clock : %8s MHz\n", + strmhz(buf, get_cpu_clk_rate())); + printf("Master clock : %8s MHz\n", + strmhz(buf, get_mck_clk_rate())); + + return 0; +} +#endif + +#ifdef CONFIG_BOOTCOUNT_LIMIT +/* + * Just as the mpc5xxx, we combine the BOOTCOUNT_MAGIC and boocount + * in one 32-bit register. This is done, as the AT91SAM9260 only has + * 4 GPBR. + */ +void bootcount_store (ulong a) +{ + volatile ulong *save_addr = + (volatile ulong *)(AT91_BASE_SYS + AT91_BOOTCOUNT_ADDRESS); + + *save_addr = (BOOTCOUNT_MAGIC & 0xffff0000) | (a & 0x0000ffff); +} + +ulong bootcount_load (void) +{ + volatile ulong *save_addr = + (volatile ulong *)(AT91_BASE_SYS + AT91_BOOTCOUNT_ADDRESS); + + if ((*save_addr & 0xffff0000) != (BOOTCOUNT_MAGIC & 0xffff0000)) + return 0; + else + return (*save_addr & 0x0000ffff); +} + +#endif /* CONFIG_BOOTCOUNT_LIMIT */ diff --git a/arch/arm/cpu/arm926ejs/at91/led.c b/arch/arm/cpu/arm926ejs/at91/led.c new file mode 100644 index 0000000000..0a315c4971 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/at91/led.c @@ -0,0 +1,65 @@ +/* + * (C) Copyright 2007-2008 + * Stelian Pop + * Lead Tech Design + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include + +#ifdef CONFIG_RED_LED +void red_LED_on(void) +{ + at91_set_gpio_value(CONFIG_RED_LED, 1); +} + +void red_LED_off(void) +{ + at91_set_gpio_value(CONFIG_RED_LED, 0); +} +#endif + +#ifdef CONFIG_GREEN_LED +void green_LED_on(void) +{ + at91_set_gpio_value(CONFIG_GREEN_LED, 0); +} + +void green_LED_off(void) +{ + at91_set_gpio_value(CONFIG_GREEN_LED, 1); +} +#endif + +#ifdef CONFIG_YELLOW_LED +void yellow_LED_on(void) +{ + at91_set_gpio_value(CONFIG_YELLOW_LED, 0); +} + +void yellow_LED_off(void) +{ + at91_set_gpio_value(CONFIG_YELLOW_LED, 1); +} +#endif diff --git a/arch/arm/cpu/arm926ejs/at91/lowlevel_init.S b/arch/arm/cpu/arm926ejs/at91/lowlevel_init.S new file mode 100644 index 0000000000..559c35c9ee --- /dev/null +++ b/arch/arm/cpu/arm926ejs/at91/lowlevel_init.S @@ -0,0 +1,274 @@ +/* + * Memory Setup stuff - taken from blob memsetup.S + * + * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and + * Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl) + * + * Copyright (C) 2008 Ronetix Ilko Iliev (www.ronetix.at) + * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_AT91_LEGACY +#include +#endif +#ifndef CONFIG_SYS_MATRIX_EBICSA_VAL +#define CONFIG_SYS_MATRIX_EBICSA_VAL CONFIG_SYS_MATRIX_EBI0CSA_VAL +#endif + +_TEXT_BASE: + .word TEXT_BASE + +.globl lowlevel_init +.type lowlevel_init,function +lowlevel_init: + + mov r5, pc /* r5 = POS1 + 4 current */ +POS1: + ldr r0, =POS1 /* r0 = POS1 compile */ + ldr r2, _TEXT_BASE + sub r0, r0, r2 /* r0 = POS1-_TEXT_BASE (POS1 relative) */ + sub r5, r5, r0 /* r0 = TEXT_BASE-1 */ + sub r5, r5, #4 /* r1 = text base - current */ + + /* memory control configuration 1 */ + ldr r0, =SMRDATA + ldr r2, =SMRDATA1 + ldr r1, _TEXT_BASE + sub r0, r0, r1 + sub r2, r2, r1 + add r0, r0, r5 + add r2, r2, r5 +0: + /* the address */ + ldr r1, [r0], #4 + /* the value */ + ldr r3, [r0], #4 + str r3, [r1] + cmp r2, r0 + bne 0b + +/* ---------------------------------------------------------------------------- + * PMC Init Step 1. + * ---------------------------------------------------------------------------- + * - Check if the PLL is already initialized + * ---------------------------------------------------------------------------- + */ + ldr r1, =(AT91_ASM_PMC_MCKR) + ldr r0, [r1] + and r0, r0, #3 + cmp r0, #0 + bne PLL_setup_end + +/* --------------------------------------------------------------------------- + * - Enable the Main Oscillator + * --------------------------------------------------------------------------- + */ + ldr r1, =(AT91_ASM_PMC_MOR) + ldr r2, =(AT91_ASM_PMC_SR) + /* Main oscillator Enable register PMC_MOR: */ + ldr r0, =CONFIG_SYS_MOR_VAL + str r0, [r1] + + /* Reading the PMC Status to detect when the Main Oscillator is enabled */ + mov r4, #AT91_PMC_IXR_MOSCS +MOSCS_Loop: + ldr r3, [r2] + and r3, r4, r3 + cmp r3, #AT91_PMC_IXR_MOSCS + bne MOSCS_Loop + +/* ---------------------------------------------------------------------------- + * PMC Init Step 2. + * ---------------------------------------------------------------------------- + * Setup PLLA + * ---------------------------------------------------------------------------- + */ + ldr r1, =(AT91_ASM_PMC_PLLAR) + ldr r0, =CONFIG_SYS_PLLAR_VAL + str r0, [r1] + + /* Reading the PMC Status register to detect when the PLLA is locked */ + mov r4, #AT91_PMC_IXR_LOCKA +MOSCS_Loop1: + ldr r3, [r2] + and r3, r4, r3 + cmp r3, #AT91_PMC_IXR_LOCKA + bne MOSCS_Loop1 + +/* ---------------------------------------------------------------------------- + * PMC Init Step 3. + * ---------------------------------------------------------------------------- + * - Switch on the Main Oscillator + * ---------------------------------------------------------------------------- + */ + ldr r1, =(AT91_ASM_PMC_MCKR) + + /* -Master Clock Controller register PMC_MCKR */ + ldr r0, =CONFIG_SYS_MCKR1_VAL + str r0, [r1] + + /* Reading the PMC Status to detect when the Master clock is ready */ + mov r4, #AT91_PMC_IXR_MCKRDY +MCKRDY_Loop: + ldr r3, [r2] + and r3, r4, r3 + cmp r3, #AT91_PMC_IXR_MCKRDY + bne MCKRDY_Loop + + ldr r0, =CONFIG_SYS_MCKR2_VAL + str r0, [r1] + + /* Reading the PMC Status to detect when the Master clock is ready */ + mov r4, #AT91_PMC_IXR_MCKRDY +MCKRDY_Loop1: + ldr r3, [r2] + and r3, r4, r3 + cmp r3, #AT91_PMC_IXR_MCKRDY + bne MCKRDY_Loop1 +PLL_setup_end: + +/* ---------------------------------------------------------------------------- + * - memory control configuration 2 + * ---------------------------------------------------------------------------- + */ + ldr r0, =(AT91_ASM_SDRAMC_TR) + ldr r1, [r0] + cmp r1, #0 + bne SDRAM_setup_end + + ldr r0, =SMRDATA1 + ldr r2, =SMRDATA2 + ldr r1, _TEXT_BASE + sub r0, r0, r1 + sub r2, r2, r1 + add r0, r0, r5 + add r2, r2, r5 +2: + /* the address */ + ldr r1, [r0], #4 + /* the value */ + ldr r3, [r0], #4 + str r3, [r1] + cmp r2, r0 + bne 2b + +SDRAM_setup_end: + /* everything is fine now */ + mov pc, lr + + .ltorg + +SMRDATA: + .word AT91_ASM_WDT_MR + .word CONFIG_SYS_WDTC_WDMR_VAL + /* configure PIOx as EBI0 D[16-31] */ +#if defined(CONFIG_AT91SAM9263) + .word AT91_ASM_PIOD_PDR + .word CONFIG_SYS_PIOD_PDR_VAL1 + .word AT91_ASM_PIOD_PUDR + .word CONFIG_SYS_PIOD_PPUDR_VAL + .word AT91_ASM_PIOD_ASR + .word CONFIG_SYS_PIOD_PPUDR_VAL +#elif defined(CONFIG_AT91SAM9260) || defined(CONFIG_AT91SAM9261) \ + || defined(CONFIG_AT91SAM9G20) + .word AT91_ASM_PIOC_PDR + .word CONFIG_SYS_PIOC_PDR_VAL1 + .word AT91_ASM_PIOC_PUDR + .word CONFIG_SYS_PIOC_PPUDR_VAL +#endif + .word AT91_ASM_MATRIX_CSA0 + .word CONFIG_SYS_MATRIX_EBICSA_VAL + + /* flash */ + .word AT91_ASM_SMC_MODE0 + .word CONFIG_SYS_SMC0_MODE0_VAL + + .word AT91_ASM_SMC_CYCLE0 + .word CONFIG_SYS_SMC0_CYCLE0_VAL + + .word AT91_ASM_SMC_PULSE0 + .word CONFIG_SYS_SMC0_PULSE0_VAL + + .word AT91_ASM_SMC_SETUP0 + .word CONFIG_SYS_SMC0_SETUP0_VAL + +SMRDATA1: + .word AT91_ASM_SDRAMC_MR + .word CONFIG_SYS_SDRC_MR_VAL1 + .word AT91_ASM_SDRAMC_TR + .word CONFIG_SYS_SDRC_TR_VAL1 + .word AT91_ASM_SDRAMC_CR + .word CONFIG_SYS_SDRC_CR_VAL + .word AT91_ASM_SDRAMC_MDR + .word CONFIG_SYS_SDRC_MDR_VAL + .word AT91_ASM_SDRAMC_MR + .word CONFIG_SYS_SDRC_MR_VAL2 + .word AT91_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL1 + .word AT91_ASM_SDRAMC_MR + .word CONFIG_SYS_SDRC_MR_VAL3 + .word AT91_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL2 + .word AT91_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL3 + .word AT91_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL4 + .word AT91_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL5 + .word AT91_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL6 + .word AT91_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL7 + .word AT91_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL8 + .word AT91_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL9 + .word AT91_ASM_SDRAMC_MR + .word CONFIG_SYS_SDRC_MR_VAL4 + .word AT91_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL10 + .word AT91_ASM_SDRAMC_MR + .word CONFIG_SYS_SDRC_MR_VAL5 + .word AT91_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL11 + .word AT91_ASM_SDRAMC_TR + .word CONFIG_SYS_SDRC_TR_VAL2 + .word AT91_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL12 + /* User reset enable*/ + .word AT91_ASM_RSTC_MR + .word CONFIG_SYS_RSTC_RMR_VAL +#ifdef CONFIG_SYS_MATRIX_MCFG_REMAP + /* MATRIX_MCFG - REMAP all masters */ + .word AT91_ASM_MATRIX_MCFG + .word 0x1FF +#endif +SMRDATA2: + .word 0 diff --git a/arch/arm/cpu/arm926ejs/at91/reset.c b/arch/arm/cpu/arm926ejs/at91/reset.c new file mode 100644 index 0000000000..1b67e77887 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/at91/reset.c @@ -0,0 +1,44 @@ +/* + * (C) Copyright 2007-2008 + * Stelian Pop + * Lead Tech Design + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include + +/* + * Reset the cpu by setting up the watchdog timer and let him time out. + */ +void reset_cpu(ulong ignored) +{ + at91_rstc_t *rstc = (at91_rstc_t *) AT91_RSTC_BASE; + + /* this is the way Linux does it */ + + writel(AT91_RSTC_KEY | AT91_RSTC_CR_PROCRST | AT91_RSTC_CR_PERRST, + &rstc->cr); + + while (1); + /* Never reached */ +} diff --git a/arch/arm/cpu/arm926ejs/at91/timer.c b/arch/arm/cpu/arm926ejs/at91/timer.c new file mode 100644 index 0000000000..d21eebfb4e --- /dev/null +++ b/arch/arm/cpu/arm926ejs/at91/timer.c @@ -0,0 +1,145 @@ +/* + * (C) Copyright 2007-2008 + * Stelian Pop + * Lead Tech Design + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include + +/* + * We're using the AT91CAP9/SAM9 PITC in 32 bit mode, by + * setting the 20 bit counter period to its maximum (0xfffff). + */ +#define TIMER_LOAD_VAL 0xfffff + +static ulong timestamp; +static ulong lastinc; +static ulong timer_freq; + +static inline unsigned long long tick_to_time(unsigned long long tick) +{ + tick *= CONFIG_SYS_HZ; + do_div(tick, timer_freq); + + return tick; +} + +static inline unsigned long long usec_to_tick(unsigned long long usec) +{ + usec *= timer_freq; + do_div(usec, 1000000); + + return usec; +} + +/* nothing really to do with interrupts, just starts up a counter. */ +int timer_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + at91_pit_t *pit = (at91_pit_t *) AT91_PIT_BASE; + /* + * Enable PITC Clock + * The clock is already enabled for system controller in boot + */ + writel(1 << AT91_ID_SYS, &pmc->pcer); + + /* Enable PITC */ + writel(TIMER_LOAD_VAL | AT91_PIT_MR_EN , &pit->mr); + + reset_timer_masked(); + + timer_freq = get_mck_clk_rate() >> 4; + + return 0; +} + +/* + * timer without interrupts + */ +unsigned long long get_ticks(void) +{ + at91_pit_t *pit = (at91_pit_t *) AT91_PIT_BASE; + + ulong now = readl(&pit->piir); + + if (now >= lastinc) /* normal mode (non roll) */ + /* move stamp forward with absolut diff ticks */ + timestamp += (now - lastinc); + else /* we have rollover of incrementer */ + timestamp += (0xFFFFFFFF - lastinc) + now; + lastinc = now; + return timestamp; +} + +void reset_timer_masked(void) +{ + /* reset time */ + at91_pit_t *pit = (at91_pit_t *) AT91_PIT_BASE; + + /* capture current incrementer value time */ + lastinc = readl(&pit->piir); + timestamp = 0; /* start "advancing" time stamp from 0 */ +} + +ulong get_timer_masked(void) +{ + return tick_to_time(get_ticks()); +} + +void __udelay(unsigned long usec) +{ + unsigned long long tmp; + ulong tmo; + + tmo = usec_to_tick(usec); + tmp = get_ticks() + tmo; /* get current timestamp */ + + while (get_ticks() < tmp) /* loop till event */ + /*NOP*/; +} + +void reset_timer(void) +{ + reset_timer_masked(); +} + +ulong get_timer(ulong base) +{ + return get_timer_masked () - base; +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + ulong tbclk; + + tbclk = CONFIG_SYS_HZ; + return tbclk; +} diff --git a/arch/arm/cpu/arm926ejs/config.mk b/arch/arm/cpu/arm926ejs/config.mk new file mode 100644 index 0000000000..f8ef90f2d5 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/config.mk @@ -0,0 +1,32 @@ +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float + +PLATFORM_CPPFLAGS += -march=armv5te +# ========================================================================= +# +# Supply options according to compiler version +# +# ========================================================================= +PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/arch/arm/cpu/arm926ejs/cpu.c b/arch/arm/cpu/arm926ejs/cpu.c new file mode 100644 index 0000000000..5c902dfc13 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/cpu.c @@ -0,0 +1,65 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * CPU specific code + */ + +#include +#include +#include + +static void cache_flush(void); + +int cleanup_before_linux (void) +{ + /* + * this function is called just before we call linux + * it prepares the processor for linux + * + * we turn off caches etc ... + */ + + disable_interrupts (); + + + /* turn off I/D-cache */ + icache_disable(); + dcache_disable(); + /* flush I/D-cache */ + cache_flush(); + + return 0; +} + +/* flush I/D-cache */ +static void cache_flush (void) +{ + unsigned long i = 0; + + asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); +} diff --git a/arch/arm/cpu/arm926ejs/davinci/Makefile b/arch/arm/cpu/arm926ejs/davinci/Makefile new file mode 100644 index 0000000000..d7e9e2ca04 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/davinci/Makefile @@ -0,0 +1,59 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# Copyright (C) 2007 Sergey Kubushyn +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +COBJS-y += cpu.o timer.o psc.o +COBJS-$(CONFIG_SOC_DM355) += dm355.o +COBJS-$(CONFIG_SOC_DM365) += dm365.o +COBJS-$(CONFIG_SOC_DM644X) += dm644x.o +COBJS-$(CONFIG_SOC_DM646X) += dm646x.o +COBJS-$(CONFIG_DRIVER_TI_EMAC) += lxt972.o dp83848.o + +SOBJS = reset.o + +ifndef CONFIG_SKIP_LOWLEVEL_INIT +SOBJS += lowlevel_init.o +endif + +SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y) $(SOBJS)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm926ejs/davinci/config.mk b/arch/arm/cpu/arm926ejs/davinci/config.mk new file mode 100644 index 0000000000..565adda11d --- /dev/null +++ b/arch/arm/cpu/arm926ejs/davinci/config.mk @@ -0,0 +1,32 @@ +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float + +PLATFORM_CPPFLAGS += -march=armv5te +# ========================================================================= +# +# Supply options according to compiler version +# +# ========================================================================= +PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/arch/arm/cpu/arm926ejs/davinci/cpu.c b/arch/arm/cpu/arm926ejs/davinci/cpu.c new file mode 100644 index 0000000000..fc3551c302 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/davinci/cpu.c @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2004 Texas Instruments. + * Copyright (C) 2009 David Brownell + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +/* offsets from PLL controller base */ +#define PLLC_PLLCTL 0x100 +#define PLLC_PLLM 0x110 +#define PLLC_PREDIV 0x114 +#define PLLC_PLLDIV1 0x118 +#define PLLC_PLLDIV2 0x11c +#define PLLC_PLLDIV3 0x120 +#define PLLC_POSTDIV 0x128 +#define PLLC_BPDIV 0x12c +#define PLLC_PLLDIV4 0x160 +#define PLLC_PLLDIV5 0x164 +#define PLLC_PLLDIV6 0x168 +#define PLLC_PLLDIV8 0x170 +#define PLLC_PLLDIV9 0x174 + +#define BIT(x) (1 << (x)) + +/* SOC-specific pll info */ +#ifdef CONFIG_SOC_DM355 +#define ARM_PLLDIV PLLC_PLLDIV1 +#define DDR_PLLDIV PLLC_PLLDIV1 +#endif + +#ifdef CONFIG_SOC_DM644X +#define ARM_PLLDIV PLLC_PLLDIV2 +#define DSP_PLLDIV PLLC_PLLDIV1 +#define DDR_PLLDIV PLLC_PLLDIV2 +#endif + +#ifdef CONFIG_SOC_DM6447 +#define ARM_PLLDIV PLLC_PLLDIV2 +#define DSP_PLLDIV PLLC_PLLDIV1 +#define DDR_PLLDIV PLLC_PLLDIV1 +#endif + +#ifdef CONFIG_SOC_DA8XX +const dv_reg * const sysdiv[7] = { + &davinci_pllc_regs->plldiv1, &davinci_pllc_regs->plldiv2, + &davinci_pllc_regs->plldiv3, &davinci_pllc_regs->plldiv4, + &davinci_pllc_regs->plldiv5, &davinci_pllc_regs->plldiv6, + &davinci_pllc_regs->plldiv7 +}; + +int clk_get(enum davinci_clk_ids id) +{ + int pre_div; + int pllm; + int post_div; + int pll_out; + + pll_out = CONFIG_SYS_OSCIN_FREQ; + + if (id == DAVINCI_AUXCLK_CLKID) + goto out; + + /* + * Lets keep this simple. Combining operations can result in + * unexpected approximations + */ + pre_div = (readl(&davinci_pllc_regs->prediv) & + DAVINCI_PLLC_DIV_MASK) + 1; + pllm = readl(&davinci_pllc_regs->pllm) + 1; + + pll_out /= pre_div; + pll_out *= pllm; + + if (id == DAVINCI_PLLM_CLKID) + goto out; + + post_div = (readl(&davinci_pllc_regs->postdiv) & + DAVINCI_PLLC_DIV_MASK) + 1; + + pll_out /= post_div; + + if (id == DAVINCI_PLLC_CLKID) + goto out; + + pll_out /= (readl(sysdiv[id - 1]) & DAVINCI_PLLC_DIV_MASK) + 1; + +out: + return pll_out; +} +#endif /* CONFIG_SOC_DA8XX */ + +#ifdef CONFIG_DISPLAY_CPUINFO + +static unsigned pll_div(volatile void *pllbase, unsigned offset) +{ + u32 div; + + div = REG(pllbase + offset); + return (div & BIT(15)) ? (1 + (div & 0x1f)) : 1; +} + +static inline unsigned pll_prediv(volatile void *pllbase) +{ +#ifdef CONFIG_SOC_DM355 + /* this register read seems to fail on pll0 */ + if (pllbase == (volatile void *)DAVINCI_PLL_CNTRL0_BASE) + return 8; + else + return pll_div(pllbase, PLLC_PREDIV); +#endif + return 1; +} + +static inline unsigned pll_postdiv(volatile void *pllbase) +{ +#ifdef CONFIG_SOC_DM355 + return pll_div(pllbase, PLLC_POSTDIV); +#elif defined(CONFIG_SOC_DM6446) + if (pllbase == (volatile void *)DAVINCI_PLL_CNTRL0_BASE) + return pll_div(pllbase, PLLC_POSTDIV); +#endif + return 1; +} + +static unsigned pll_sysclk_mhz(unsigned pll_addr, unsigned div) +{ + volatile void *pllbase = (volatile void *) pll_addr; + unsigned base = CONFIG_SYS_HZ_CLOCK / 1000; + + /* the PLL might be bypassed */ + if (REG(pllbase + PLLC_PLLCTL) & BIT(0)) { + base /= pll_prediv(pllbase); + base *= 1 + (REG(pllbase + PLLC_PLLM) & 0x0ff); + base /= pll_postdiv(pllbase); + } + return DIV_ROUND_UP(base, 1000 * pll_div(pllbase, div)); +} + +int print_cpuinfo(void) +{ + /* REVISIT fetch and display CPU ID and revision information + * too ... that will matter as more revisions appear. + */ + printf("Cores: ARM %d MHz", + pll_sysclk_mhz(DAVINCI_PLL_CNTRL0_BASE, ARM_PLLDIV)); + +#ifdef DSP_PLLDIV + printf(", DSP %d MHz", + pll_sysclk_mhz(DAVINCI_PLL_CNTRL0_BASE, DSP_PLLDIV)); +#endif + + printf("\nDDR: %d MHz\n", + /* DDR PHY uses an x2 input clock */ + pll_sysclk_mhz(DAVINCI_PLL_CNTRL1_BASE, DDR_PLLDIV) + / 2); + return 0; +} + +#endif + +/* + * Initializes on-chip ethernet controllers. + * to override, implement board_eth_init() + */ +int cpu_eth_init(bd_t *bis) +{ +#if defined(CONFIG_DRIVER_TI_EMAC) + davinci_emac_initialize(); +#endif + return 0; +} diff --git a/arch/arm/cpu/arm926ejs/davinci/dm355.c b/arch/arm/cpu/arm926ejs/davinci/dm355.c new file mode 100644 index 0000000000..bc45b67fbe --- /dev/null +++ b/arch/arm/cpu/arm926ejs/davinci/dm355.c @@ -0,0 +1,45 @@ +/* + * SoC-specific code for tms320dm355 and similar chips + * + * Copyright (C) 2009 David Brownell + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include + + +void davinci_enable_uart0(void) +{ + lpsc_on(DAVINCI_LPSC_UART0); + + /* Bringup UART0 out of reset */ + REG(UART0_PWREMU_MGMT) = 0x00006001; +} + + +#ifdef CONFIG_DRIVER_DAVINCI_I2C +void davinci_enable_i2c(void) +{ + lpsc_on(DAVINCI_LPSC_I2C); + + /* Enable I2C pin Mux */ + REG(PINMUX3) |= (1 << 20) | (1 << 19); +} +#endif diff --git a/arch/arm/cpu/arm926ejs/davinci/dm365.c b/arch/arm/cpu/arm926ejs/davinci/dm365.c new file mode 100644 index 0000000000..56c1bc032b --- /dev/null +++ b/arch/arm/cpu/arm926ejs/davinci/dm365.c @@ -0,0 +1,35 @@ +/* + * SoC-specific code for tms320dm365 and similar chips + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include + +void davinci_enable_uart0(void) +{ + lpsc_on(DAVINCI_LPSC_UART0); +} + +#ifdef CONFIG_DRIVER_DAVINCI_I2C +void davinci_enable_i2c(void) +{ + lpsc_on(DAVINCI_LPSC_I2C); +} +#endif diff --git a/arch/arm/cpu/arm926ejs/davinci/dm644x.c b/arch/arm/cpu/arm926ejs/davinci/dm644x.c new file mode 100644 index 0000000000..bb105b56ee --- /dev/null +++ b/arch/arm/cpu/arm926ejs/davinci/dm644x.c @@ -0,0 +1,96 @@ +/* + * SoC-specific code for tms320dm644x chips + * + * Copyright (C) 2007 Sergey Kubushyn + * Copyright (C) 2008 Lyrtech + * Copyright (C) 2004 Texas Instruments. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include + + +#define PINMUX0_EMACEN (1 << 31) +#define PINMUX0_AECS5 (1 << 11) +#define PINMUX0_AECS4 (1 << 10) + +#define PINMUX1_I2C (1 << 7) +#define PINMUX1_UART1 (1 << 1) +#define PINMUX1_UART0 (1 << 0) + + +void davinci_enable_uart0(void) +{ + lpsc_on(DAVINCI_LPSC_UART0); + + /* Bringup UART0 out of reset */ + REG(UART0_PWREMU_MGMT) = 0x00006001; + + /* Enable UART0 MUX lines */ + REG(PINMUX1) |= PINMUX1_UART0; +} + +#ifdef CONFIG_DRIVER_TI_EMAC +void davinci_enable_emac(void) +{ + lpsc_on(DAVINCI_LPSC_EMAC); + lpsc_on(DAVINCI_LPSC_EMAC_WRAPPER); + lpsc_on(DAVINCI_LPSC_MDIO); + + /* Enable GIO3.3V cells used for EMAC */ + REG(VDD3P3V_PWDN) = 0; + + /* Enable EMAC. */ + REG(PINMUX0) |= PINMUX0_EMACEN; +} +#endif + +#ifdef CONFIG_DRIVER_DAVINCI_I2C +void davinci_enable_i2c(void) +{ + lpsc_on(DAVINCI_LPSC_I2C); + + /* Enable I2C pin Mux */ + REG(PINMUX1) |= PINMUX1_I2C; +} +#endif + +void davinci_errata_workarounds(void) +{ + /* + * Workaround for TMS320DM6446 errata 1.3.22: + * PSC: PTSTAT Register Does Not Clear After Warm/Maximum Reset + * Revision(s) Affected: 1.3 and earlier + */ + REG(PSC_SILVER_BULLET) = 0; + + /* + * Set the PR_OLD_COUNT bits in the Bus Burst Priority Register (PBBPR) + * as suggested in TMS320DM6446 errata 2.1.2: + * + * On DM6446 Silicon Revision 2.1 and earlier, under certain conditions + * low priority modules can occupy the bus and prevent high priority + * modules like the VPSS from getting the required DDR2 throughput. + * A hex value of 0x20 should provide a good ARM (cache enabled) + * performance and still allow good utilization by the VPSS or other + * modules. + */ + REG(VBPR) = 0x20; +} diff --git a/arch/arm/cpu/arm926ejs/davinci/dm646x.c b/arch/arm/cpu/arm926ejs/davinci/dm646x.c new file mode 100644 index 0000000000..329825f453 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/davinci/dm646x.c @@ -0,0 +1,41 @@ +/* + * SoC-specific code for TMS320DM646x chips + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +void davinci_enable_uart0(void) +{ + lpsc_on(DAVINCI_DM646X_LPSC_UART0); +} + +#ifdef CONFIG_DRIVER_TI_EMAC +void davinci_enable_emac(void) +{ + lpsc_on(DAVINCI_DM646X_LPSC_EMAC); +} +#endif + +#ifdef CONFIG_DRIVER_DAVINCI_I2C +void davinci_enable_i2c(void) +{ + lpsc_on(DAVINCI_DM646X_LPSC_I2C); +} +#endif diff --git a/arch/arm/cpu/arm926ejs/davinci/dp83848.c b/arch/arm/cpu/arm926ejs/davinci/dp83848.c new file mode 100644 index 0000000000..c71c685f72 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/davinci/dp83848.c @@ -0,0 +1,143 @@ +/* + * National Semiconductor DP83848 PHY Driver for TI DaVinci + * (TMS320DM644x) based boards. + * + * Copyright (C) 2007 Sergey Kubushyn + * + * -------------------------------------------------------- + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include + +#ifdef CONFIG_DRIVER_TI_EMAC + +#ifdef CONFIG_CMD_NET + +int dp83848_is_phy_connected(int phy_addr) +{ + u_int16_t id1, id2; + + if (!davinci_eth_phy_read(phy_addr, DP83848_PHYID1_REG, &id1)) + return(0); + if (!davinci_eth_phy_read(phy_addr, DP83848_PHYID2_REG, &id2)) + return(0); + + if ((id1 == DP83848_PHYID1_OUI) && (id2 == DP83848_PHYID2_OUI)) + return(1); + + return(0); +} + +int dp83848_get_link_speed(int phy_addr) +{ + u_int16_t tmp; + volatile emac_regs* emac = (emac_regs *)EMAC_BASE_ADDR; + + if (!davinci_eth_phy_read(phy_addr, DP83848_STAT_REG, &tmp)) + return(0); + + if (!(tmp & DP83848_LINK_STATUS)) /* link up? */ + return(0); + + if (!davinci_eth_phy_read(phy_addr, DP83848_PHY_STAT_REG, &tmp)) + return(0); + + /* Speed doesn't matter, there is no setting for it in EMAC... */ + if (tmp & DP83848_DUPLEX) { + /* set DM644x EMAC for Full Duplex */ + emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE | + EMAC_MACCONTROL_FULLDUPLEX_ENABLE; + } else { + /*set DM644x EMAC for Half Duplex */ + emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE; + } + + return(1); +} + + +int dp83848_init_phy(int phy_addr) +{ + int ret = 1; + + if (!dp83848_get_link_speed(phy_addr)) { + /* Try another time */ + udelay(100000); + ret = dp83848_get_link_speed(phy_addr); + } + + /* Disable PHY Interrupts */ + davinci_eth_phy_write(phy_addr, DP83848_PHY_INTR_CTRL_REG, 0); + + return(ret); +} + + +int dp83848_auto_negotiate(int phy_addr) +{ + u_int16_t tmp; + + + if (!davinci_eth_phy_read(phy_addr, DP83848_CTL_REG, &tmp)) + return(0); + + /* Restart Auto_negotiation */ + tmp &= ~DP83848_AUTONEG; /* remove autonegotiation enable */ + tmp |= DP83848_ISOLATE; /* Electrically isolate PHY */ + davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp); + + /* Set the Auto_negotiation Advertisement Register + * MII advertising for Next page, 100BaseTxFD and HD, + * 10BaseTFD and HD, IEEE 802.3 + */ + tmp = DP83848_NP | DP83848_TX_FDX | DP83848_TX_HDX | + DP83848_10_FDX | DP83848_10_HDX | DP83848_AN_IEEE_802_3; + davinci_eth_phy_write(phy_addr, DP83848_ANA_REG, tmp); + + + /* Read Control Register */ + if (!davinci_eth_phy_read(phy_addr, DP83848_CTL_REG, &tmp)) + return(0); + + tmp |= DP83848_SPEED_SELECT | DP83848_AUTONEG | DP83848_DUPLEX_MODE; + davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp); + + /* Restart Auto_negotiation */ + tmp |= DP83848_RESTART_AUTONEG; + davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp); + + /*check AutoNegotiate complete */ + udelay(10000); + if (!davinci_eth_phy_read(phy_addr, DP83848_STAT_REG, &tmp)) + return(0); + + if (!(tmp & DP83848_AUTONEG_COMP)) + return(0); + + return (dp83848_get_link_speed(phy_addr)); +} + +#endif /* CONFIG_CMD_NET */ + +#endif /* CONFIG_DRIVER_ETHER */ diff --git a/arch/arm/cpu/arm926ejs/davinci/lowlevel_init.S b/arch/arm/cpu/arm926ejs/davinci/lowlevel_init.S new file mode 100644 index 0000000000..0a4b2cf674 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/davinci/lowlevel_init.S @@ -0,0 +1,707 @@ +/* + * Low-level board setup code for TI DaVinci SoC based boards. + * + * Copyright (C) 2007 Sergey Kubushyn + * + * Partially based on TI sources, original copyrights follow: + */ + +/* + * Board specific setup info + * + * (C) Copyright 2003 + * Texas Instruments, + * Kshitij Gupta + * + * Modified for OMAP 1610 H2 board by Nishant Kamat, Jan 2004 + * + * Modified for OMAP 5912 OSK board by Rishi Bhattacharya, Apr 2004 + * See file CREDITS for list of people who contributed to this + * project. + * + * Modified for DV-EVM board by Rishi Bhattacharya, Apr 2005 + * See file CREDITS for list of people who contributed to this + * project. + * + * Modified for DV-EVM board by Swaminathan S, Nov 2005 + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +.globl lowlevel_init +lowlevel_init: + + /*-------------------------------------------------------* + * Mask all IRQs by setting all bits in the EINT default * + *-------------------------------------------------------*/ + mov r1, $0 + ldr r0, =EINT_ENABLE0 + str r1, [r0] + ldr r0, =EINT_ENABLE1 + str r1, [r0] + + /*------------------------------------------------------* + * Put the GEM in reset * + *------------------------------------------------------*/ + + /* Put the GEM in reset */ + ldr r8, PSC_GEM_FLAG_CLEAR + ldr r6, MDCTL_GEM + ldr r7, [r6] + and r7, r7, r8 + str r7, [r6] + + /* Enable the Power Domain Transition Command */ + ldr r6, PTCMD + ldr r7, [r6] + orr r7, r7, $0x02 + str r7, [r6] + + /* Check for Transition Complete(PTSTAT) */ +checkStatClkStopGem: + ldr r6, PTSTAT + ldr r7, [r6] + ands r7, r7, $0x02 + bne checkStatClkStopGem + + /* Check for GEM Reset Completion */ +checkGemStatClkStop: + ldr r6, MDSTAT_GEM + ldr r7, [r6] + ands r7, r7, $0x100 + bne checkGemStatClkStop + + /* Do this for enabling a WDT initiated reset this is a workaround + for a chip bug. Not required under normal situations */ + ldr r6, P1394 + mov r10, $0 + str r10, [r6] + + /*------------------------------------------------------* + * Enable L1 & L2 Memories in Fast mode * + *------------------------------------------------------*/ + ldr r6, DFT_ENABLE + mov r10, $0x01 + str r10, [r6] + + ldr r6, MMARG_BRF0 + ldr r10, MMARG_BRF0_VAL + str r10, [r6] + + ldr r6, DFT_ENABLE + mov r10, $0 + str r10, [r6] + + /*------------------------------------------------------* + * DDR2 PLL Initialization * + *------------------------------------------------------*/ + + /* Select the Clock Mode Depending on the Value written in the Boot Table by the run script */ + mov r10, $0 + ldr r6, PLL2_CTL + ldr r7, PLL_CLKSRC_MASK + ldr r8, [r6] + and r8, r8, r7 + mov r9, r10, lsl $8 + orr r8, r8, r9 + str r8, [r6] + + /* Select the PLLEN source */ + ldr r7, PLL_ENSRC_MASK + and r8, r8, r7 + str r8, [r6] + + /* Bypass the PLL */ + ldr r7, PLL_BYPASS_MASK + and r8, r8, r7 + str r8, [r6] + + /* Wait for few cycles to allow PLLEN Mux switch properly to bypass Clock */ + mov r10, $0x20 +WaitPPL2Loop: + subs r10, r10, $1 + bne WaitPPL2Loop + + /* Reset the PLL */ + ldr r7, PLL_RESET_MASK + and r8, r8, r7 + str r8, [r6] + + /* Power up the PLL */ + ldr r7, PLL_PWRUP_MASK + and r8, r8, r7 + str r8, [r6] + + /* Enable the PLL from Disable Mode */ + ldr r7, PLL_DISABLE_ENABLE_MASK + and r8, r8, r7 + str r8, [r6] + + /* Program the PLL Multiplier */ + ldr r6, PLL2_PLLM + mov r2, $0x17 /* 162 MHz */ + str r2, [r6] + + /* Program the PLL2 Divisor Value */ + ldr r6, PLL2_DIV2 + mov r3, $0x01 + str r3, [r6] + + /* Program the PLL2 Divisor Value */ + ldr r6, PLL2_DIV1 + mov r4, $0x0b /* 54 MHz */ + str r4, [r6] + + /* PLL2 DIV2 MMR */ + ldr r8, PLL2_DIV_MASK + ldr r6, PLL2_DIV2 + ldr r9, [r6] + and r8, r8, r9 + mov r9, $0x01 + mov r9, r9, lsl $15 + orr r8, r8, r9 + str r8, [r6] + + /* Program the GOSET bit to take new divider values */ + ldr r6, PLL2_PLLCMD + ldr r7, [r6] + orr r7, r7, $0x01 + str r7, [r6] + + /* Wait for Done */ + ldr r6, PLL2_PLLSTAT +doneLoop_0: + ldr r7, [r6] + ands r7, r7, $0x01 + bne doneLoop_0 + + /* PLL2 DIV1 MMR */ + ldr r8, PLL2_DIV_MASK + ldr r6, PLL2_DIV1 + ldr r9, [r6] + and r8, r8, r9 + mov r9, $0x01 + mov r9, r9, lsl $15 + orr r8, r8, r9 + str r8, [r6] + + /* Program the GOSET bit to take new divider values */ + ldr r6, PLL2_PLLCMD + ldr r7, [r6] + orr r7, r7, $0x01 + str r7, [r6] + + /* Wait for Done */ + ldr r6, PLL2_PLLSTAT +doneLoop: + ldr r7, [r6] + ands r7, r7, $0x01 + bne doneLoop + + /* Wait for PLL to Reset Properly */ + mov r10, $0x218 +ResetPPL2Loop: + subs r10, r10, $1 + bne ResetPPL2Loop + + /* Bring PLL out of Reset */ + ldr r6, PLL2_CTL + ldr r8, [r6] + orr r8, r8, $0x08 + str r8, [r6] + + /* Wait for PLL to Lock */ + ldr r10, PLL_LOCK_COUNT +PLL2Lock: + subs r10, r10, $1 + bne PLL2Lock + + /* Enable the PLL */ + ldr r6, PLL2_CTL + ldr r8, [r6] + orr r8, r8, $0x01 + str r8, [r6] + + /*------------------------------------------------------* + * Issue Soft Reset to DDR Module * + *------------------------------------------------------*/ + + /* Shut down the DDR2 LPSC Module */ + ldr r8, PSC_FLAG_CLEAR + ldr r6, MDCTL_DDR2 + ldr r7, [r6] + and r7, r7, r8 + orr r7, r7, $0x03 + str r7, [r6] + + /* Enable the Power Domain Transition Command */ + ldr r6, PTCMD + ldr r7, [r6] + orr r7, r7, $0x01 + str r7, [r6] + + /* Check for Transition Complete(PTSTAT) */ +checkStatClkStop: + ldr r6, PTSTAT + ldr r7, [r6] + ands r7, r7, $0x01 + bne checkStatClkStop + + /* Check for DDR2 Controller Enable Completion */ +checkDDRStatClkStop: + ldr r6, MDSTAT_DDR2 + ldr r7, [r6] + and r7, r7, $0x1f + cmp r7, $0x03 + bne checkDDRStatClkStop + + /*------------------------------------------------------* + * Program DDR2 MMRs for 162MHz Setting * + *------------------------------------------------------*/ + + /* Program PHY Control Register */ + ldr r6, DDRCTL + ldr r7, DDRCTL_VAL + str r7, [r6] + + /* Program SDRAM Bank Config Register */ + ldr r6, SDCFG + ldr r7, SDCFG_VAL + str r7, [r6] + + /* Program SDRAM TIM-0 Config Register */ + ldr r6, SDTIM0 + ldr r7, SDTIM0_VAL_162MHz + str r7, [r6] + + /* Program SDRAM TIM-1 Config Register */ + ldr r6, SDTIM1 + ldr r7, SDTIM1_VAL_162MHz + str r7, [r6] + + /* Program the SDRAM Bank Config Control Register */ + ldr r10, MASK_VAL + ldr r8, SDCFG + ldr r9, SDCFG_VAL + and r9, r9, r10 + str r9, [r8] + + /* Program SDRAM SDREF Config Register */ + ldr r6, SDREF + ldr r7, SDREF_VAL + str r7, [r6] + + /*------------------------------------------------------* + * Issue Soft Reset to DDR Module * + *------------------------------------------------------*/ + + /* Issue a Dummy DDR2 read/write */ + ldr r8, DDR2_START_ADDR + ldr r7, DUMMY_VAL + str r7, [r8] + ldr r7, [r8] + + /* Shut down the DDR2 LPSC Module */ + ldr r8, PSC_FLAG_CLEAR + ldr r6, MDCTL_DDR2 + ldr r7, [r6] + and r7, r7, r8 + orr r7, r7, $0x01 + str r7, [r6] + + /* Enable the Power Domain Transition Command */ + ldr r6, PTCMD + ldr r7, [r6] + orr r7, r7, $0x01 + str r7, [r6] + + /* Check for Transition Complete(PTSTAT) */ +checkStatClkStop2: + ldr r6, PTSTAT + ldr r7, [r6] + ands r7, r7, $0x01 + bne checkStatClkStop2 + + /* Check for DDR2 Controller Enable Completion */ +checkDDRStatClkStop2: + ldr r6, MDSTAT_DDR2 + ldr r7, [r6] + and r7, r7, $0x1f + cmp r7, $0x01 + bne checkDDRStatClkStop2 + + /*------------------------------------------------------* + * Turn DDR2 Controller Clocks On * + *------------------------------------------------------*/ + + /* Enable the DDR2 LPSC Module */ + ldr r6, MDCTL_DDR2 + ldr r7, [r6] + orr r7, r7, $0x03 + str r7, [r6] + + /* Enable the Power Domain Transition Command */ + ldr r6, PTCMD + ldr r7, [r6] + orr r7, r7, $0x01 + str r7, [r6] + + /* Check for Transition Complete(PTSTAT) */ +checkStatClkEn2: + ldr r6, PTSTAT + ldr r7, [r6] + ands r7, r7, $0x01 + bne checkStatClkEn2 + + /* Check for DDR2 Controller Enable Completion */ +checkDDRStatClkEn2: + ldr r6, MDSTAT_DDR2 + ldr r7, [r6] + and r7, r7, $0x1f + cmp r7, $0x03 + bne checkDDRStatClkEn2 + + /* DDR Writes and Reads */ + ldr r6, CFGTEST + mov r3, $0x01 + str r3, [r6] + + /*------------------------------------------------------* + * System PLL Initialization * + *------------------------------------------------------*/ + + /* Select the Clock Mode Depending on the Value written in the Boot Table by the run script */ + mov r2, $0 + ldr r6, PLL1_CTL + ldr r7, PLL_CLKSRC_MASK + ldr r8, [r6] + and r8, r8, r7 + mov r9, r2, lsl $8 + orr r8, r8, r9 + str r8, [r6] + + /* Select the PLLEN source */ + ldr r7, PLL_ENSRC_MASK + and r8, r8, r7 + str r8, [r6] + + /* Bypass the PLL */ + ldr r7, PLL_BYPASS_MASK + and r8, r8, r7 + str r8, [r6] + + /* Wait for few cycles to allow PLLEN Mux switch properly to bypass Clock */ + mov r10, $0x20 + +WaitLoop: + subs r10, r10, $1 + bne WaitLoop + + /* Reset the PLL */ + ldr r7, PLL_RESET_MASK + and r8, r8, r7 + str r8, [r6] + + /* Disable the PLL */ + orr r8, r8, $0x10 + str r8, [r6] + + /* Power up the PLL */ + ldr r7, PLL_PWRUP_MASK + and r8, r8, r7 + str r8, [r6] + + /* Enable the PLL from Disable Mode */ + ldr r7, PLL_DISABLE_ENABLE_MASK + and r8, r8, r7 + str r8, [r6] + + /* Program the PLL Multiplier */ + ldr r6, PLL1_PLLM + mov r3, $0x15 /* For 594MHz */ + str r3, [r6] + + /* Wait for PLL to Reset Properly */ + mov r10, $0xff + +ResetLoop: + subs r10, r10, $1 + bne ResetLoop + + /* Bring PLL out of Reset */ + ldr r6, PLL1_CTL + orr r8, r8, $0x08 + str r8, [r6] + + /* Wait for PLL to Lock */ + ldr r10, PLL_LOCK_COUNT + +PLL1Lock: + subs r10, r10, $1 + bne PLL1Lock + + /* Enable the PLL */ + orr r8, r8, $0x01 + str r8, [r6] + + nop + nop + nop + nop + + /*------------------------------------------------------* + * AEMIF configuration for NOR Flash (double check) * + *------------------------------------------------------*/ + ldr r0, _PINMUX0 + ldr r1, _DEV_SETTING + str r1, [r0] + + ldr r0, WAITCFG + ldr r1, WAITCFG_VAL + ldr r2, [r0] + orr r2, r2, r1 + str r2, [r0] + + ldr r0, ACFG3 + ldr r1, ACFG3_VAL + ldr r2, [r0] + and r1, r2, r1 + str r1, [r0] + + ldr r0, ACFG4 + ldr r1, ACFG4_VAL + ldr r2, [r0] + and r1, r2, r1 + str r1, [r0] + + ldr r0, ACFG5 + ldr r1, ACFG5_VAL + ldr r2, [r0] + and r1, r2, r1 + str r1, [r0] + + /*--------------------------------------* + * VTP manual Calibration * + *--------------------------------------*/ + ldr r0, VTPIOCR + ldr r1, VTP_MMR0 + str r1, [r0] + + ldr r0, VTPIOCR + ldr r1, VTP_MMR1 + str r1, [r0] + + /* Wait for 33 VTP CLK cycles. VRP operates at 27 MHz */ + ldr r10, VTP_LOCK_COUNT +VTPLock: + subs r10, r10, $1 + bne VTPLock + + ldr r6, DFT_ENABLE + mov r10, $0x01 + str r10, [r6] + + ldr r6, DDRVTPR + ldr r7, [r6] + and r7, r7, $0x1f + and r8, r7, $0x3e0 + orr r8, r7, r8 + ldr r7, VTP_RECAL + orr r8, r7, r8 + ldr r7, VTP_EN + orr r8, r7, r8 + str r8, [r0] + + + /* Wait for 33 VTP CLK cycles. VRP operates at 27 MHz */ + ldr r10, VTP_LOCK_COUNT +VTP1Lock: + subs r10, r10, $1 + bne VTP1Lock + + ldr r1, [r0] + ldr r2, VTP_MASK + and r2, r1, r2 + str r2, [r0] + + ldr r6, DFT_ENABLE + mov r10, $0 + str r10, [r6] + + /* + * Call board-specific lowlevel init. + * That MUST be present and THAT returns + * back to arch calling code with "mov pc, lr." + */ + b dv_board_init + +.ltorg + +_PINMUX0: + .word 0x01c40000 /* Device Configuration Registers */ +_PINMUX1: + .word 0x01c40004 /* Device Configuration Registers */ + +_DEV_SETTING: + .word 0x00000c1f + +WAITCFG: + .word 0x01e00004 +WAITCFG_VAL: + .word 0 +ACFG3: + .word 0x01e00014 +ACFG3_VAL: + .word 0x3ffffffd +ACFG4: + .word 0x01e00018 +ACFG4_VAL: + .word 0x3ffffffd +ACFG5: + .word 0x01e0001c +ACFG5_VAL: + .word 0x3ffffffd + +MDCTL_DDR2: + .word 0x01c41a34 +MDSTAT_DDR2: + .word 0x01c41834 + +PTCMD: + .word 0x01c41120 +PTSTAT: + .word 0x01c41128 + +EINT_ENABLE0: + .word 0x01c48018 +EINT_ENABLE1: + .word 0x01c4801c + +PSC_FLAG_CLEAR: + .word 0xffffffe0 +PSC_GEM_FLAG_CLEAR: + .word 0xfffffeff + +/* DDR2 MMR & CONFIGURATION VALUES, 162 MHZ clock */ +DDRCTL: + .word 0x200000e4 +DDRCTL_VAL: + .word 0x50006405 +SDREF: + .word 0x2000000c +SDREF_VAL: + .word 0x000005c3 +SDCFG: + .word 0x20000008 +SDCFG_VAL: +#ifdef DDR_4BANKS + .word 0x00178622 +#elif defined DDR_8BANKS + .word 0x00178632 +#else +#error "Unknown DDR configuration!!!" +#endif +SDTIM0: + .word 0x20000010 +SDTIM0_VAL_162MHz: + .word 0x28923211 +SDTIM1: + .word 0x20000014 +SDTIM1_VAL_162MHz: + .word 0x0016c722 +VTPIOCR: + .word 0x200000f0 /* VTP IO Control register */ +DDRVTPR: + .word 0x01c42030 /* DDR VPTR MMR */ +VTP_MMR0: + .word 0x201f +VTP_MMR1: + .word 0xa01f +DFT_ENABLE: + .word 0x01c4004c +VTP_LOCK_COUNT: + .word 0x5b0 +VTP_MASK: + .word 0xffffdfff +VTP_RECAL: + .word 0x40000 +VTP_EN: + .word 0x02000 +CFGTEST: + .word 0x80010000 +MASK_VAL: + .word 0x00000fff + +/* GEM Power Up & LPSC Control Register */ +MDCTL_GEM: + .word 0x01c41a9c +MDSTAT_GEM: + .word 0x01c4189c + +/* For WDT reset chip bug */ +P1394: + .word 0x01c41a20 + +PLL_CLKSRC_MASK: + .word 0xfffffeff /* Mask the Clock Mode bit */ +PLL_ENSRC_MASK: + .word 0xffffffdf /* Select the PLLEN source */ +PLL_BYPASS_MASK: + .word 0xfffffffe /* Put the PLL in BYPASS */ +PLL_RESET_MASK: + .word 0xfffffff7 /* Put the PLL in Reset Mode */ +PLL_PWRUP_MASK: + .word 0xfffffffd /* PLL Power up Mask Bit */ +PLL_DISABLE_ENABLE_MASK: + .word 0xffffffef /* Enable the PLL from Disable */ +PLL_LOCK_COUNT: + .word 0x2000 + +/* PLL1-SYSTEM PLL MMRs */ +PLL1_CTL: + .word 0x01c40900 +PLL1_PLLM: + .word 0x01c40910 + +/* PLL2-SYSTEM PLL MMRs */ +PLL2_CTL: + .word 0x01c40d00 +PLL2_PLLM: + .word 0x01c40d10 +PLL2_DIV1: + .word 0x01c40d18 +PLL2_DIV2: + .word 0x01c40d1c +PLL2_PLLCMD: + .word 0x01c40d38 +PLL2_PLLSTAT: + .word 0x01c40d3c +PLL2_DIV_MASK: + .word 0xffff7fff + +MMARG_BRF0: + .word 0x01c42010 /* BRF margin mode 0 (R/W)*/ +MMARG_BRF0_VAL: + .word 0x00444400 + +DDR2_START_ADDR: + .word 0x80000000 +DUMMY_VAL: + .word 0xa55aa55a diff --git a/arch/arm/cpu/arm926ejs/davinci/lxt972.c b/arch/arm/cpu/arm926ejs/davinci/lxt972.c new file mode 100644 index 0000000000..ce3e41c551 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/davinci/lxt972.c @@ -0,0 +1,128 @@ +/* + * Intel LXT971/LXT972 PHY Driver for TI DaVinci + * (TMS320DM644x) based boards. + * + * Copyright (C) 2007 Sergey Kubushyn + * + * -------------------------------------------------------- + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include + +#ifdef CONFIG_DRIVER_TI_EMAC + +#ifdef CONFIG_CMD_NET + +int lxt972_is_phy_connected(int phy_addr) +{ + u_int16_t id1, id2; + + if (!davinci_eth_phy_read(phy_addr, PHY_PHYIDR1, &id1)) + return(0); + if (!davinci_eth_phy_read(phy_addr, PHY_PHYIDR2, &id2)) + return(0); + + if ((id1 == (0x0013)) && ((id2 & 0xfff0) == 0x78e0)) + return(1); + + return(0); +} + +int lxt972_get_link_speed(int phy_addr) +{ + u_int16_t stat1, tmp; + volatile emac_regs *emac = (emac_regs *)EMAC_BASE_ADDR; + + if (!davinci_eth_phy_read(phy_addr, PHY_LXT971_STAT2, &stat1)) + return(0); + + if (!(stat1 & PHY_LXT971_STAT2_LINK)) /* link up? */ + return(0); + + if (!davinci_eth_phy_read(phy_addr, PHY_LXT971_DIG_CFG, &tmp)) + return(0); + + tmp |= PHY_LXT971_DIG_CFG_MII_DRIVE; + + davinci_eth_phy_write(phy_addr, PHY_LXT971_DIG_CFG, tmp); + /* Read back */ + if (!davinci_eth_phy_read(phy_addr, PHY_LXT971_DIG_CFG, &tmp)) + return(0); + + /* Speed doesn't matter, there is no setting for it in EMAC... */ + if (stat1 & PHY_LXT971_STAT2_DUPLEX_MODE) { + /* set DM644x EMAC for Full Duplex */ + emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE | + EMAC_MACCONTROL_FULLDUPLEX_ENABLE; + } else { + /*set DM644x EMAC for Half Duplex */ + emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE; + } + + return(1); +} + + +int lxt972_init_phy(int phy_addr) +{ + int ret = 1; + + if (!lxt972_get_link_speed(phy_addr)) { + /* Try another time */ + ret = lxt972_get_link_speed(phy_addr); + } + + /* Disable PHY Interrupts */ + davinci_eth_phy_write(phy_addr, PHY_LXT971_INT_ENABLE, 0); + + return(ret); +} + + +int lxt972_auto_negotiate(int phy_addr) +{ + u_int16_t tmp; + + if (!davinci_eth_phy_read(phy_addr, PHY_BMCR, &tmp)) + return(0); + + /* Restart Auto_negotiation */ + tmp |= PHY_BMCR_RST_NEG; + davinci_eth_phy_write(phy_addr, PHY_BMCR, tmp); + + /*check AutoNegotiate complete */ + udelay (10000); + if (!davinci_eth_phy_read(phy_addr, PHY_BMSR, &tmp)) + return(0); + + if (!(tmp & PHY_BMSR_AUTN_COMP)) + return(0); + + return (lxt972_get_link_speed(phy_addr)); +} + +#endif /* CONFIG_CMD_NET */ + +#endif /* CONFIG_DRIVER_ETHER */ diff --git a/arch/arm/cpu/arm926ejs/davinci/psc.c b/arch/arm/cpu/arm926ejs/davinci/psc.c new file mode 100644 index 0000000000..8273a7fae4 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/davinci/psc.c @@ -0,0 +1,160 @@ +/* + * Power and Sleep Controller (PSC) functions. + * + * Copyright (C) 2007 Sergey Kubushyn + * Copyright (C) 2008 Lyrtech + * Copyright (C) 2004 Texas Instruments. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include + +/* + * The PSC manages three inputs to a "module" which may be a peripheral or + * CPU. Those inputs are the module's: clock; reset signal; and sometimes + * its power domain. For our purposes, we only care whether clock and power + * are active, and the module is out of reset. + * + * DaVinci chips may include two separate power domains: "Always On" and "DSP". + * Chips without a DSP generally have only one domain. + * + * The "Always On" power domain is always on when the chip is on, and is + * powered by the VDD pins (on DM644X). The majority of DaVinci modules + * lie within the "Always On" power domain. + * + * A separate domain called the "DSP" domain houses the C64x+ and other video + * hardware such as VICP. In some chips, the "DSP" domain is not always on. + * The "DSP" power domain is powered by the CVDDDSP pins (on DM644X). + */ + +/* Works on Always On power domain only (no PD argument) */ +void lpsc_on(unsigned int id) +{ + dv_reg_p mdstat, mdctl, ptstat, ptcmd; +#ifdef CONFIG_SOC_DA8XX + struct davinci_psc_regs *psc_regs; +#endif + +#ifndef CONFIG_SOC_DA8XX + if (id >= DAVINCI_LPSC_GEM) + return; /* Don't work on DSP Power Domain */ + + mdstat = REG_P(PSC_MDSTAT_BASE + (id * 4)); + mdctl = REG_P(PSC_MDCTL_BASE + (id * 4)); + ptstat = REG_P(PSC_PTSTAT); + ptcmd = REG_P(PSC_PTCMD); +#else + if (id < DAVINCI_LPSC_PSC1_BASE) { + if (id >= PSC_PSC0_MODULE_ID_CNT) + return; + psc_regs = davinci_psc0_regs; + mdstat = &psc_regs->psc0.mdstat[id]; + mdctl = &psc_regs->psc0.mdctl[id]; + } else { + id -= DAVINCI_LPSC_PSC1_BASE; + if (id >= PSC_PSC1_MODULE_ID_CNT) + return; + psc_regs = davinci_psc1_regs; + mdstat = &psc_regs->psc1.mdstat[id]; + mdctl = &psc_regs->psc1.mdctl[id]; + } + ptstat = &psc_regs->ptstat; + ptcmd = &psc_regs->ptcmd; +#endif + + while (readl(ptstat) & 0x01) + continue; + + if ((readl(mdstat) & 0x1f) == 0x03) + return; /* Already on and enabled */ + + writel(readl(mdctl) | 0x03, mdctl); + + switch (id) { +#ifdef CONFIG_SOC_DM644X + /* Special treatment for some modules as for sprue14 p.7.4.2 */ + case DAVINCI_LPSC_VPSSSLV: + case DAVINCI_LPSC_EMAC: + case DAVINCI_LPSC_EMAC_WRAPPER: + case DAVINCI_LPSC_MDIO: + case DAVINCI_LPSC_USB: + case DAVINCI_LPSC_ATA: + case DAVINCI_LPSC_VLYNQ: + case DAVINCI_LPSC_UHPI: + case DAVINCI_LPSC_DDR_EMIF: + case DAVINCI_LPSC_AEMIF: + case DAVINCI_LPSC_MMC_SD: + case DAVINCI_LPSC_MEMSTICK: + case DAVINCI_LPSC_McBSP: + case DAVINCI_LPSC_GPIO: + writel(readl(mdctl) | 0x200, mdctl); + break; +#endif + } + + writel(0x01, ptcmd); + + while (readl(ptstat) & 0x01) + continue; + while ((readl(mdstat) & 0x1f) != 0x03) + continue; +} + +/* Not all DaVinci chips have a DSP power domain. */ +#ifdef CONFIG_SOC_DM644X + +/* If DSPLINK is used, we don't want U-Boot to power on the DSP. */ +#if !defined(CONFIG_SYS_USE_DSPLINK) +void dsp_on(void) +{ + int i; + + if (REG(PSC_PDSTAT1) & 0x1f) + return; /* Already on */ + + REG(PSC_GBLCTL) |= 0x01; + REG(PSC_PDCTL1) |= 0x01; + REG(PSC_PDCTL1) &= ~0x100; + REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_GEM * 4)) |= 0x03; + REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_GEM * 4)) &= 0xfffffeff; + REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_IMCOP * 4)) |= 0x03; + REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_IMCOP * 4)) &= 0xfffffeff; + REG(PSC_PTCMD) = 0x02; + + for (i = 0; i < 100; i++) { + if (REG(PSC_EPCPR) & 0x02) + break; + } + + REG(PSC_CHP_SHRTSW) = 0x01; + REG(PSC_PDCTL1) |= 0x100; + REG(PSC_EPCCR) = 0x02; + + for (i = 0; i < 100; i++) { + if (!(REG(PSC_PTSTAT) & 0x02)) + break; + } + + REG(PSC_GBLCTL) &= ~0x1f; +} +#endif /* CONFIG_SYS_USE_DSPLINK */ + +#endif /* have a DSP */ diff --git a/arch/arm/cpu/arm926ejs/davinci/reset.S b/arch/arm/cpu/arm926ejs/davinci/reset.S new file mode 100644 index 0000000000..ba0a7c3b4b --- /dev/null +++ b/arch/arm/cpu/arm926ejs/davinci/reset.S @@ -0,0 +1,81 @@ +/* + * Processor reset using WDT for TI TMS320DM644x SoC. + * + * Copyright (C) 2007 Sergey Kubushyn + * + * ----------------------------------------------------- + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +.globl reset_cpu +reset_cpu: + ldr r0, WDT_TGCR + mov r1, $0x08 + str r1, [r0] + ldr r1, [r0] + orr r1, r1, $0x03 + str r1, [r0] + mov r1, $0 + ldr r0, WDT_TIM12 + str r1, [r0] + ldr r0, WDT_TIM34 + str r1, [r0] + ldr r0, WDT_PRD12 + str r1, [r0] + ldr r0, WDT_PRD34 + str r1, [r0] + ldr r0, WDT_TCR + ldr r1, [r0] + orr r1, r1, $0x40 + str r1, [r0] + ldr r0, WDT_WDTCR + ldr r1, [r0] + orr r1, r1, $0x4000 + str r1, [r0] + ldr r1, WDTCR_VAL1 + str r1, [r0] + ldr r1, WDTCR_VAL2 + str r1, [r0] + /* Write an invalid value to the WDKEY field to trigger + * an immediate watchdog reset */ + mov r1, $0x4000 + str r1, [r0] + nop + nop + nop + nop +reset_cpu_loop: + b reset_cpu_loop + +WDT_TGCR: + .word 0x01c21c24 +WDT_TIM12: + .word 0x01c21c10 +WDT_TIM34: + .word 0x01c21c14 +WDT_PRD12: + .word 0x01c21c18 +WDT_PRD34: + .word 0x01c21c1c +WDT_TCR: + .word 0x01c21c20 +WDT_WDTCR: + .word 0x01c21c28 +WDTCR_VAL1: + .word 0xa5c64000 +WDTCR_VAL2: + .word 0xda7e4000 diff --git a/arch/arm/cpu/arm926ejs/davinci/timer.c b/arch/arm/cpu/arm926ejs/davinci/timer.c new file mode 100644 index 0000000000..9da7443f30 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/davinci/timer.c @@ -0,0 +1,149 @@ +/* + * (C) Copyright 2003 + * Texas Instruments + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * (C) Copyright 2002-2004 + * Gary Jennejohn, DENX Software Engineering, + * + * (C) Copyright 2004 + * Philippe Robin, ARM Ltd. + * + * Copyright (C) 2007 Sergey Kubushyn + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +struct davinci_timer { + u_int32_t pid12; + u_int32_t emumgt; + u_int32_t na1; + u_int32_t na2; + u_int32_t tim12; + u_int32_t tim34; + u_int32_t prd12; + u_int32_t prd34; + u_int32_t tcr; + u_int32_t tgcr; + u_int32_t wdtcr; +}; + +static struct davinci_timer * const timer = + (struct davinci_timer *)CONFIG_SYS_TIMERBASE; + +#define TIMER_LOAD_VAL (CONFIG_SYS_HZ_CLOCK / CONFIG_SYS_HZ) +#define TIM_CLK_DIV 16 + +static ulong timestamp; +static ulong lastinc; + +int timer_init(void) +{ + /* We are using timer34 in unchained 32-bit mode, full speed */ + writel(0x0, &timer->tcr); + writel(0x0, &timer->tgcr); + writel(0x06 | ((TIM_CLK_DIV - 1) << 8), &timer->tgcr); + writel(0x0, &timer->tim34); + writel(TIMER_LOAD_VAL, &timer->prd34); + lastinc = 0; + timestamp = 0; + writel(2 << 22, &timer->tcr); + + return(0); +} + +void reset_timer(void) +{ + writel(0x0, &timer->tcr); + writel(0x0, &timer->tim34); + lastinc = 0; + timestamp = 0; + writel(2 << 22, &timer->tcr); +} + +static ulong get_timer_raw(void) +{ + ulong now = readl(&timer->tim34); + + if (now >= lastinc) { + /* normal mode */ + timestamp += now - lastinc; + } else { + /* overflow ... */ + timestamp += now + TIMER_LOAD_VAL - lastinc; + } + lastinc = now; + return timestamp; +} + +ulong get_timer(ulong base) +{ + return((get_timer_raw() / (TIMER_LOAD_VAL / TIM_CLK_DIV)) - base); +} + +void set_timer(ulong t) +{ + timestamp = t; +} + +void __udelay(unsigned long usec) +{ + ulong tmo; + ulong endtime; + signed long diff; + + tmo = CONFIG_SYS_HZ_CLOCK / 1000; + tmo *= usec; + tmo /= (1000 * TIM_CLK_DIV); + + endtime = get_timer_raw() + tmo; + + do { + ulong now = get_timer_raw(); + diff = endtime - now; + } while (diff >= 0); +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return(get_timer(0)); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + return CONFIG_SYS_HZ; +} diff --git a/arch/arm/cpu/arm926ejs/kirkwood/Makefile b/arch/arm/cpu/arm926ejs/kirkwood/Makefile new file mode 100644 index 0000000000..fc2cc03001 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/kirkwood/Makefile @@ -0,0 +1,49 @@ +# +# (C) Copyright 2009 +# Marvell Semiconductor +# Written-by: Prafulla Wadaskar +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +COBJS-y = cpu.o +COBJS-y += dram.o +COBJS-y += mpp.o +COBJS-y += timer.o + +SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm926ejs/kirkwood/cpu.c b/arch/arm/cpu/arm926ejs/kirkwood/cpu.c new file mode 100644 index 0000000000..6fc3902580 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/kirkwood/cpu.c @@ -0,0 +1,387 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor + * Written-by: Prafulla Wadaskar + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include + +#define BUFLEN 16 + +void reset_cpu(unsigned long ignored) +{ + struct kwcpu_registers *cpureg = + (struct kwcpu_registers *)KW_CPU_REG_BASE; + + writel(readl(&cpureg->rstoutn_mask) | (1 << 2), + &cpureg->rstoutn_mask); + writel(readl(&cpureg->sys_soft_rst) | 1, + &cpureg->sys_soft_rst); + while (1) ; +} + +/* + * Generates Ramdom hex number reading some time varient system registers + * and using md5 algorithm + */ +unsigned char get_random_hex(void) +{ + int i; + u32 inbuf[BUFLEN]; + u8 outbuf[BUFLEN]; + + /* + * in case of 88F6281/88F6192 A0, + * Bit7 need to reset to generate random values in KW_REG_UNDOC_0x1470 + * Soc reg offsets KW_REG_UNDOC_0x1470 and KW_REG_UNDOC_0x1478 are reserved regs and + * Does not have names at this moment (no errata available) + */ + writel(readl(KW_REG_UNDOC_0x1478) & ~(1 << 7), KW_REG_UNDOC_0x1478); + for (i = 0; i < BUFLEN; i++) { + inbuf[i] = readl(KW_REG_UNDOC_0x1470); + } + md5((u8 *) inbuf, (BUFLEN * sizeof(u32)), outbuf); + return outbuf[outbuf[7] % 0x0f]; +} + +/* + * Window Size + * Used with the Base register to set the address window size and location. + * Must be programmed from LSB to MSB as sequence of ones followed by + * sequence of zeros. The number of ones specifies the size of the window in + * 64 KByte granularity (e.g., a value of 0x00FF specifies 256 = 16 MByte). + * NOTE: A value of 0x0 specifies 64-KByte size. + */ +unsigned int kw_winctrl_calcsize(unsigned int sizeval) +{ + int i; + unsigned int j = 0; + u32 val = sizeval >> 1; + + for (i = 0; val > 0x10000; i++) { + j |= (1 << i); + val = val >> 1; + } + return (0x0000ffff & j); +} + +/* + * kw_config_adr_windows - Configure address Windows + * + * There are 8 address windows supported by Kirkwood Soc to addess different + * devices. Each window can be configured for size, BAR and remap addr + * Below configuration is standard for most of the cases + * + * If remap function not used, remap_lo must be set as base + * + * Reference Documentation: + * Mbus-L to Mbus Bridge Registers Configuration. + * (Sec 25.1 and 25.3 of Datasheet) + */ +int kw_config_adr_windows(void) +{ + struct kwwin_registers *winregs = + (struct kwwin_registers *)KW_CPU_WIN_BASE; + + /* Window 0: PCIE MEM address space */ + writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 256, KWCPU_TARGET_PCIE, + KWCPU_ATTR_PCIE_MEM, KWCPU_WIN_ENABLE), &winregs[0].ctrl); + + writel(KW_DEFADR_PCI_MEM, &winregs[0].base); + writel(KW_DEFADR_PCI_MEM, &winregs[0].remap_lo); + writel(0x0, &winregs[0].remap_hi); + + /* Window 1: PCIE IO address space */ + writel(KWCPU_WIN_CTRL_DATA(1024 * 64, KWCPU_TARGET_PCIE, + KWCPU_ATTR_PCIE_IO, KWCPU_WIN_ENABLE), &winregs[1].ctrl); + writel(KW_DEFADR_PCI_IO, &winregs[1].base); + writel(KW_DEFADR_PCI_IO_REMAP, &winregs[1].remap_lo); + writel(0x0, &winregs[1].remap_hi); + + /* Window 2: NAND Flash address space */ + writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 128, KWCPU_TARGET_MEMORY, + KWCPU_ATTR_NANDFLASH, KWCPU_WIN_ENABLE), &winregs[2].ctrl); + writel(KW_DEFADR_NANDF, &winregs[2].base); + writel(KW_DEFADR_NANDF, &winregs[2].remap_lo); + writel(0x0, &winregs[2].remap_hi); + + /* Window 3: SPI Flash address space */ + writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 128, KWCPU_TARGET_MEMORY, + KWCPU_ATTR_SPIFLASH, KWCPU_WIN_ENABLE), &winregs[3].ctrl); + writel(KW_DEFADR_SPIF, &winregs[3].base); + writel(KW_DEFADR_SPIF, &winregs[3].remap_lo); + writel(0x0, &winregs[3].remap_hi); + + /* Window 4: BOOT Memory address space */ + writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 128, KWCPU_TARGET_MEMORY, + KWCPU_ATTR_BOOTROM, KWCPU_WIN_ENABLE), &winregs[4].ctrl); + writel(KW_DEFADR_BOOTROM, &winregs[4].base); + + /* Window 5: Security SRAM address space */ + writel(KWCPU_WIN_CTRL_DATA(1024 * 64, KWCPU_TARGET_SASRAM, + KWCPU_ATTR_SASRAM, KWCPU_WIN_ENABLE), &winregs[5].ctrl); + writel(KW_DEFADR_SASRAM, &winregs[5].base); + + /* Window 6-7: Disabled */ + writel(KWCPU_WIN_DISABLE, &winregs[6].ctrl); + writel(KWCPU_WIN_DISABLE, &winregs[7].ctrl); + + return 0; +} + +/* + * kw_config_gpio - GPIO configuration + */ +void kw_config_gpio(u32 gpp0_oe_val, u32 gpp1_oe_val, u32 gpp0_oe, u32 gpp1_oe) +{ + struct kwgpio_registers *gpio0reg = + (struct kwgpio_registers *)KW_GPIO0_BASE; + struct kwgpio_registers *gpio1reg = + (struct kwgpio_registers *)KW_GPIO1_BASE; + + /* Init GPIOS to default values as per board requirement */ + writel(gpp0_oe_val, &gpio0reg->dout); + writel(gpp1_oe_val, &gpio1reg->dout); + writel(gpp0_oe, &gpio0reg->oe); + writel(gpp1_oe, &gpio1reg->oe); +} + +/* + * kw_config_mpp - Multi-Purpose Pins Functionality configuration + * + * Each MPP can be configured to different functionality through + * MPP control register, ref (sec 6.1 of kirkwood h/w specification) + * + * There are maximum 64 Multi-Pourpose Pins on Kirkwood + * Each MPP functionality can be configuration by a 4bit value + * of MPP control reg, the value and associated functionality depends + * upon used SoC varient + */ +int kw_config_mpp(u32 mpp0_7, u32 mpp8_15, u32 mpp16_23, u32 mpp24_31, + u32 mpp32_39, u32 mpp40_47, u32 mpp48_55) +{ + u32 *mppreg = (u32 *) KW_MPP_BASE; + + /* program mpp registers */ + writel(mpp0_7, &mppreg[0]); + writel(mpp8_15, &mppreg[1]); + writel(mpp16_23, &mppreg[2]); + writel(mpp24_31, &mppreg[3]); + writel(mpp32_39, &mppreg[4]); + writel(mpp40_47, &mppreg[5]); + writel(mpp48_55, &mppreg[6]); + return 0; +} + +/* + * SYSRSTn Duration Counter Support + * + * Kirkwood SoC implements a hardware-based SYSRSTn duration counter. + * When SYSRSTn is asserted low, a SYSRSTn duration counter is running. + * The SYSRSTn duration counter is useful for implementing a manufacturer + * or factory reset. Upon a long reset assertion that is greater than a + * pre-configured environment variable value for sysrstdelay, + * The counter value is stored in the SYSRSTn Length Counter Register + * The counter is based on the 25-MHz reference clock (40ns) + * It is a 29-bit counter, yielding a maximum counting duration of + * 2^29/25 MHz (21.4 seconds). When the counter reach its maximum value, + * it remains at this value until counter reset is triggered by setting + * bit 31 of KW_REG_SYSRST_CNT + */ +static void kw_sysrst_action(void) +{ + int ret; + char *s = getenv("sysrstcmd"); + + if (!s) { + debug("Error.. %s failed, check sysrstcmd\n", + __FUNCTION__); + return; + } + + debug("Starting %s process...\n", __FUNCTION__); +#if !defined(CONFIG_SYS_HUSH_PARSER) + ret = run_command (s, 0); +#else + ret = parse_string_outer(s, FLAG_PARSE_SEMICOLON + | FLAG_EXIT_FROM_LOOP); +#endif + if (ret < 0) + debug("Error.. %s failed\n", __FUNCTION__); + else + debug("%s process finished\n", __FUNCTION__); +} + +static void kw_sysrst_check(void) +{ + u32 sysrst_cnt, sysrst_dly; + char *s; + + /* + * no action if sysrstdelay environment variable is not defined + */ + s = getenv("sysrstdelay"); + if (s == NULL) + return; + + /* read sysrstdelay value */ + sysrst_dly = (u32) simple_strtoul(s, NULL, 10); + + /* read SysRst Length counter register (bits 28:0) */ + sysrst_cnt = (0x1fffffff & readl(KW_REG_SYSRST_CNT)); + debug("H/w Rst hold time: %d.%d secs\n", + sysrst_cnt / SYSRST_CNT_1SEC_VAL, + sysrst_cnt % SYSRST_CNT_1SEC_VAL); + + /* clear the counter for next valid read*/ + writel(1 << 31, KW_REG_SYSRST_CNT); + + /* + * sysrst_action: + * if H/w Reset key is pressed and hold for time + * more than sysrst_dly in seconds + */ + if (sysrst_cnt >= SYSRST_CNT_1SEC_VAL * sysrst_dly) + kw_sysrst_action(); +} + +#if defined(CONFIG_DISPLAY_CPUINFO) +int print_cpuinfo(void) +{ + char *name = "Unknown"; + + switch (readl(KW_REG_DEVICE_ID) & 0x03) { + case 1: + name = "88F6192_A0"; + break; + case 2: + name = "88F6281_A0"; + break; + default: + printf("SoC: Unsupported Kirkwood\n"); + return -1; + } + printf("SoC: Kirkwood %s\n", name); + return 0; +} +#endif /* CONFIG_DISPLAY_CPUINFO */ + +#ifdef CONFIG_ARCH_CPU_INIT +int arch_cpu_init(void) +{ + u32 reg; + struct kwcpu_registers *cpureg = + (struct kwcpu_registers *)KW_CPU_REG_BASE; + + /* Linux expects` the internal registers to be at 0xf1000000 */ + writel(KW_REGS_PHY_BASE, KW_OFFSET_REG); + + /* Enable and invalidate L2 cache in write through mode */ + writel(readl(&cpureg->l2_cfg) | 0x18, &cpureg->l2_cfg); + invalidate_l2_cache(); + + kw_config_adr_windows(); + +#ifdef CONFIG_KIRKWOOD_RGMII_PAD_1V8 + /* + * Configures the I/O voltage of the pads connected to Egigabit + * Ethernet interface to 1.8V + * By defult it is set to 3.3V + */ + reg = readl(KW_REG_MPP_OUT_DRV_REG); + reg |= (1 << 7); + writel(reg, KW_REG_MPP_OUT_DRV_REG); +#endif +#ifdef CONFIG_KIRKWOOD_EGIGA_INIT + /* + * Set egiga port0/1 in normal functional mode + * This is required becasue on kirkwood by default ports are in reset mode + * OS egiga driver may not have provision to set them in normal mode + * and if u-boot is build without network support, network may fail at OS level + */ + reg = readl(KWGBE_PORT_SERIAL_CONTROL1_REG(0)); + reg &= ~(1 << 4); /* Clear PortReset Bit */ + writel(reg, (KWGBE_PORT_SERIAL_CONTROL1_REG(0))); + reg = readl(KWGBE_PORT_SERIAL_CONTROL1_REG(1)); + reg &= ~(1 << 4); /* Clear PortReset Bit */ + writel(reg, (KWGBE_PORT_SERIAL_CONTROL1_REG(1))); +#endif +#ifdef CONFIG_KIRKWOOD_PCIE_INIT + /* + * Enable PCI Express Port0 + */ + reg = readl(&cpureg->ctrl_stat); + reg |= (1 << 0); /* Set PEX0En Bit */ + writel(reg, &cpureg->ctrl_stat); +#endif + return 0; +} +#endif /* CONFIG_ARCH_CPU_INIT */ + +/* + * SOC specific misc init + */ +#if defined(CONFIG_ARCH_MISC_INIT) +int arch_misc_init(void) +{ + volatile u32 temp; + + /*CPU streaming & write allocate */ + temp = readfr_extra_feature_reg(); + temp &= ~(1 << 28); /* disable wr alloc */ + writefr_extra_feature_reg(temp); + + temp = readfr_extra_feature_reg(); + temp &= ~(1 << 29); /* streaming disabled */ + writefr_extra_feature_reg(temp); + + /* L2Cache settings */ + temp = readfr_extra_feature_reg(); + /* Disable L2C pre fetch - Set bit 24 */ + temp |= (1 << 24); + /* enable L2C - Set bit 22 */ + temp |= (1 << 22); + writefr_extra_feature_reg(temp); + + icache_enable(); + /* Change reset vector to address 0x0 */ + temp = get_cr(); + set_cr(temp & ~CR_V); + + /* checks and execute resset to factory event */ + kw_sysrst_check(); + + return 0; +} +#endif /* CONFIG_ARCH_MISC_INIT */ + +#ifdef CONFIG_KIRKWOOD_EGIGA +int cpu_eth_init(bd_t *bis) +{ + kirkwood_egiga_initialize(bis); + return 0; +} +#endif diff --git a/arch/arm/cpu/arm926ejs/kirkwood/dram.c b/arch/arm/cpu/arm926ejs/kirkwood/dram.c new file mode 100644 index 0000000000..8f2a18af6b --- /dev/null +++ b/arch/arm/cpu/arm926ejs/kirkwood/dram.c @@ -0,0 +1,58 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor + * Written-by: Prafulla Wadaskar + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include +#include + +#define KW_REG_CPUCS_WIN_BAR(x) (KW_REGISTER(0x1500) + (x * 0x08)) +#define KW_REG_CPUCS_WIN_SZ(x) (KW_REGISTER(0x1504) + (x * 0x08)) +/* + * kw_sdram_bar - reads SDRAM Base Address Register + */ +u32 kw_sdram_bar(enum memory_bank bank) +{ + u32 result = 0; + u32 enable = 0x01 & readl(KW_REG_CPUCS_WIN_SZ(bank)); + + if ((!enable) || (bank > BANK3)) + return 0; + + result = readl(KW_REG_CPUCS_WIN_BAR(bank)); + return result; +} + +/* + * kw_sdram_bs - reads SDRAM Bank size + */ +u32 kw_sdram_bs(enum memory_bank bank) +{ + u32 result = 0; + u32 enable = 0x01 & readl(KW_REG_CPUCS_WIN_SZ(bank)); + + if ((!enable) || (bank > BANK3)) + return 0; + result = 0xff000000 & readl(KW_REG_CPUCS_WIN_SZ(bank)); + result += 0x01000000; + return result; +} diff --git a/arch/arm/cpu/arm926ejs/kirkwood/mpp.c b/arch/arm/cpu/arm926ejs/kirkwood/mpp.c new file mode 100644 index 0000000000..b2f0ad55e3 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/kirkwood/mpp.c @@ -0,0 +1,80 @@ +/* + * arch/arm/mach-kirkwood/mpp.c + * + * MPP functions for Marvell Kirkwood SoCs + * Referenced from Linux kernel source + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include + +static u32 kirkwood_variant(void) +{ + switch (readl(KW_REG_DEVICE_ID) & 0x03) { + case 1: + return MPP_F6192_MASK; + case 2: + return MPP_F6281_MASK; + default: + debug("MPP setup: unknown kirkwood variant\n"); + return 0; + } +} + +#define MPP_CTRL(i) (KW_MPP_BASE + (i* 4)) +#define MPP_NR_REGS (1 + MPP_MAX/8) + +void kirkwood_mpp_conf(u32 *mpp_list) +{ + u32 mpp_ctrl[MPP_NR_REGS]; + unsigned int variant_mask; + int i; + + variant_mask = kirkwood_variant(); + if (!variant_mask) + return; + + debug( "initial MPP regs:"); + for (i = 0; i < MPP_NR_REGS; i++) { + mpp_ctrl[i] = readl(MPP_CTRL(i)); + debug(" %08x", mpp_ctrl[i]); + } + debug("\n"); + + + while (*mpp_list) { + unsigned int num = MPP_NUM(*mpp_list); + unsigned int sel = MPP_SEL(*mpp_list); + int shift; + + if (num > MPP_MAX) { + debug("kirkwood_mpp_conf: invalid MPP " + "number (%u)\n", num); + continue; + } + if (!(*mpp_list & variant_mask)) { + debug("kirkwood_mpp_conf: requested MPP%u config " + "unavailable on this hardware\n", num); + continue; + } + + shift = (num & 7) << 2; + mpp_ctrl[num / 8] &= ~(0xf << shift); + mpp_ctrl[num / 8] |= sel << shift; + + mpp_list++; + } + + debug(" final MPP regs:"); + for (i = 0; i < MPP_NR_REGS; i++) { + writel(mpp_ctrl[i], MPP_CTRL(i)); + debug(" %08x", mpp_ctrl[i]); + } + debug("\n"); + +} diff --git a/arch/arm/cpu/arm926ejs/kirkwood/timer.c b/arch/arm/cpu/arm926ejs/kirkwood/timer.c new file mode 100644 index 0000000000..2ec6a93807 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/kirkwood/timer.c @@ -0,0 +1,168 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * Written-by: Prafulla Wadaskar + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include +#include + +#define UBOOT_CNTR 0 /* counter to use for uboot timer */ + +/* Timer reload and current value registers */ +struct kwtmr_val { + u32 reload; /* Timer reload reg */ + u32 val; /* Timer value reg */ +}; + +/* Timer registers */ +struct kwtmr_registers { + u32 ctrl; /* Timer control reg */ + u32 pad[3]; + struct kwtmr_val tmr[2]; + u32 wdt_reload; + u32 wdt_val; +}; + +struct kwtmr_registers *kwtmr_regs = (struct kwtmr_registers *)KW_TIMER_BASE; + +/* + * ARM Timers Registers Map + */ +#define CNTMR_CTRL_REG &kwtmr_regs->ctrl +#define CNTMR_RELOAD_REG(tmrnum) &kwtmr_regs->tmr[tmrnum].reload +#define CNTMR_VAL_REG(tmrnum) &kwtmr_regs->tmr[tmrnum].val + +/* + * ARM Timers Control Register + * CPU_TIMERS_CTRL_REG (CTCR) + */ +#define CTCR_ARM_TIMER_EN_OFFS(cntr) (cntr * 2) +#define CTCR_ARM_TIMER_EN_MASK(cntr) (1 << CTCR_ARM_TIMER_EN_OFFS) +#define CTCR_ARM_TIMER_EN(cntr) (1 << CTCR_ARM_TIMER_EN_OFFS(cntr)) +#define CTCR_ARM_TIMER_DIS(cntr) (0 << CTCR_ARM_TIMER_EN_OFFS(cntr)) + +#define CTCR_ARM_TIMER_AUTO_OFFS(cntr) ((cntr * 2) + 1) +#define CTCR_ARM_TIMER_AUTO_MASK(cntr) (1 << 1) +#define CTCR_ARM_TIMER_AUTO_EN(cntr) (1 << CTCR_ARM_TIMER_AUTO_OFFS(cntr)) +#define CTCR_ARM_TIMER_AUTO_DIS(cntr) (0 << CTCR_ARM_TIMER_AUTO_OFFS(cntr)) + +/* + * ARM Timer\Watchdog Reload Register + * CNTMR_RELOAD_REG (TRR) + */ +#define TRG_ARM_TIMER_REL_OFFS 0 +#define TRG_ARM_TIMER_REL_MASK 0xffffffff + +/* + * ARM Timer\Watchdog Register + * CNTMR_VAL_REG (TVRG) + */ +#define TVR_ARM_TIMER_OFFS 0 +#define TVR_ARM_TIMER_MASK 0xffffffff +#define TVR_ARM_TIMER_MAX 0xffffffff +#define TIMER_LOAD_VAL 0xffffffff + +#define READ_TIMER (readl(CNTMR_VAL_REG(UBOOT_CNTR)) / \ + (CONFIG_SYS_TCLK / 1000)) + +static ulong timestamp; +static ulong lastdec; + +void reset_timer_masked(void) +{ + /* reset time */ + lastdec = READ_TIMER; + timestamp = 0; +} + +ulong get_timer_masked(void) +{ + ulong now = READ_TIMER; + + if (lastdec >= now) { + /* normal mode */ + timestamp += lastdec - now; + } else { + /* we have an overflow ... */ + timestamp += lastdec + + (TIMER_LOAD_VAL / (CONFIG_SYS_TCLK / 1000)) - now; + } + lastdec = now; + + return timestamp; +} + +void reset_timer(void) +{ + reset_timer_masked(); +} + +ulong get_timer(ulong base) +{ + return get_timer_masked() - base; +} + +void set_timer(ulong t) +{ + timestamp = t; +} + +void __udelay(unsigned long usec) +{ + uint current; + ulong delayticks; + + current = readl(CNTMR_VAL_REG(UBOOT_CNTR)); + delayticks = (usec * (CONFIG_SYS_TCLK / 1000000)); + + if (current < delayticks) { + delayticks -= current; + while (readl(CNTMR_VAL_REG(UBOOT_CNTR)) < current) ; + while ((TIMER_LOAD_VAL - delayticks) < + readl(CNTMR_VAL_REG(UBOOT_CNTR))) ; + } else { + while (readl(CNTMR_VAL_REG(UBOOT_CNTR)) > + (current - delayticks)) ; + } +} + +/* + * init the counter + */ +int timer_init(void) +{ + unsigned int cntmrctrl; + + /* load value into timer */ + writel(TIMER_LOAD_VAL, CNTMR_RELOAD_REG(UBOOT_CNTR)); + writel(TIMER_LOAD_VAL, CNTMR_VAL_REG(UBOOT_CNTR)); + + /* enable timer in auto reload mode */ + cntmrctrl = readl(CNTMR_CTRL_REG); + cntmrctrl |= CTCR_ARM_TIMER_EN(UBOOT_CNTR); + cntmrctrl |= CTCR_ARM_TIMER_AUTO_EN(UBOOT_CNTR); + writel(cntmrctrl, CNTMR_CTRL_REG); + + /* init the timestamp and lastdec value */ + reset_timer_masked(); + + return 0; +} diff --git a/arch/arm/cpu/arm926ejs/mx25/Makefile b/arch/arm/cpu/arm926ejs/mx25/Makefile new file mode 100644 index 0000000000..76f01791a0 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/mx25/Makefile @@ -0,0 +1,46 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +COBJS = generic.o timer.o +MX27OBJS = reset.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +SRCS += $(addprefix $(SRCTREE)/arch/arm/cpu/arm926ejs/mx27/,$(MX27OBJS:.o=.c)) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS) $(MX27OBJS)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm926ejs/mx25/generic.c b/arch/arm/cpu/arm926ejs/mx25/generic.c new file mode 100644 index 0000000000..694841dd10 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/mx25/generic.c @@ -0,0 +1,263 @@ +/* + * (C) Copyright 2009 DENX Software Engineering + * Author: John Rigby + * + * Based on mx27/generic.c: + * Copyright (c) 2008 Eric Jarrige + * Copyright (c) 2009 Ilya Yanok + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_MXC_MMC +#include +#endif + +/* + * get the system pll clock in Hz + * + * mfi + mfn / (mfd +1) + * f = 2 * f_ref * -------------------- + * pd + 1 + */ +static unsigned int imx_decode_pll (unsigned int pll, unsigned int f_ref) +{ + unsigned int mfi = (pll >> CCM_PLL_MFI_SHIFT) + & CCM_PLL_MFI_MASK; + unsigned int mfn = (pll >> CCM_PLL_MFN_SHIFT) + & CCM_PLL_MFN_MASK; + unsigned int mfd = (pll >> CCM_PLL_MFD_SHIFT) + & CCM_PLL_MFD_MASK; + unsigned int pd = (pll >> CCM_PLL_PD_SHIFT) + & CCM_PLL_PD_MASK; + + mfi = mfi <= 5 ? 5 : mfi; + + return lldiv (2 * (u64) f_ref * (mfi * (mfd + 1) + mfn), + (mfd + 1) * (pd + 1)); +} + +static ulong imx_get_mpllclk (void) +{ + struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE; + ulong fref = 24000000; + + return imx_decode_pll (readl (&ccm->mpctl), fref); +} + +ulong imx_get_armclk (void) +{ + struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE; + ulong cctl = readl (&ccm->cctl); + ulong fref = imx_get_mpllclk (); + ulong div; + + if (cctl & CCM_CCTL_ARM_SRC) + fref = lldiv ((fref * 3), 4); + + div = ((cctl >> CCM_CCTL_ARM_DIV_SHIFT) + & CCM_CCTL_ARM_DIV_MASK) + 1; + + return lldiv (fref, div); +} + +ulong imx_get_ahbclk (void) +{ + struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE; + ulong cctl = readl (&ccm->cctl); + ulong fref = imx_get_armclk (); + ulong div; + + div = ((cctl >> CCM_CCTL_AHB_DIV_SHIFT) + & CCM_CCTL_AHB_DIV_MASK) + 1; + + return lldiv (fref, div); +} + +ulong imx_get_perclk (int clk) +{ + struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE; + ulong fref = imx_get_ahbclk (); + ulong div; + + div = readl (&ccm->pcdr[CCM_PERCLK_REG (clk)]); + div = ((div >> CCM_PERCLK_SHIFT (clk)) & CCM_PERCLK_MASK) + 1; + + return lldiv (fref, div); +} + +#if defined(CONFIG_DISPLAY_CPUINFO) +int print_cpuinfo (void) +{ + char buf[32]; + + printf ("CPU: Freescale i.MX25 at %s MHz\n\n", + strmhz (buf, imx_get_mpllclk ())); + return 0; +} +#endif + +int cpu_eth_init (bd_t * bis) +{ +#if defined(CONFIG_FEC_MXC) + struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE; + ulong val; + + val = readl (&ccm->cgr0); + val |= (1 << 23); + writel (val, &ccm->cgr0); + return fecmxc_initialize (bis); +#else + return 0; +#endif +} + +/* + * Initializes on-chip MMC controllers. + * to override, implement board_mmc_init() + */ +int cpu_mmc_init (bd_t * bis) +{ +#ifdef CONFIG_MXC_MMC + return mxc_mmc_init (bis); +#else + return 0; +#endif +} + +#ifdef CONFIG_MXC_UART +void mx25_uart_init_pins (void) +{ + struct iomuxc_mux_ctl *muxctl; + struct iomuxc_pad_ctl *padctl; + u32 inpadctl; + u32 outpadctl; + u32 muxmode0; + + muxctl = (struct iomuxc_mux_ctl *)IMX_IOPADMUX_BASE; + padctl = (struct iomuxc_pad_ctl *)IMX_IOPADCTL_BASE; + muxmode0 = MX25_PIN_MUX_MODE (0); + /* + * set up input pins with hysteresis and 100K pull-ups + */ + inpadctl = MX25_PIN_PAD_CTL_HYS + | MX25_PIN_PAD_CTL_PKE + | MX25_PIN_PAD_CTL_PUE | MX25_PIN_PAD_CTL_100K_PU; + + /* + * set up output pins with 100K pull-downs + * FIXME: need to revisit this + * PUE is ignored if PKE is not set + * so the right value here is likely + * 0x0 for no pull up/down + * or + * 0xc0 for 100k pull down + */ + outpadctl = MX25_PIN_PAD_CTL_PUE | MX25_PIN_PAD_CTL_100K_PD; + + /* UART1 */ + /* rxd */ + writel (muxmode0, &muxctl->pad_uart1_rxd); + writel (inpadctl, &padctl->pad_uart1_rxd); + + /* txd */ + writel (muxmode0, &muxctl->pad_uart1_txd); + writel (outpadctl, &padctl->pad_uart1_txd); + + /* rts */ + writel (muxmode0, &muxctl->pad_uart1_rts); + writel (outpadctl, &padctl->pad_uart1_rts); + + /* cts */ + writel (muxmode0, &muxctl->pad_uart1_cts); + writel (inpadctl, &padctl->pad_uart1_cts); +} +#endif /* CONFIG_MXC_UART */ + +#ifdef CONFIG_FEC_MXC +void mx25_fec_init_pins (void) +{ + struct iomuxc_mux_ctl *muxctl; + struct iomuxc_pad_ctl *padctl; + u32 inpadctl_100kpd; + u32 inpadctl_22kpu; + u32 outpadctl; + u32 muxmode0; + + muxctl = (struct iomuxc_mux_ctl *)IMX_IOPADMUX_BASE; + padctl = (struct iomuxc_pad_ctl *)IMX_IOPADCTL_BASE; + muxmode0 = MX25_PIN_MUX_MODE (0); + inpadctl_100kpd = MX25_PIN_PAD_CTL_HYS + | MX25_PIN_PAD_CTL_PKE + | MX25_PIN_PAD_CTL_PUE | MX25_PIN_PAD_CTL_100K_PD; + inpadctl_22kpu = MX25_PIN_PAD_CTL_HYS + | MX25_PIN_PAD_CTL_PKE + | MX25_PIN_PAD_CTL_PUE | MX25_PIN_PAD_CTL_22K_PU; + /* + * set up output pins with 100K pull-downs + * FIXME: need to revisit this + * PUE is ignored if PKE is not set + * so the right value here is likely + * 0x0 for no pull + * or + * 0xc0 for 100k pull down + */ + outpadctl = MX25_PIN_PAD_CTL_PUE | MX25_PIN_PAD_CTL_100K_PD; + + /* FEC_TX_CLK */ + writel (muxmode0, &muxctl->pad_fec_tx_clk); + writel (inpadctl_100kpd, &padctl->pad_fec_tx_clk); + + /* FEC_RX_DV */ + writel (muxmode0, &muxctl->pad_fec_rx_dv); + writel (inpadctl_100kpd, &padctl->pad_fec_rx_dv); + + /* FEC_RDATA0 */ + writel (muxmode0, &muxctl->pad_fec_rdata0); + writel (inpadctl_100kpd, &padctl->pad_fec_rdata0); + + /* FEC_TDATA0 */ + writel (muxmode0, &muxctl->pad_fec_tdata0); + writel (outpadctl, &padctl->pad_fec_tdata0); + + /* FEC_TX_EN */ + writel (muxmode0, &muxctl->pad_fec_tx_en); + writel (outpadctl, &padctl->pad_fec_tx_en); + + /* FEC_MDC */ + writel (muxmode0, &muxctl->pad_fec_mdc); + writel (outpadctl, &padctl->pad_fec_mdc); + + /* FEC_MDIO */ + writel (muxmode0, &muxctl->pad_fec_mdio); + writel (inpadctl_22kpu, &padctl->pad_fec_mdio); + + /* FEC_RDATA1 */ + writel (muxmode0, &muxctl->pad_fec_rdata1); + writel (inpadctl_100kpd, &padctl->pad_fec_rdata1); + + /* FEC_TDATA1 */ + writel (muxmode0, &muxctl->pad_fec_tdata1); + writel (outpadctl, &padctl->pad_fec_tdata1); + +} +#endif /* CONFIG_FEC_MXC */ diff --git a/arch/arm/cpu/arm926ejs/mx25/reset.c b/arch/arm/cpu/arm926ejs/mx25/reset.c new file mode 100644 index 0000000000..1e33150eb9 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/mx25/reset.c @@ -0,0 +1,56 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * (C) Copyright 2009 + * Ilya Yanok, Emcraft Systems Ltd, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +/* + * Reset the cpu by setting up the watchdog timer and let it time out + */ +void reset_cpu (ulong ignored) +{ + struct wdog_regs *regs = (struct wdog_regs *)IMX_WDT_BASE; + /* Disable watchdog and set Time-Out field to 0 */ + writel (0x00000000, ®s->wcr); + + /* Write Service Sequence */ + writel (0x00005555, ®s->wsr); + writel (0x0000AAAA, ®s->wsr); + + /* Enable watchdog */ + writel (WCR_WDE, ®s->wcr); + + while (1) ; +} diff --git a/arch/arm/cpu/arm926ejs/mx25/timer.c b/arch/arm/cpu/arm926ejs/mx25/timer.c new file mode 100644 index 0000000000..11d41a8bf9 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/mx25/timer.c @@ -0,0 +1,187 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * (C) Copyright 2009 + * Ilya Yanok, Emcraft Systems Ltd, + * + * (C) Copyright 2009 DENX Software Engineering + * Author: John Rigby + * Add support for MX25 + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include + +static ulong timestamp; +static ulong lastinc; + +/* + * "time" is measured in 1 / CONFIG_SYS_HZ seconds, + * "tick" is internal timer period + */ +#ifdef CONFIG_MX25_TIMER_HIGH_PRECISION +/* ~0.4% error - measured with stop-watch on 100s boot-delay */ +static inline unsigned long long tick_to_time(unsigned long long tick) +{ + tick *= CONFIG_SYS_HZ; + do_div(tick, CONFIG_MX25_CLK32); + return tick; +} + +static inline unsigned long long time_to_tick(unsigned long long time) +{ + time *= CONFIG_MX25_CLK32; + do_div(time, CONFIG_SYS_HZ); + return time; +} + +static inline unsigned long long us_to_tick(unsigned long long us) +{ + us = us * CONFIG_MX25_CLK32 + 999999; + do_div(us, 1000000); + return us; +} +#else +/* ~2% error */ +#define TICK_PER_TIME ((CONFIG_MX25_CLK32 + CONFIG_SYS_HZ / 2) / \ + CONFIG_SYS_HZ) +#define US_PER_TICK (1000000 / CONFIG_MX25_CLK32) + +static inline unsigned long long tick_to_time(unsigned long long tick) +{ + do_div(tick, TICK_PER_TIME); + return tick; +} + +static inline unsigned long long time_to_tick(unsigned long long time) +{ + return time * TICK_PER_TIME; +} + +static inline unsigned long long us_to_tick(unsigned long long us) +{ + us += US_PER_TICK - 1; + do_div(us, US_PER_TICK); + return us; +} +#endif + +/* nothing really to do with interrupts, just starts up a counter. */ +/* The 32KHz 32-bit timer overruns in 134217 seconds */ +int timer_init(void) +{ + int i; + struct gpt_regs *gpt = (struct gpt_regs *)IMX_GPT1_BASE; + struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE; + + /* setup GP Timer 1 */ + writel(GPT_CTRL_SWR, &gpt->ctrl); + + writel(readl(&ccm->cgr1) | CCM_CGR1_GPT1, &ccm->cgr1); + + for (i = 0; i < 100; i++) + writel(0, &gpt->ctrl); /* We have no udelay by now */ + writel(0, &gpt->pre); /* prescaler = 1 */ + /* Freerun Mode, 32KHz input */ + writel(readl(&gpt->ctrl) | GPT_CTRL_CLKSOURCE_32 | GPT_CTRL_FRR, + &gpt->ctrl); + writel(readl(&gpt->ctrl) | GPT_CTRL_TEN, &gpt->ctrl); + + return 0; +} + +void reset_timer_masked(void) +{ + struct gpt_regs *gpt = (struct gpt_regs *)IMX_GPT1_BASE; + /* reset time */ + /* capture current incrementer value time */ + lastinc = readl(&gpt->counter); + timestamp = 0; /* start "advancing" time stamp from 0 */ +} + +void reset_timer(void) +{ + reset_timer_masked(); +} + +unsigned long long get_ticks (void) +{ + struct gpt_regs *gpt = (struct gpt_regs *)IMX_GPT1_BASE; + ulong now = readl(&gpt->counter); /* current tick value */ + + if (now >= lastinc) { + /* + * normal mode (non roll) + * move stamp forward with absolut diff ticks + */ + timestamp += (now - lastinc); + } else { + /* we have rollover of incrementer */ + timestamp += (0xFFFFFFFF - lastinc) + now; + } + lastinc = now; + return timestamp; +} + +ulong get_timer_masked (void) +{ + /* + * get_ticks() returns a long long (64 bit), it wraps in + * 2^64 / CONFIG_MX25_CLK32 = 2^64 / 2^15 = 2^49 ~ 5 * 10^14 (s) ~ + * 5 * 10^9 days... and get_ticks() * CONFIG_SYS_HZ wraps in + * 5 * 10^6 days - long enough. + */ + return tick_to_time(get_ticks()); +} + +ulong get_timer (ulong base) +{ + return get_timer_masked () - base; +} + +void set_timer (ulong t) +{ + timestamp = time_to_tick(t); +} + +/* delay x useconds AND preserve advance timstamp value */ +void __udelay (unsigned long usec) +{ + unsigned long long tmp; + ulong tmo; + + tmo = us_to_tick(usec); + tmp = get_ticks() + tmo; /* get current timestamp */ + + while (get_ticks() < tmp) /* loop till event */ + /*NOP*/; +} diff --git a/arch/arm/cpu/arm926ejs/mx27/Makefile b/arch/arm/cpu/arm926ejs/mx27/Makefile new file mode 100644 index 0000000000..67d1b0e303 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/mx27/Makefile @@ -0,0 +1,44 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +COBJS = generic.o reset.o timer.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm926ejs/mx27/generic.c b/arch/arm/cpu/arm926ejs/mx27/generic.c new file mode 100644 index 0000000000..30cf544712 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/mx27/generic.c @@ -0,0 +1,335 @@ +/* + * Copyright (c) 2008 Eric Jarrige + * Copyright (c) 2009 Ilya Yanok + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#ifdef CONFIG_MXC_MMC +#include +#endif + +/* + * get the system pll clock in Hz + * + * mfi + mfn / (mfd +1) + * f = 2 * f_ref * -------------------- + * pd + 1 + */ +unsigned int imx_decode_pll(unsigned int pll, unsigned int f_ref) +{ + unsigned int mfi = (pll >> 10) & 0xf; + unsigned int mfn = pll & 0x3ff; + unsigned int mfd = (pll >> 16) & 0x3ff; + unsigned int pd = (pll >> 26) & 0xf; + + mfi = mfi <= 5 ? 5 : mfi; + + return lldiv(2 * (u64)f_ref * (mfi * (mfd + 1) + mfn), + (mfd + 1) * (pd + 1)); +} + +static ulong clk_in_32k(void) +{ + return 1024 * CONFIG_MX27_CLK32; +} + +static ulong clk_in_26m(void) +{ + struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; + + if (readl(&pll->cscr) & CSCR_OSC26M_DIV1P5) { + /* divide by 1.5 */ + return 26000000 * 2 / 3; + } else { + return 26000000; + } +} + +ulong imx_get_mpllclk(void) +{ + struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; + ulong cscr = readl(&pll->cscr); + ulong fref; + + if (cscr & CSCR_MCU_SEL) + fref = clk_in_26m(); + else + fref = clk_in_32k(); + + return imx_decode_pll(readl(&pll->mpctl0), fref); +} + +ulong imx_get_armclk(void) +{ + struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; + ulong cscr = readl(&pll->cscr); + ulong fref = imx_get_mpllclk(); + ulong div; + + if (!(cscr & CSCR_ARM_SRC_MPLL)) + fref = lldiv((fref * 2), 3); + + div = ((cscr >> 12) & 0x3) + 1; + + return lldiv(fref, div); +} + +ulong imx_get_ahbclk(void) +{ + struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; + ulong cscr = readl(&pll->cscr); + ulong fref = imx_get_mpllclk(); + ulong div; + + div = ((cscr >> 8) & 0x3) + 1; + + return lldiv(fref * 2, 3 * div); +} + +ulong imx_get_spllclk(void) +{ + struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; + ulong cscr = readl(&pll->cscr); + ulong fref; + + if (cscr & CSCR_SP_SEL) + fref = clk_in_26m(); + else + fref = clk_in_32k(); + + return imx_decode_pll(readl(&pll->spctl0), fref); +} + +static ulong imx_decode_perclk(ulong div) +{ + return lldiv((imx_get_mpllclk() * 2), (div * 3)); +} + +ulong imx_get_perclk1(void) +{ + struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; + + return imx_decode_perclk((readl(&pll->pcdr1) & 0x3f) + 1); +} + +ulong imx_get_perclk2(void) +{ + struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; + + return imx_decode_perclk(((readl(&pll->pcdr1) >> 8) & 0x3f) + 1); +} + +ulong imx_get_perclk3(void) +{ + struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; + + return imx_decode_perclk(((readl(&pll->pcdr1) >> 16) & 0x3f) + 1); +} + +ulong imx_get_perclk4(void) +{ + struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; + + return imx_decode_perclk(((readl(&pll->pcdr1) >> 24) & 0x3f) + 1); +} + +#if defined(CONFIG_DISPLAY_CPUINFO) +int print_cpuinfo (void) +{ + char buf[32]; + + printf("CPU: Freescale i.MX27 at %s MHz\n\n", + strmhz(buf, imx_get_mpllclk())); + return 0; +} +#endif + +int cpu_eth_init(bd_t *bis) +{ +#if defined(CONFIG_FEC_MXC) + struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; + + /* enable FEC clock */ + writel(readl(&pll->pccr1) | PCCR1_HCLK_FEC, &pll->pccr1); + writel(readl(&pll->pccr0) | PCCR0_FEC_EN, &pll->pccr0); + return fecmxc_initialize(bis); +#else + return 0; +#endif +} + +/* + * Initializes on-chip MMC controllers. + * to override, implement board_mmc_init() + */ +int cpu_mmc_init(bd_t *bis) +{ +#ifdef CONFIG_MXC_MMC + return mxc_mmc_init(bis); +#else + return 0; +#endif +} + +void imx_gpio_mode(int gpio_mode) +{ + struct gpio_regs *regs = (struct gpio_regs *)IMX_GPIO_BASE; + unsigned int pin = gpio_mode & GPIO_PIN_MASK; + unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> GPIO_OCR_SHIFT; + unsigned int aout = (gpio_mode & GPIO_AOUT_MASK) >> GPIO_AOUT_SHIFT; + unsigned int bout = (gpio_mode & GPIO_BOUT_MASK) >> GPIO_BOUT_SHIFT; + unsigned int tmp; + + /* Pullup enable */ + if (gpio_mode & GPIO_PUEN) { + writel(readl(®s->port[port].puen) | (1 << pin), + ®s->port[port].puen); + } else { + writel(readl(®s->port[port].puen) & ~(1 << pin), + ®s->port[port].puen); + } + + /* Data direction */ + if (gpio_mode & GPIO_OUT) { + writel(readl(®s->port[port].ddir) | 1 << pin, + ®s->port[port].ddir); + } else { + writel(readl(®s->port[port].ddir) & ~(1 << pin), + ®s->port[port].ddir); + } + + /* Primary / alternate function */ + if (gpio_mode & GPIO_AF) { + writel(readl(®s->port[port].gpr) | (1 << pin), + ®s->port[port].gpr); + } else { + writel(readl(®s->port[port].gpr) & ~(1 << pin), + ®s->port[port].gpr); + } + + /* use as gpio? */ + if (!(gpio_mode & (GPIO_PF | GPIO_AF))) { + writel(readl(®s->port[port].gius) | (1 << pin), + ®s->port[port].gius); + } else { + writel(readl(®s->port[port].gius) & ~(1 << pin), + ®s->port[port].gius); + } + + /* Output / input configuration */ + if (pin < 16) { + tmp = readl(®s->port[port].ocr1); + tmp &= ~(3 << (pin * 2)); + tmp |= (ocr << (pin * 2)); + writel(tmp, ®s->port[port].ocr1); + + writel(readl(®s->port[port].iconfa1) & ~(3 << (pin * 2)), + ®s->port[port].iconfa1); + writel(readl(®s->port[port].iconfa1) | aout << (pin * 2), + ®s->port[port].iconfa1); + writel(readl(®s->port[port].iconfb1) & ~(3 << (pin * 2)), + ®s->port[port].iconfb1); + writel(readl(®s->port[port].iconfb1) | bout << (pin * 2), + ®s->port[port].iconfb1); + } else { + pin -= 16; + + tmp = readl(®s->port[port].ocr2); + tmp &= ~(3 << (pin * 2)); + tmp |= (ocr << (pin * 2)); + writel(tmp, ®s->port[port].ocr2); + + writel(readl(®s->port[port].iconfa2) & ~(3 << (pin * 2)), + ®s->port[port].iconfa2); + writel(readl(®s->port[port].iconfa2) | aout << (pin * 2), + ®s->port[port].iconfa2); + writel(readl(®s->port[port].iconfb2) & ~(3 << (pin * 2)), + ®s->port[port].iconfb2); + writel(readl(®s->port[port].iconfb2) | bout << (pin * 2), + ®s->port[port].iconfb2); + } +} + +#ifdef CONFIG_MXC_UART +void mx27_uart_init_pins(void) +{ + int i; + unsigned int mode[] = { + PE12_PF_UART1_TXD, + PE13_PF_UART1_RXD, + }; + + for (i = 0; i < ARRAY_SIZE(mode); i++) + imx_gpio_mode(mode[i]); + +} +#endif /* CONFIG_MXC_UART */ + +#ifdef CONFIG_FEC_MXC +void mx27_fec_init_pins(void) +{ + int i; + unsigned int mode[] = { + PD0_AIN_FEC_TXD0, + PD1_AIN_FEC_TXD1, + PD2_AIN_FEC_TXD2, + PD3_AIN_FEC_TXD3, + PD4_AOUT_FEC_RX_ER, + PD5_AOUT_FEC_RXD1, + PD6_AOUT_FEC_RXD2, + PD7_AOUT_FEC_RXD3, + PD8_AF_FEC_MDIO, + PD9_AIN_FEC_MDC | GPIO_PUEN, + PD10_AOUT_FEC_CRS, + PD11_AOUT_FEC_TX_CLK, + PD12_AOUT_FEC_RXD0, + PD13_AOUT_FEC_RX_DV, + PD14_AOUT_FEC_CLR, + PD15_AOUT_FEC_COL, + PD16_AIN_FEC_TX_ER, + PF23_AIN_FEC_TX_EN, + }; + + for (i = 0; i < ARRAY_SIZE(mode); i++) + imx_gpio_mode(mode[i]); +} +#endif /* CONFIG_FEC_MXC */ + +#ifdef CONFIG_MXC_MMC +void mx27_sd2_init_pins(void) +{ + int i; + unsigned int mode[] = { + PB4_PF_SD2_D0, + PB5_PF_SD2_D1, + PB6_PF_SD2_D2, + PB7_PF_SD2_D3, + PB8_PF_SD2_CMD, + PB9_PF_SD2_CLK, + }; + + for (i = 0; i < ARRAY_SIZE(mode); i++) + imx_gpio_mode(mode[i]); + +} +#endif /* CONFIG_MXC_MMC */ diff --git a/arch/arm/cpu/arm926ejs/mx27/reset.c b/arch/arm/cpu/arm926ejs/mx27/reset.c new file mode 100644 index 0000000000..6c54eafd37 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/mx27/reset.c @@ -0,0 +1,57 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * (C) Copyright 2009 + * Ilya Yanok, Emcraft Systems Ltd, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +/* + * Reset the cpu by setting up the watchdog timer and let it time out + */ +void reset_cpu (ulong ignored) +{ + struct wdog_regs *regs = (struct wdog_regs *)IMX_WDT_BASE; + /* Disable watchdog and set Time-Out field to 0 */ + writel(0x00000000, ®s->wcr); + + /* Write Service Sequence */ + writel(0x00005555, ®s->wsr); + writel(0x0000AAAA, ®s->wsr); + + /* Enable watchdog */ + writel(WCR_WDE, ®s->wcr); + + while (1); + /*NOTREACHED*/ +} diff --git a/arch/arm/cpu/arm926ejs/mx27/timer.c b/arch/arm/cpu/arm926ejs/mx27/timer.c new file mode 100644 index 0000000000..8f1d47bba7 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/mx27/timer.c @@ -0,0 +1,190 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * (C) Copyright 2009 + * Ilya Yanok, Emcraft Systems Ltd, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include + +/* General purpose timers bitfields */ +#define GPTCR_SWR (1 << 15) /* Software reset */ +#define GPTCR_FRR (1 << 8) /* Freerun / restart */ +#define GPTCR_CLKSOURCE_32 (4 << 1) /* Clock source */ +#define GPTCR_TEN 1 /* Timer enable */ + +static ulong timestamp; +static ulong lastinc; + +/* + * "time" is measured in 1 / CONFIG_SYS_HZ seconds, + * "tick" is internal timer period + */ +#ifdef CONFIG_MX27_TIMER_HIGH_PRECISION +/* ~0.4% error - measured with stop-watch on 100s boot-delay */ +static inline unsigned long long tick_to_time(unsigned long long tick) +{ + tick *= CONFIG_SYS_HZ; + do_div(tick, CONFIG_MX27_CLK32); + return tick; +} + +static inline unsigned long long time_to_tick(unsigned long long time) +{ + time *= CONFIG_MX27_CLK32; + do_div(time, CONFIG_SYS_HZ); + return time; +} + +static inline unsigned long long us_to_tick(unsigned long long us) +{ + us = us * CONFIG_MX27_CLK32 + 999999; + do_div(us, 1000000); + return us; +} +#else +/* ~2% error */ +#define TICK_PER_TIME ((CONFIG_MX27_CLK32 + CONFIG_SYS_HZ / 2) / \ + CONFIG_SYS_HZ) +#define US_PER_TICK (1000000 / CONFIG_MX27_CLK32) + +static inline unsigned long long tick_to_time(unsigned long long tick) +{ + do_div(tick, TICK_PER_TIME); + return tick; +} + +static inline unsigned long long time_to_tick(unsigned long long time) +{ + return time * TICK_PER_TIME; +} + +static inline unsigned long long us_to_tick(unsigned long long us) +{ + us += US_PER_TICK - 1; + do_div(us, US_PER_TICK); + return us; +} +#endif + +/* nothing really to do with interrupts, just starts up a counter. */ +/* The 32768Hz 32-bit timer overruns in 131072 seconds */ +int timer_init(void) +{ + int i; + struct gpt_regs *regs = (struct gpt_regs *)IMX_TIM1_BASE; + struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; + + /* setup GP Timer 1 */ + writel(GPTCR_SWR, ®s->gpt_tctl); + + writel(readl(&pll->pccr0) | PCCR0_GPT1_EN, &pll->pccr0); + writel(readl(&pll->pccr1) | PCCR1_PERCLK1_EN, &pll->pccr1); + + for (i = 0; i < 100; i++) + writel(0, ®s->gpt_tctl); /* We have no udelay by now */ + writel(0, ®s->gpt_tprer); /* 32Khz */ + /* Freerun Mode, PERCLK1 input */ + writel(readl(®s->gpt_tctl) | GPTCR_CLKSOURCE_32 | GPTCR_FRR, + ®s->gpt_tctl); + writel(readl(®s->gpt_tctl) | GPTCR_TEN, ®s->gpt_tctl); + + return 0; +} + +void reset_timer_masked(void) +{ + struct gpt_regs *regs = (struct gpt_regs *)IMX_TIM1_BASE; + /* reset time */ + /* capture current incrementer value time */ + lastinc = readl(®s->gpt_tcn); + timestamp = 0; /* start "advancing" time stamp from 0 */ +} + +void reset_timer(void) +{ + reset_timer_masked(); +} + +unsigned long long get_ticks (void) +{ + struct gpt_regs *regs = (struct gpt_regs *)IMX_TIM1_BASE; + ulong now = readl(®s->gpt_tcn); /* current tick value */ + + if (now >= lastinc) { + /* + * normal mode (non roll) + * move stamp forward with absolut diff ticks + */ + timestamp += (now - lastinc); + } else { + /* we have rollover of incrementer */ + timestamp += (0xFFFFFFFF - lastinc) + now; + } + lastinc = now; + return timestamp; +} + +ulong get_timer_masked (void) +{ + /* + * get_ticks() returns a long long (64 bit), it wraps in + * 2^64 / CONFIG_MX27_CLK32 = 2^64 / 2^15 = 2^49 ~ 5 * 10^14 (s) ~ + * 5 * 10^9 days... and get_ticks() * CONFIG_SYS_HZ wraps in + * 5 * 10^6 days - long enough. + */ + return tick_to_time(get_ticks()); +} + +ulong get_timer (ulong base) +{ + return get_timer_masked () - base; +} + +void set_timer (ulong t) +{ + timestamp = time_to_tick(t); +} + +/* delay x useconds AND preserve advance timstamp value */ +void __udelay (unsigned long usec) +{ + unsigned long long tmp; + ulong tmo; + + tmo = us_to_tick(usec); + tmp = get_ticks() + tmo; /* get current timestamp */ + + while (get_ticks() < tmp) /* loop till event */ + /*NOP*/; +} diff --git a/arch/arm/cpu/arm926ejs/nomadik/Makefile b/arch/arm/cpu/arm926ejs/nomadik/Makefile new file mode 100644 index 0000000000..0fc9f2a4c1 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/nomadik/Makefile @@ -0,0 +1,46 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +COBJS = timer.o gpio.o +SOBJS = reset.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) $(addprefix $(obj),$(SOBJS)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm926ejs/nomadik/gpio.c b/arch/arm/cpu/arm926ejs/nomadik/gpio.c new file mode 100644 index 0000000000..62a375b5b5 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/nomadik/gpio.c @@ -0,0 +1,99 @@ +/* + * (C) Copyright 2009 Alessandro Rubini + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +static unsigned long gpio_base[4] = { + NOMADIK_GPIO0_BASE, + NOMADIK_GPIO1_BASE, + NOMADIK_GPIO2_BASE, + NOMADIK_GPIO3_BASE +}; + +enum gpio_registers { + GPIO_DAT = 0x00, /* data register */ + GPIO_DATS = 0x04, /* data set */ + GPIO_DATC = 0x08, /* data clear */ + GPIO_PDIS = 0x0c, /* pull disable */ + GPIO_DIR = 0x10, /* direction */ + GPIO_DIRS = 0x14, /* direction set */ + GPIO_DIRC = 0x18, /* direction clear */ + GPIO_AFSLA = 0x20, /* alternate function select A */ + GPIO_AFSLB = 0x24, /* alternate function select B */ +}; + +static inline unsigned long gpio_to_base(int gpio) +{ + return gpio_base[gpio / 32]; +} + +static inline u32 gpio_to_bit(int gpio) +{ + return 1 << (gpio & 0x1f); +} + +void nmk_gpio_af(int gpio, int alternate_function) +{ + unsigned long base = gpio_to_base(gpio); + u32 bit = gpio_to_bit(gpio); + u32 afunc, bfunc; + + /* alternate function is 0..3, with one bit per register */ + afunc = readl(base + GPIO_AFSLA) & ~bit; + bfunc = readl(base + GPIO_AFSLB) & ~bit; + if (alternate_function & 1) afunc |= bit; + if (alternate_function & 2) bfunc |= bit; + writel(afunc, base + GPIO_AFSLA); + writel(bfunc, base + GPIO_AFSLB); +} + +void nmk_gpio_dir(int gpio, int dir) +{ + unsigned long base = gpio_to_base(gpio); + u32 bit = gpio_to_bit(gpio); + + if (dir) + writel(bit, base + GPIO_DIRS); + else + writel(bit, base + GPIO_DIRC); +} + +void nmk_gpio_set(int gpio, int val) +{ + unsigned long base = gpio_to_base(gpio); + u32 bit = gpio_to_bit(gpio); + + if (val) + writel(bit, base + GPIO_DATS); + else + writel(bit, base + GPIO_DATC); +} + +int nmk_gpio_get(int gpio) +{ + unsigned long base = gpio_to_base(gpio); + u32 bit = gpio_to_bit(gpio); + + return readl(base + GPIO_DAT) & bit; +} diff --git a/arch/arm/cpu/arm926ejs/nomadik/reset.S b/arch/arm/cpu/arm926ejs/nomadik/reset.S new file mode 100644 index 0000000000..ec954726ae --- /dev/null +++ b/arch/arm/cpu/arm926ejs/nomadik/reset.S @@ -0,0 +1,14 @@ +#include +/* + * Processor reset for Nomadik + */ + + .align 5 +.globl reset_cpu +reset_cpu: + ldr r0, =NOMADIK_SRC_BASE /* System and Reset Controller */ + ldr r1, =0x1 + str r1, [r0, #0x18] + +_loop_forever: + b _loop_forever diff --git a/arch/arm/cpu/arm926ejs/nomadik/timer.c b/arch/arm/cpu/arm926ejs/nomadik/timer.c new file mode 100644 index 0000000000..1d98ef3eb3 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/nomadik/timer.c @@ -0,0 +1,79 @@ +/* + * (C) Copyright 2009 Alessandro Rubini + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +/* + * The timer is a decrementer, we'll left it free running at 2.4MHz. + * We have 2.4 ticks per microsecond and an overflow in almost 30min + */ +#define TIMER_CLOCK (24 * 100 * 1000) +#define COUNT_TO_USEC(x) ((x) * 5 / 12) /* overflows at 6min */ +#define USEC_TO_COUNT(x) ((x) * 12 / 5) /* overflows at 6min */ +#define TICKS_PER_HZ (TIMER_CLOCK / CONFIG_SYS_HZ) +#define TICKS_TO_HZ(x) ((x) / TICKS_PER_HZ) + +/* macro to read the decrementing 32 bit timer as an increasing count */ +#define READ_TIMER() (0 - readl(CONFIG_SYS_TIMERBASE + MTU_VAL(0))) + +/* Configure a free-running, auto-wrap counter with no prescaler */ +int timer_init(void) +{ + writel(MTU_CRn_ENA | MTU_CRn_PRESCALE_1 | MTU_CRn_32BITS, + CONFIG_SYS_TIMERBASE + MTU_CR(0)); + reset_timer(); + return 0; +} + +/* Restart counting from 0 */ +void reset_timer(void) +{ + ulong val; + writel(0, CONFIG_SYS_TIMERBASE + MTU_LR(0)); + /* + * The load-register isn't really immediate: it changes on clock + * edges, so we must wait for our newly-written value to appear. + * Since we might miss reading 0, wait for any change in value. + */ + val = READ_TIMER(); + while (READ_TIMER() == val) + ; +} + +/* Return how many HZ passed since "base" */ +ulong get_timer(ulong base) +{ + return TICKS_TO_HZ(READ_TIMER()) - base; +} + +/* Delay x useconds */ +void __udelay(unsigned long usec) +{ + ulong ini, end; + + ini = READ_TIMER(); + end = ini + USEC_TO_COUNT(usec); + while ((signed)(end - READ_TIMER()) > 0) + ; +} diff --git a/arch/arm/cpu/arm926ejs/omap/Makefile b/arch/arm/cpu/arm926ejs/omap/Makefile new file mode 100644 index 0000000000..74aea74189 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/omap/Makefile @@ -0,0 +1,47 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +COBJS = timer.o cpuinfo.o +SOBJS = reset.o + +SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm926ejs/omap/cpuinfo.c b/arch/arm/cpu/arm926ejs/omap/cpuinfo.c new file mode 100644 index 0000000000..0052daba8e --- /dev/null +++ b/arch/arm/cpu/arm926ejs/omap/cpuinfo.c @@ -0,0 +1,241 @@ +/* + * OMAP1 CPU identification code + * + * Copyright (C) 2004 Nokia Corporation + * Written by Tony Lindgren + * + * 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. + */ + +#include +#include + +#if defined(CONFIG_DISPLAY_CPUINFO) && defined(CONFIG_OMAP) + +#define omap_readw(x) *(volatile unsigned short *)(x) +#define omap_readl(x) *(volatile unsigned long *)(x) + +#define OMAP_DIE_ID_0 0xfffe1800 +#define OMAP_DIE_ID_1 0xfffe1804 +#define OMAP_PRODUCTION_ID_0 0xfffe2000 +#define OMAP_PRODUCTION_ID_1 0xfffe2004 +#define OMAP32_ID_0 0xfffed400 +#define OMAP32_ID_1 0xfffed404 + +struct omap_id { + u16 jtag_id; /* Used to determine OMAP type */ + u8 die_rev; /* Processor revision */ + u32 omap_id; /* OMAP revision */ + u32 type; /* Cpu id bits [31:08], cpu class bits [07:00] */ +}; + +/* Register values to detect the OMAP version */ +static struct omap_id omap_ids[] = { + { .jtag_id = 0xb574, .die_rev = 0x2, .omap_id = 0x03310315, .type = 0x03100000}, + { .jtag_id = 0x355f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300100}, + { .jtag_id = 0xb55f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300300}, + { .jtag_id = 0xb470, .die_rev = 0x0, .omap_id = 0x03310100, .type = 0x15100000}, + { .jtag_id = 0xb576, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x16100000}, + { .jtag_id = 0xb576, .die_rev = 0x2, .omap_id = 0x03320100, .type = 0x16110000}, + { .jtag_id = 0xb576, .die_rev = 0x3, .omap_id = 0x03320100, .type = 0x16100c00}, + { .jtag_id = 0xb576, .die_rev = 0x0, .omap_id = 0x03320200, .type = 0x16100d00}, + { .jtag_id = 0xb613, .die_rev = 0x0, .omap_id = 0x03320300, .type = 0x1610ef00}, + { .jtag_id = 0xb613, .die_rev = 0x0, .omap_id = 0x03320300, .type = 0x1610ef00}, + { .jtag_id = 0xb576, .die_rev = 0x1, .omap_id = 0x03320100, .type = 0x16110000}, + { .jtag_id = 0xb58c, .die_rev = 0x2, .omap_id = 0x03320200, .type = 0x16110b00}, + { .jtag_id = 0xb58c, .die_rev = 0x3, .omap_id = 0x03320200, .type = 0x16110c00}, + { .jtag_id = 0xb65f, .die_rev = 0x0, .omap_id = 0x03320400, .type = 0x16212300}, + { .jtag_id = 0xb65f, .die_rev = 0x1, .omap_id = 0x03320400, .type = 0x16212300}, + { .jtag_id = 0xb65f, .die_rev = 0x1, .omap_id = 0x03320500, .type = 0x16212300}, + { .jtag_id = 0xb5f7, .die_rev = 0x0, .omap_id = 0x03330000, .type = 0x17100000}, + { .jtag_id = 0xb5f7, .die_rev = 0x1, .omap_id = 0x03330100, .type = 0x17100000}, + { .jtag_id = 0xb5f7, .die_rev = 0x2, .omap_id = 0x03330100, .type = 0x17100000}, +}; + +/* + * Get OMAP type from PROD_ID. + * 1710 has the PROD_ID in bits 15:00, not in 16:01 as documented in TRM. + * 1510 PROD_ID is empty, and 1610 PROD_ID does not make sense. + * Undocumented register in TEST BLOCK is used as fallback; This seems to + * work on 1510, 1610 & 1710. The official way hopefully will work in future + * processors. + */ +static u16 omap_get_jtag_id(void) +{ + u32 prod_id, omap_id; + + prod_id = omap_readl(OMAP_PRODUCTION_ID_1); + omap_id = omap_readl(OMAP32_ID_1); + + /* Check for unusable OMAP_PRODUCTION_ID_1 on 1611B/5912 and 730 */ + if (((prod_id >> 20) == 0) || (prod_id == omap_id)) + prod_id = 0; + else + prod_id &= 0xffff; + + if (prod_id) + return prod_id; + + /* Use OMAP32_ID_1 as fallback */ + prod_id = ((omap_id >> 12) & 0xffff); + + return prod_id; +} + +/* + * Get OMAP revision from DIE_REV. + * Early 1710 processors may have broken OMAP_DIE_ID, it contains PROD_ID. + * Undocumented register in the TEST BLOCK is used as fallback. + * REVISIT: This does not seem to work on 1510 + */ +static u8 omap_get_die_rev(void) +{ + u32 die_rev; + + die_rev = omap_readl(OMAP_DIE_ID_1); + + /* Check for broken OMAP_DIE_ID on early 1710 */ + if (((die_rev >> 12) & 0xffff) == omap_get_jtag_id()) + die_rev = 0; + + die_rev = (die_rev >> 17) & 0xf; + if (die_rev) + return die_rev; + + die_rev = (omap_readl(OMAP32_ID_1) >> 28) & 0xf; + + return die_rev; +} + +static unsigned long dpll1(void) +{ + unsigned short pll_ctl_val = omap_readw(DPLL_CTL_REG); + unsigned long rate; + + rate = CONFIG_SYS_CLK_FREQ; /* Base xtal rate */ + if (pll_ctl_val & 0x10) { + /* PLL enabled, apply multiplier and divisor */ + if (pll_ctl_val & 0xf80) + rate *= (pll_ctl_val & 0xf80) >> 7; + rate /= ((pll_ctl_val & 0x60) >> 5) + 1; + } else { + /* PLL disabled, apply bypass divisor */ + switch (pll_ctl_val & 0xc) { + case 0: + break; + case 0x4: + rate /= 2; + break; + default: + rate /= 4; + break; + } + } + + return rate; +} + +static unsigned long armcore(void) +{ + unsigned short arm_ckctl = omap_readw(ARM_CKCTL); + + return (dpll1() >> ((arm_ckctl & 0x0030) >> 4)); +} + +int print_cpuinfo (void) +{ + int i; + u16 jtag_id; + u8 die_rev; + u32 omap_id; + u8 cpu_type; + u32 system_serial_high; + u32 system_serial_low; + u32 system_rev = 0; + + jtag_id = omap_get_jtag_id(); + die_rev = omap_get_die_rev(); + omap_id = omap_readl(OMAP32_ID_0); + +#ifdef DEBUG + printf("OMAP_DIE_ID_0: 0x%08x\n", omap_readl(OMAP_DIE_ID_0)); + printf("OMAP_DIE_ID_1: 0x%08x DIE_REV: %i\n", + omap_readl(OMAP_DIE_ID_1), + (omap_readl(OMAP_DIE_ID_1) >> 17) & 0xf); + printf("OMAP_PRODUCTION_ID_0: 0x%08x\n", omap_readl(OMAP_PRODUCTION_ID_0)); + printf("OMAP_PRODUCTION_ID_1: 0x%08x JTAG_ID: 0x%04x\n", + omap_readl(OMAP_PRODUCTION_ID_1), + omap_readl(OMAP_PRODUCTION_ID_1) & 0xffff); + printf("OMAP32_ID_0: 0x%08x\n", omap_readl(OMAP32_ID_0)); + printf("OMAP32_ID_1: 0x%08x\n", omap_readl(OMAP32_ID_1)); + printf("JTAG_ID: 0x%04x DIE_REV: %i\n", jtag_id, die_rev); +#endif + + system_serial_high = omap_readl(OMAP_DIE_ID_0); + system_serial_low = omap_readl(OMAP_DIE_ID_1); + + /* First check only the major version in a safe way */ + for (i = 0; i < ARRAY_SIZE(omap_ids); i++) { + if (jtag_id == (omap_ids[i].jtag_id)) { + system_rev = omap_ids[i].type; + break; + } + } + + /* Check if we can find the die revision */ + for (i = 0; i < ARRAY_SIZE(omap_ids); i++) { + if (jtag_id == omap_ids[i].jtag_id && die_rev == omap_ids[i].die_rev) { + system_rev = omap_ids[i].type; + break; + } + } + + /* Finally check also the omap_id */ + for (i = 0; i < ARRAY_SIZE(omap_ids); i++) { + if (jtag_id == omap_ids[i].jtag_id + && die_rev == omap_ids[i].die_rev + && omap_id == omap_ids[i].omap_id) { + system_rev = omap_ids[i].type; + break; + } + } + + /* Add the cpu class info (7xx, 15xx, 16xx, 24xx) */ + cpu_type = system_rev >> 24; + + switch (cpu_type) { + case 0x07: + system_rev |= 0x07; + break; + case 0x03: + case 0x15: + system_rev |= 0x15; + break; + case 0x16: + case 0x17: + system_rev |= 0x16; + break; + case 0x24: + system_rev |= 0x24; + break; + default: + printf("Unknown OMAP cpu type: 0x%02x\n", cpu_type); + } + + printf("CPU: OMAP%04x", system_rev >> 16); + if ((system_rev >> 8) & 0xff) + printf("%x", (system_rev >> 8) & 0xff); +#ifdef DEBUG + printf(" revision %i handled as %02xxx id: %08x%08x", + die_rev, system_rev & 0xff, system_serial_low, system_serial_high); +#endif + printf(" at %ld.%01ld MHz (DPLL1=%ld.%01ld MHz)\n", + armcore() / 1000000, (armcore() / 100000) % 10, + dpll1() / 1000000, (dpll1() / 100000) % 10); + + return 0; +} + +#endif /* #if defined(CONFIG_DISPLAY_CPUINFO) && defined(CONFIG_OMAP) */ diff --git a/arch/arm/cpu/arm926ejs/omap/reset.S b/arch/arm/cpu/arm926ejs/omap/reset.S new file mode 100644 index 0000000000..4b20756d1b --- /dev/null +++ b/arch/arm/cpu/arm926ejs/omap/reset.S @@ -0,0 +1,45 @@ +/* + * armboot - Startup Code for ARM926EJS CPU-core + * + * Copyright (c) 2003 Texas Instruments + * + * ----- Adapted for OMAP1610 OMAP730 from ARM925t code ------ + * + * Copyright (c) 2001 Marius Gröger + * Copyright (c) 2002 Alex Züpke + * Copyright (c) 2002 Gary Jennejohn + * Copyright (c) 2003 Richard Woodruff + * Copyright (c) 2003 Kshitij + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + .align 5 +.globl reset_cpu +reset_cpu: + ldr r1, rstctl1 /* get clkm1 reset ctl */ + mov r3, #0x0 + strh r3, [r1] /* clear it */ + mov r3, #0x8 + strh r3, [r1] /* force dsp+arm reset */ +_loop_forever: + b _loop_forever + +rstctl1: + .word 0xfffece10 diff --git a/arch/arm/cpu/arm926ejs/omap/timer.c b/arch/arm/cpu/arm926ejs/omap/timer.c new file mode 100644 index 0000000000..2ac38c40b7 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/omap/timer.c @@ -0,0 +1,176 @@ +/* + * (C) Copyright 2003 + * Texas Instruments + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * (C) Copyright 2002-2004 + * Gary Jennejohn, DENX Software Engineering, + * + * (C) Copyright 2004 + * Philippe Robin, ARM Ltd. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +#define TIMER_LOAD_VAL 0xffffffff + +/* macro to read the 32 bit timer */ +#define READ_TIMER (*(volatile ulong *)(CONFIG_SYS_TIMERBASE+8)) + +static ulong timestamp; +static ulong lastdec; + +int timer_init (void) +{ + int32_t val; + + /* Start the decrementer ticking down from 0xffffffff */ + *((int32_t *) (CONFIG_SYS_TIMERBASE + LOAD_TIM)) = TIMER_LOAD_VAL; + val = MPUTIM_ST | MPUTIM_AR | MPUTIM_CLOCK_ENABLE | (CONFIG_SYS_PTV << MPUTIM_PTV_BIT); + *((int32_t *) (CONFIG_SYS_TIMERBASE + CNTL_TIMER)) = val; + + /* init the timestamp and lastdec value */ + reset_timer_masked(); + + return 0; +} + +/* + * timer without interrupts + */ + +void reset_timer (void) +{ + reset_timer_masked (); +} + +ulong get_timer (ulong base) +{ + return get_timer_masked () - base; +} + +void set_timer (ulong t) +{ + timestamp = t; +} + +/* delay x useconds AND perserve advance timstamp value */ +void __udelay (unsigned long usec) +{ + ulong tmo, tmp; + + if(usec >= 1000){ /* if "big" number, spread normalization to seconds */ + tmo = usec / 1000; /* start to normalize for usec to ticks per sec */ + tmo *= CONFIG_SYS_HZ; /* find number of "ticks" to wait to achieve target */ + tmo /= 1000; /* finish normalize. */ + }else{ /* else small number, don't kill it prior to HZ multiply */ + tmo = usec * CONFIG_SYS_HZ; + tmo /= (1000*1000); + } + + tmp = get_timer (0); /* get current timestamp */ + if( (tmo + tmp + 1) < tmp ) /* if setting this fordward will roll time stamp */ + reset_timer_masked (); /* reset "advancing" timestamp to 0, set lastdec value */ + else + tmo += tmp; /* else, set advancing stamp wake up time */ + + while (get_timer_masked () < tmo)/* loop till event */ + /*NOP*/; +} + +void reset_timer_masked (void) +{ + /* reset time */ + lastdec = READ_TIMER; /* capure current decrementer value time */ + timestamp = 0; /* start "advancing" time stamp from 0 */ +} + +ulong get_timer_masked (void) +{ + ulong now = READ_TIMER; /* current tick value */ + + if (lastdec >= now) { /* normal mode (non roll) */ + /* normal mode */ + timestamp += lastdec - now; /* move stamp fordward with absoulte diff ticks */ + } else { /* we have overflow of the count down timer */ + /* nts = ts + ld + (TLV - now) + * ts=old stamp, ld=time that passed before passing through -1 + * (TLV-now) amount of time after passing though -1 + * nts = new "advancing time stamp"...it could also roll and cause problems. + */ + timestamp += lastdec + TIMER_LOAD_VAL - now; + } + lastdec = now; + + return timestamp; +} + +/* waits specified delay value and resets timestamp */ +void udelay_masked (unsigned long usec) +{ + ulong tmo; + ulong endtime; + signed long diff; + + if (usec >= 1000) { /* if "big" number, spread normalization to seconds */ + tmo = usec / 1000; /* start to normalize for usec to ticks per sec */ + tmo *= CONFIG_SYS_HZ; /* find number of "ticks" to wait to achieve target */ + tmo /= 1000; /* finish normalize. */ + } else { /* else small number, don't kill it prior to HZ multiply */ + tmo = usec * CONFIG_SYS_HZ; + tmo /= (1000*1000); + } + + endtime = get_timer_masked () + tmo; + + do { + ulong now = get_timer_masked (); + diff = endtime - now; + } while (diff >= 0); +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk (void) +{ + ulong tbclk; + + tbclk = CONFIG_SYS_HZ; + return tbclk; +} diff --git a/arch/arm/cpu/arm926ejs/spear/Makefile b/arch/arm/cpu/arm926ejs/spear/Makefile new file mode 100644 index 0000000000..bf8dfa8c3c --- /dev/null +++ b/arch/arm/cpu/arm926ejs/spear/Makefile @@ -0,0 +1,52 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +COBJS := reset.o \ + timer.o +SOBJS := + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +$(LIB): $(obj).depend $(OBJS) $(SOBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS) + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak $(obj).depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm926ejs/spear/reset.c b/arch/arm/cpu/arm926ejs/spear/reset.c new file mode 100644 index 0000000000..73ad86da30 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/spear/reset.c @@ -0,0 +1,54 @@ +/* + * (C) Copyright 2009 + * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include + +void reset_cpu(ulong ignored) +{ + struct syscntl_regs *syscntl_regs_p = + (struct syscntl_regs *)CONFIG_SPEAR_SYSCNTLBASE; + + printf("System is going to reboot ...\n"); + + /* + * This 1 second delay will allow the above message + * to be printed before reset + */ + udelay((1000 * 1000)); + + /* Going into slow mode before resetting SOC */ + writel(0x02, &syscntl_regs_p->scctrl); + + /* + * Writing any value to the system status register will + * reset the SoC + */ + writel(0x00, &syscntl_regs_p->scsysstat); + + /* system will restart */ + while (1) + ; +} diff --git a/arch/arm/cpu/arm926ejs/spear/timer.c b/arch/arm/cpu/arm926ejs/spear/timer.c new file mode 100644 index 0000000000..06858b4a13 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/spear/timer.c @@ -0,0 +1,153 @@ +/* + * (C) Copyright 2009 + * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include + +#define GPT_RESOLUTION (CONFIG_SPEAR_HZ_CLOCK / CONFIG_SPEAR_HZ) +#define READ_TIMER() (readl(&gpt_regs_p->count) & GPT_FREE_RUNNING) + +static struct gpt_regs *const gpt_regs_p = + (struct gpt_regs *)CONFIG_SPEAR_TIMERBASE; + +static struct misc_regs *const misc_regs_p = + (struct misc_regs *)CONFIG_SPEAR_MISCBASE; + +static ulong timestamp; +static ulong lastdec; + +int timer_init(void) +{ + u32 synth; + + /* Prescaler setting */ +#if defined(CONFIG_SPEAR3XX) + writel(MISC_PRSC_CFG, &misc_regs_p->prsc2_clk_cfg); + synth = MISC_GPT4SYNTH; +#elif defined(CONFIG_SPEAR600) + writel(MISC_PRSC_CFG, &misc_regs_p->prsc1_clk_cfg); + synth = MISC_GPT3SYNTH; +#else +# error Incorrect config. Can only be spear{600|300|310|320} +#endif + + writel(readl(&misc_regs_p->periph_clk_cfg) | synth, + &misc_regs_p->periph_clk_cfg); + + /* disable timers */ + writel(GPT_PRESCALER_1 | GPT_MODE_AUTO_RELOAD, &gpt_regs_p->control); + + /* load value for free running */ + writel(GPT_FREE_RUNNING, &gpt_regs_p->compare); + + /* auto reload, start timer */ + writel(readl(&gpt_regs_p->control) | GPT_ENABLE, &gpt_regs_p->control); + + reset_timer_masked(); + + return 0; +} + +/* + * timer without interrupts + */ + +void reset_timer(void) +{ + reset_timer_masked(); +} + +ulong get_timer(ulong base) +{ + return (get_timer_masked() / GPT_RESOLUTION) - base; +} + +void set_timer(ulong t) +{ + timestamp = t; +} + +void __udelay(unsigned long usec) +{ + ulong tmo; + ulong start = get_timer_masked(); + ulong tenudelcnt = CONFIG_SPEAR_HZ_CLOCK / (1000 * 100); + ulong rndoff; + + rndoff = (usec % 10) ? 1 : 0; + + /* tenudelcnt timer tick gives 10 microsecconds delay */ + tmo = ((usec / 10) + rndoff) * tenudelcnt; + + while ((ulong) (get_timer_masked() - start) < tmo) + ; +} + +void reset_timer_masked(void) +{ + /* reset time */ + lastdec = READ_TIMER(); + timestamp = 0; +} + +ulong get_timer_masked(void) +{ + ulong now = READ_TIMER(); + + if (now >= lastdec) { + /* normal mode */ + timestamp += now - lastdec; + } else { + /* we have an overflow ... */ + timestamp += now + GPT_FREE_RUNNING - lastdec; + } + lastdec = now; + + return timestamp; +} + +void udelay_masked(unsigned long usec) +{ + return udelay(usec); +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + return CONFIG_SPEAR_HZ; +} diff --git a/arch/arm/cpu/arm926ejs/start.S b/arch/arm/cpu/arm926ejs/start.S new file mode 100644 index 0000000000..3b81151f49 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/start.S @@ -0,0 +1,440 @@ +/* + * armboot - Startup Code for ARM926EJS CPU-core + * + * Copyright (c) 2003 Texas Instruments + * + * ----- Adapted for OMAP1610 OMAP730 from ARM925t code ------ + * + * Copyright (c) 2001 Marius Gröger + * Copyright (c) 2002 Alex Züpke + * Copyright (c) 2002 Gary Jennejohn + * Copyright (c) 2003 Richard Woodruff + * Copyright (c) 2003 Kshitij + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + +#include +#include +#include + +#if defined(CONFIG_OMAP1610) +#include <./configs/omap1510.h> +#elif defined(CONFIG_OMAP730) +#include <./configs/omap730.h> +#endif + +/* + ************************************************************************* + * + * Jump vector table as in table 3.1 in [1] + * + ************************************************************************* + */ + + +.globl _start +_start: + b reset +#ifdef CONFIG_PRELOADER +/* No exception handlers in preloader */ + ldr pc, _hang + ldr pc, _hang + ldr pc, _hang + ldr pc, _hang + ldr pc, _hang + ldr pc, _hang + ldr pc, _hang + +_hang: + .word do_hang +/* pad to 64 byte boundary */ + .word 0x12345678 + .word 0x12345678 + .word 0x12345678 + .word 0x12345678 + .word 0x12345678 + .word 0x12345678 + .word 0x12345678 +#else + 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 + +_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 + +#endif /* CONFIG_PRELOADER */ + .balignl 16,0xdeadbeef + + +/* + ************************************************************************* + * + * Startup Code (reset vector) + * + * do important init only if we don't start from memory! + * setup Memory and board specific bits prior to relocation. + * relocate armboot to ram + * setup stack + * + ************************************************************************* + */ + +_TEXT_BASE: + .word TEXT_BASE + +.globl _armboot_start +_armboot_start: + .word _start + +/* + * These are defined in the board-specific linker script. + */ +.globl _bss_start +_bss_start: + .word __bss_start + +.globl _bss_end +_bss_end: + .word _end + +#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 + + +/* + * the actual reset code + */ + +reset: + /* + * set the cpu to SVC32 mode + */ + mrs r0,cpsr + bic r0,r0,#0x1f + orr r0,r0,#0xd3 + msr cpsr,r0 + + /* + * we do sys-critical inits only at reboot, + * not when booting from ram! + */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl cpu_init_crit +#endif + +#ifndef CONFIG_SKIP_RELOCATE_UBOOT +relocate: /* relocate U-Boot to RAM */ + adr r0, _start /* r0 <- current position of code */ + ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ + cmp r0, r1 /* don't reloc during debug */ + beq stack_setup + ldr r2, _armboot_start + ldr r3, _bss_start + sub r2, r3, r2 /* r2 <- size of armboot */ + add r2, r0, r2 /* r2 <- source end address */ + +copy_loop: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end addreee [r2] */ + ble copy_loop +#endif /* CONFIG_SKIP_RELOCATE_UBOOT */ + + /* Set up the stack */ +stack_setup: + ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ + sub sp, r0, #128 /* leave 32 words for abort-stack */ +#ifndef CONFIG_PRELOADER + sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */ + sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ +#ifdef CONFIG_USE_IRQ + sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) +#endif +#endif /* CONFIG_PRELOADER */ + sub sp, r0, #12 /* leave 3 words for abort-stack */ + bic sp, r0, #7 /* 8-byte align stack for ABI compliance */ + +clear_bss: + ldr r0, _bss_start /* find start of bss segment */ + ldr r1, _bss_end /* stop here */ + mov r2, #0x00000000 /* clear */ + +#ifndef CONFIG_PRELOADER +clbss_l:str r2, [r0] /* clear loop... */ + add r0, r0, #4 + cmp r0, r1 + ble clbss_l + + bl coloured_LED_init + bl red_LED_on +#endif /* CONFIG_PRELOADER */ + + ldr pc, _start_armboot + +_start_armboot: +#ifdef CONFIG_NAND_SPL + .word nand_boot +#else + .word start_armboot +#endif /* CONFIG_NAND_SPL */ + + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + ************************************************************************* + */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT +cpu_init_crit: + /* + * flush v4 I/D caches + */ + mov r0, #0 + mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ + mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ + + /* + * disable MMU stuff and caches + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x00002300 /* clear bits 13, 9:8 (--V- --RS) */ + bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */ + orr r0, r0, #0x00000002 /* set bit 2 (A) Align */ + orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */ + mcr p15, 0, r0, c1, c0, 0 + + /* + * Go setup Memory and board specific bits prior to relocation. + */ + mov ip, lr /* perserve link reg across call */ + bl lowlevel_init /* go setup pll,mux,memory */ + mov lr, ip /* restore link */ + mov pc, lr /* back to my caller */ +#endif /* CONFIG_SKIP_LOWLEVEL_INIT */ + +#ifndef CONFIG_PRELOADER +/* + ************************************************************************* + * + * 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 +#define I_BIT 0x80 + +/* + * use bad_save_user_regs for abort/prefetch/undef/swi ... + * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling + */ + + .macro bad_save_user_regs + @ carve out a frame on current user stack + sub sp, sp, #S_FRAME_SIZE + stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12 + + ldr r2, _armboot_start + sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) + sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack + @ get values for "aborted" pc and cpsr (into parm regs) + ldmia r2, {r2 - r3} + add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack + add r5, sp, #S_SP + mov r1, lr + stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr + mov r0, sp @ save current stack into r0 (param register) + .endm + + .macro irq_save_user_regs + sub sp, sp, #S_FRAME_SIZE + stmia sp, {r0 - r12} @ Calling r0-r12 + @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good. + 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, _armboot_start @ setup our mode stack + sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) + sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack + + str lr, [r13] @ save caller lr in position 0 of saved stack + mrs lr, spsr @ get the spsr + str lr, [r13, #4] @ save spsr in position 1 of saved stack + mov r13, #MODE_SVC @ prepare SVC-Mode + @ msr spsr_c, r13 + msr spsr, r13 @ switch modes, make sure moves will execute + mov lr, pc @ capture return pc + movs pc, lr @ jump to next instruction & switch modes. + .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 +#endif /* CONFIG_PRELOADER */ + +/* + * exception handlers + */ +#ifdef CONFIG_PRELOADER + .align 5 +do_hang: + ldr sp, _TEXT_BASE /* switch to abort stack */ +1: + bl 1b /* hang and never return */ +#else /* !CONFIG_PRELOADER */ + .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 + /* someone ought to write a more effiction fiq_save_user_regs */ + irq_save_user_regs + bl do_fiq + 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 +#endif /* CONFIG_PRELOADER */ diff --git a/arch/arm/cpu/arm926ejs/u-boot.lds b/arch/arm/cpu/arm926ejs/u-boot.lds new file mode 100644 index 0000000000..ecbc58c7c2 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/u-boot.lds @@ -0,0 +1,56 @@ +/* + * (C) Copyright 2002-2004 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + arch/arm/cpu/arm926ejs/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = ALIGN(4); + __bss_start = .; + .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } + _end = .; +} diff --git a/arch/arm/cpu/arm926ejs/versatile/Makefile b/arch/arm/cpu/arm926ejs/versatile/Makefile new file mode 100644 index 0000000000..c335d5c866 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/versatile/Makefile @@ -0,0 +1,47 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +COBJS = timer.o +SOBJS = reset.o + +SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm926ejs/versatile/reset.S b/arch/arm/cpu/arm926ejs/versatile/reset.S new file mode 100644 index 0000000000..4b20756d1b --- /dev/null +++ b/arch/arm/cpu/arm926ejs/versatile/reset.S @@ -0,0 +1,45 @@ +/* + * armboot - Startup Code for ARM926EJS CPU-core + * + * Copyright (c) 2003 Texas Instruments + * + * ----- Adapted for OMAP1610 OMAP730 from ARM925t code ------ + * + * Copyright (c) 2001 Marius Gröger + * Copyright (c) 2002 Alex Züpke + * Copyright (c) 2002 Gary Jennejohn + * Copyright (c) 2003 Richard Woodruff + * Copyright (c) 2003 Kshitij + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + .align 5 +.globl reset_cpu +reset_cpu: + ldr r1, rstctl1 /* get clkm1 reset ctl */ + mov r3, #0x0 + strh r3, [r1] /* clear it */ + mov r3, #0x8 + strh r3, [r1] /* force dsp+arm reset */ +_loop_forever: + b _loop_forever + +rstctl1: + .word 0xfffece10 diff --git a/arch/arm/cpu/arm926ejs/versatile/timer.c b/arch/arm/cpu/arm926ejs/versatile/timer.c new file mode 100644 index 0000000000..563db36548 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/versatile/timer.c @@ -0,0 +1,205 @@ +/* + * (C) Copyright 2003 + * Texas Instruments + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * (C) Copyright 2002-2004 + * Gary Jennejohn, DENX Software Engineering, + * + * (C) Copyright 2004 + * Philippe Robin, ARM Ltd. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +#define TIMER_LOAD_VAL 0xffffffff + +/* macro to read the 32 bit timer */ +#define READ_TIMER (*(volatile ulong *)(CONFIG_SYS_TIMERBASE+4)) + +static ulong timestamp; +static ulong lastdec; + +#define TIMER_ENABLE (1 << 7) +#define TIMER_MODE_MSK (1 << 6) +#define TIMER_MODE_FR (0 << 6) +#define TIMER_MODE_PD (1 << 6) + +#define TIMER_INT_EN (1 << 5) +#define TIMER_PRS_MSK (3 << 2) +#define TIMER_PRS_8S (1 << 3) +#define TIMER_SIZE_MSK (1 << 2) +#define TIMER_ONE_SHT (1 << 0) + +int timer_init (void) +{ + ulong tmr_ctrl_val; + + /* 1st disable the Timer */ + tmr_ctrl_val = *(volatile ulong *)(CONFIG_SYS_TIMERBASE + 8); + tmr_ctrl_val &= ~TIMER_ENABLE; + *(volatile ulong *)(CONFIG_SYS_TIMERBASE + 8) = tmr_ctrl_val; + + /* + * The Timer Control Register has one Undefined/Shouldn't Use Bit + * So we should do read/modify/write Operation + */ + + /* + * Timer Mode : Free Running + * Interrupt : Disabled + * Prescale : 8 Stage, Clk/256 + * Tmr Siz : 16 Bit Counter + * Tmr in Wrapping Mode + */ + tmr_ctrl_val = *(volatile ulong *)(CONFIG_SYS_TIMERBASE + 8); + tmr_ctrl_val &= ~(TIMER_MODE_MSK | TIMER_INT_EN | TIMER_PRS_MSK | TIMER_SIZE_MSK | TIMER_ONE_SHT ); + tmr_ctrl_val |= (TIMER_ENABLE | TIMER_PRS_8S); + + *(volatile ulong *)(CONFIG_SYS_TIMERBASE + 8) = tmr_ctrl_val; + + /* init the timestamp and lastdec value */ + reset_timer_masked(); + + return 0; +} + +/* + * timer without interrupts + */ + +void reset_timer (void) +{ + reset_timer_masked (); +} + +ulong get_timer (ulong base) +{ + return get_timer_masked () - base; +} + +void set_timer (ulong t) +{ + timestamp = t; +} + +/* delay x useconds AND perserve advance timstamp value */ +void __udelay (unsigned long usec) +{ + ulong tmo, tmp; + + if(usec >= 1000){ /* if "big" number, spread normalization to seconds */ + tmo = usec / 1000; /* start to normalize for usec to ticks per sec */ + tmo *= CONFIG_SYS_HZ; /* find number of "ticks" to wait to achieve target */ + tmo /= 1000; /* finish normalize. */ + }else{ /* else small number, don't kill it prior to HZ multiply */ + tmo = usec * CONFIG_SYS_HZ; + tmo /= (1000*1000); + } + + tmp = get_timer (0); /* get current timestamp */ + if( (tmo + tmp + 1) < tmp ) /* if setting this fordward will roll time stamp */ + reset_timer_masked (); /* reset "advancing" timestamp to 0, set lastdec value */ + else + tmo += tmp; /* else, set advancing stamp wake up time */ + + while (get_timer_masked () < tmo)/* loop till event */ + /*NOP*/; +} + +void reset_timer_masked (void) +{ + /* reset time */ + lastdec = READ_TIMER; /* capure current decrementer value time */ + timestamp = 0; /* start "advancing" time stamp from 0 */ +} + +ulong get_timer_masked (void) +{ + ulong now = READ_TIMER; /* current tick value */ + + if (lastdec >= now) { /* normal mode (non roll) */ + /* normal mode */ + timestamp += lastdec - now; /* move stamp fordward with absoulte diff ticks */ + } else { /* we have overflow of the count down timer */ + /* nts = ts + ld + (TLV - now) + * ts=old stamp, ld=time that passed before passing through -1 + * (TLV-now) amount of time after passing though -1 + * nts = new "advancing time stamp"...it could also roll and cause problems. + */ + timestamp += lastdec + TIMER_LOAD_VAL - now; + } + lastdec = now; + + return timestamp; +} + +/* waits specified delay value and resets timestamp */ +void udelay_masked (unsigned long usec) +{ + ulong tmo; + ulong endtime; + signed long diff; + + if (usec >= 1000) { /* if "big" number, spread normalization to seconds */ + tmo = usec / 1000; /* start to normalize for usec to ticks per sec */ + tmo *= CONFIG_SYS_HZ; /* find number of "ticks" to wait to achieve target */ + tmo /= 1000; /* finish normalize. */ + } else { /* else small number, don't kill it prior to HZ multiply */ + tmo = usec * CONFIG_SYS_HZ; + tmo /= (1000*1000); + } + + endtime = get_timer_masked () + tmo; + + do { + ulong now = get_timer_masked (); + diff = endtime - now; + } while (diff >= 0); +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk (void) +{ + ulong tbclk; + + tbclk = CONFIG_SYS_HZ; + return tbclk; +} diff --git a/arch/arm/cpu/arm946es/Makefile b/arch/arm/cpu/arm946es/Makefile new file mode 100644 index 0000000000..e81f2da29d --- /dev/null +++ b/arch/arm/cpu/arm946es/Makefile @@ -0,0 +1,48 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(CPU).a + +START = start.o + +COBJS = cpu.o + +SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm946es/config.mk b/arch/arm/cpu/arm946es/config.mk new file mode 100644 index 0000000000..e783f697a1 --- /dev/null +++ b/arch/arm/cpu/arm946es/config.mk @@ -0,0 +1,32 @@ +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float + +PLATFORM_CPPFLAGS += -march=armv4 +# ========================================================================= +# +# Supply options according to compiler version +# +# ========================================================================= +PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/arch/arm/cpu/arm946es/cpu.c b/arch/arm/cpu/arm946es/cpu.c new file mode 100644 index 0000000000..c63c98be86 --- /dev/null +++ b/arch/arm/cpu/arm946es/cpu.c @@ -0,0 +1,69 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * CPU specific code + */ + +#include +#include +#include + +static void cache_flush(void); + +int cleanup_before_linux (void) +{ + /* + * this function is called just before we call linux + * it prepares the processor for linux + * + * we turn off caches etc ... + */ + + disable_interrupts (); + + /* ARM926E-S needs the protection unit enabled for the icache to have + * been enabled - left for possible later use + * should turn off the protection unit as well.... + */ + /* turn off I/D-cache */ + icache_disable(); + dcache_disable(); + /* flush I/D-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)); + asm ("mcr p15, 0, %0, c7, c6, 0": :"r" (i)); +} diff --git a/arch/arm/cpu/arm946es/start.S b/arch/arm/cpu/arm946es/start.S new file mode 100644 index 0000000000..627e3cb94d --- /dev/null +++ b/arch/arm/cpu/arm946es/start.S @@ -0,0 +1,411 @@ +/* + * armboot - Startup Code for ARM926EJS CPU-core + * + * Copyright (c) 2003 Texas Instruments + * + * ----- Adapted for OMAP1610 OMAP730 from ARM925t code ------ + * + * Copyright (c) 2001 Marius Gröger + * Copyright (c) 2002 Alex Züpke + * Copyright (c) 2002 Gary Jennejohn + * Copyright (c) 2003 Richard Woodruff + * Copyright (c) 2003 Kshitij + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + +#include +#include + +/* + ************************************************************************* + * + * Jump vector table as in table 3.1 in [1] + * + ************************************************************************* + */ + + +.globl _start +_start: + b 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 + +_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! + * setup Memory and board specific bits prior to relocation. + * relocate armboot to ram + * setup stack + * + ************************************************************************* + */ + +_TEXT_BASE: + .word TEXT_BASE + +.globl _armboot_start +_armboot_start: + .word _start + +/* + * These are defined in the board-specific linker script. + */ +.globl _bss_start +_bss_start: + .word __bss_start + +.globl _bss_end +_bss_end: + .word _end + +#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 + + +/* + * the actual reset code + */ + +reset: + /* + * set the cpu to SVC32 mode + */ + mrs r0,cpsr + bic r0,r0,#0x1f + orr r0,r0,#0xd3 + msr cpsr,r0 + + /* + * we do sys-critical inits only at reboot, + * not when booting from ram! + */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl cpu_init_crit +#endif + +relocate: /* relocate U-Boot to RAM */ + adr r0, _start /* r0 <- current position of code */ + ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ + cmp r0, r1 /* don't reloc during debug */ + beq stack_setup + + ldr r2, _armboot_start + ldr r3, _bss_start + sub r2, r3, r2 /* r2 <- size of armboot */ + add r2, r0, r2 /* r2 <- source end address */ + +copy_loop: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end addreee [r2] */ + ble copy_loop + + /* Set up the stack */ +stack_setup: + ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ + sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */ + sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ +#ifdef CONFIG_USE_IRQ + sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) +#endif + sub sp, r0, #12 /* leave 3 words for abort-stack */ + +clear_bss: + ldr r0, _bss_start /* find start of bss segment */ + ldr r1, _bss_end /* stop here */ + mov r2, #0x00000000 /* clear */ + +clbss_l:str r2, [r0] /* clear loop... */ + add r0, r0, #4 + cmp r0, r1 + bne clbss_l + + ldr pc, _start_armboot + +_start_armboot: + .word start_armboot + + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + ************************************************************************* + */ + + +#ifndef CONFIG_SKIP_LOWLEVEL_INIT +cpu_init_crit: + /* + * flush v4 I/D caches + */ + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 /* flush v4 I-cache */ + mcr p15, 0, r0, c7, c6, 0 /* flush v4 D-cache */ + + /* + * disable MMU stuff and caches + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x00002300 /* clear bits 13, 9:8 (--V- --RS) */ + bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */ + orr r0, r0, #0x00000002 /* set bit 2 (A) Align */ + orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */ + mcr p15, 0, r0, c1, c0, 0 + + /* + * Go setup Memory and board specific bits prior to relocation. + */ + mov ip, lr /* perserve link reg across call */ + bl lowlevel_init /* go setup memory */ + mov lr, ip /* restore link */ + mov pc, lr /* back to my caller */ +#endif +/* + ************************************************************************* + * + * 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 +#define I_BIT 0x80 + +/* + * use bad_save_user_regs for abort/prefetch/undef/swi ... + * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling + */ + + .macro bad_save_user_regs + @ carve out a frame on current user stack + sub sp, sp, #S_FRAME_SIZE + stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12 + + ldr r2, _armboot_start + sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) + sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack + @ get values for "aborted" pc and cpsr (into parm regs) + ldmia r2, {r2 - r3} + add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack + add r5, sp, #S_SP + mov r1, lr + stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr + mov r0, sp @ save current stack into r0 (param register) + .endm + + .macro irq_save_user_regs + sub sp, sp, #S_FRAME_SIZE + stmia sp, {r0 - r12} @ Calling r0-r12 + @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good. + 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, _armboot_start @ setup our mode stack + sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) + sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack + + str lr, [r13] @ save caller lr in position 0 of saved stack + mrs lr, spsr @ get the spsr + str lr, [r13, #4] @ save spsr in position 1 of saved stack + mov r13, #MODE_SVC @ prepare SVC-Mode + @ msr spsr_c, r13 + msr spsr, r13 @ switch modes, make sure moves will execute + mov lr, pc @ capture return pc + movs pc, lr @ jump to next instruction & switch modes. + .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 + /* someone ought to write a more effiction fiq_save_user_regs */ + irq_save_user_regs + bl do_fiq + 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 + +# ifdef CONFIG_INTEGRATOR + + /* Satisfied by general board level routine */ + +#else + + .align 5 +.globl reset_cpu +reset_cpu: + + ldr r1, rstctl1 /* get clkm1 reset ctl */ + mov r3, #0x0 + strh r3, [r1] /* clear it */ + mov r3, #0x8 + strh r3, [r1] /* force dsp+arm reset */ +_loop_forever: + b _loop_forever + +rstctl1: + .word 0xfffece10 + +#endif /* #ifdef CONFIG_INTEGRATOR */ diff --git a/arch/arm/cpu/arm946es/u-boot.lds b/arch/arm/cpu/arm946es/u-boot.lds new file mode 100644 index 0000000000..fef21c7587 --- /dev/null +++ b/arch/arm/cpu/arm946es/u-boot.lds @@ -0,0 +1,56 @@ +/* + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + arch/arm/cpu/arm946es/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = ALIGN(4); + __bss_start = .; + .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } + _end = .; +} diff --git a/arch/arm/cpu/arm_cortexa8/Makefile b/arch/arm/cpu/arm_cortexa8/Makefile new file mode 100644 index 0000000000..ae20299db7 --- /dev/null +++ b/arch/arm/cpu/arm_cortexa8/Makefile @@ -0,0 +1,47 @@ +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(CPU).a + +START := start.o +COBJS := cpu.o + +SRCS := $(START:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### \ No newline at end of file diff --git a/arch/arm/cpu/arm_cortexa8/config.mk b/arch/arm/cpu/arm_cortexa8/config.mk new file mode 100644 index 0000000000..49ac9c74ae --- /dev/null +++ b/arch/arm/cpu/arm_cortexa8/config.mk @@ -0,0 +1,33 @@ +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float + +# Make ARMv5 to allow more compilers to work, even though its v7a. +PLATFORM_CPPFLAGS += -march=armv5 +# ========================================================================= +# +# Supply options according to compiler version +# +# ========================================================================= +PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,\ + $(call cc-option,-malignment-traps,)) diff --git a/arch/arm/cpu/arm_cortexa8/cpu.c b/arch/arm/cpu/arm_cortexa8/cpu.c new file mode 100644 index 0000000000..a01e0d605f --- /dev/null +++ b/arch/arm/cpu/arm_cortexa8/cpu.c @@ -0,0 +1,83 @@ +/* + * (C) Copyright 2008 Texas Insturments + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * CPU specific code + */ + +#include +#include +#include +#include +#ifndef CONFIG_L2_OFF +#include +#endif + +static void cache_flush(void); + +int cleanup_before_linux(void) +{ + unsigned int i; + + /* + * this function is called just before we call linux + * it prepares the processor for linux + * + * we turn off caches etc ... + */ + disable_interrupts(); + + /* turn off I/D-cache */ + icache_disable(); + dcache_disable(); + + /* invalidate I-cache */ + cache_flush(); + +#ifndef CONFIG_L2_OFF + /* turn off L2 cache */ + l2_cache_disable(); + /* invalidate L2 cache also */ + invalidate_dcache(get_device_type()); +#endif + i = 0; + /* mem barrier to sync up things */ + asm("mcr p15, 0, %0, c7, c10, 4": :"r"(i)); + +#ifndef CONFIG_L2_OFF + l2_cache_enable(); +#endif + + return 0; +} + +static void cache_flush(void) +{ + asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (0)); +} diff --git a/arch/arm/cpu/arm_cortexa8/mx51/Makefile b/arch/arm/cpu/arm_cortexa8/mx51/Makefile new file mode 100644 index 0000000000..7cfaa2c130 --- /dev/null +++ b/arch/arm/cpu/arm_cortexa8/mx51/Makefile @@ -0,0 +1,48 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2009 Freescale Semiconductor, Inc. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +COBJS = soc.o clock.o iomux.o timer.o speed.o +SOBJS = lowlevel_init.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm_cortexa8/mx51/clock.c b/arch/arm/cpu/arm_cortexa8/mx51/clock.c new file mode 100644 index 0000000000..38480ac5a1 --- /dev/null +++ b/arch/arm/cpu/arm_cortexa8/mx51/clock.c @@ -0,0 +1,294 @@ +/* + * (C) Copyright 2007 + * Sascha Hauer, Pengutronix + * + * (C) Copyright 2009 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include + +enum pll_clocks { + PLL1_CLOCK = 0, + PLL2_CLOCK, + PLL3_CLOCK, + PLL_CLOCKS, +}; + +struct mxc_pll_reg *mxc_plls[PLL_CLOCKS] = { + [PLL1_CLOCK] = (struct mxc_pll_reg *)PLL1_BASE_ADDR, + [PLL2_CLOCK] = (struct mxc_pll_reg *)PLL2_BASE_ADDR, + [PLL3_CLOCK] = (struct mxc_pll_reg *)PLL3_BASE_ADDR, +}; + +struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)MXC_CCM_BASE; + +/* + * Calculate the frequency of this pll. + */ +static u32 decode_pll(struct mxc_pll_reg *pll, u32 infreq) +{ + u32 mfi, mfn, mfd, pd; + + mfn = __raw_readl(&pll->mfn); + mfd = __raw_readl(&pll->mfd) + 1; + mfi = __raw_readl(&pll->op); + pd = (mfi & 0xF) + 1; + mfi = (mfi >> 4) & 0xF; + mfi = (mfi >= 5) ? mfi : 5; + + return ((4 * (infreq / 1000) * (mfi * mfd + mfn)) / (mfd * pd)) * 1000; +} + +/* + * Get mcu main rate + */ +u32 get_mcu_main_clk(void) +{ + u32 reg, freq; + + reg = (__raw_readl(&mxc_ccm->cacrr) & MXC_CCM_CACRR_ARM_PODF_MASK) >> + MXC_CCM_CACRR_ARM_PODF_OFFSET; + freq = decode_pll(mxc_plls[PLL1_CLOCK], CONFIG_MX51_HCLK_FREQ); + return freq / (reg + 1); +} + +/* + * Get the rate of peripheral's root clock. + */ +static u32 get_periph_clk(void) +{ + u32 reg; + + reg = __raw_readl(&mxc_ccm->cbcdr); + if (!(reg & MXC_CCM_CBCDR_PERIPH_CLK_SEL)) + return decode_pll(mxc_plls[PLL2_CLOCK], CONFIG_MX51_HCLK_FREQ); + reg = __raw_readl(&mxc_ccm->cbcmr); + switch ((reg & MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK) >> + MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET) { + case 0: + return decode_pll(mxc_plls[PLL1_CLOCK], CONFIG_MX51_HCLK_FREQ); + case 1: + return decode_pll(mxc_plls[PLL3_CLOCK], CONFIG_MX51_HCLK_FREQ); + default: + return 0; + } + /* NOTREACHED */ +} + +/* + * Get the rate of ipg clock. + */ +static u32 get_ipg_clk(void) +{ + u32 ahb_podf, ipg_podf; + + ahb_podf = __raw_readl(&mxc_ccm->cbcdr); + ipg_podf = (ahb_podf & MXC_CCM_CBCDR_IPG_PODF_MASK) >> + MXC_CCM_CBCDR_IPG_PODF_OFFSET; + ahb_podf = (ahb_podf & MXC_CCM_CBCDR_AHB_PODF_MASK) >> + MXC_CCM_CBCDR_AHB_PODF_OFFSET; + return get_periph_clk() / ((ahb_podf + 1) * (ipg_podf + 1)); +} + +/* + * Get the rate of ipg_per clock. + */ +static u32 get_ipg_per_clk(void) +{ + u32 pred1, pred2, podf; + + if (__raw_readl(&mxc_ccm->cbcmr) & MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL) + return get_ipg_clk(); + /* Fixme: not handle what about lpm*/ + podf = __raw_readl(&mxc_ccm->cbcdr); + pred1 = (podf & MXC_CCM_CBCDR_PERCLK_PRED1_MASK) >> + MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET; + pred2 = (podf & MXC_CCM_CBCDR_PERCLK_PRED2_MASK) >> + MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET; + podf = (podf & MXC_CCM_CBCDR_PERCLK_PODF_MASK) >> + MXC_CCM_CBCDR_PERCLK_PODF_OFFSET; + + return get_periph_clk() / ((pred1 + 1) * (pred2 + 1) * (podf + 1)); +} + +/* + * Get the rate of uart clk. + */ +static u32 get_uart_clk(void) +{ + unsigned int freq, reg, pred, podf; + + reg = __raw_readl(&mxc_ccm->cscmr1); + switch ((reg & MXC_CCM_CSCMR1_UART_CLK_SEL_MASK) >> + MXC_CCM_CSCMR1_UART_CLK_SEL_OFFSET) { + case 0x0: + freq = decode_pll(mxc_plls[PLL1_CLOCK], + CONFIG_MX51_HCLK_FREQ); + break; + case 0x1: + freq = decode_pll(mxc_plls[PLL2_CLOCK], + CONFIG_MX51_HCLK_FREQ); + break; + case 0x2: + freq = decode_pll(mxc_plls[PLL3_CLOCK], + CONFIG_MX51_HCLK_FREQ); + break; + default: + return 66500000; + } + + reg = __raw_readl(&mxc_ccm->cscdr1); + + pred = (reg & MXC_CCM_CSCDR1_UART_CLK_PRED_MASK) >> + MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET; + + podf = (reg & MXC_CCM_CSCDR1_UART_CLK_PODF_MASK) >> + MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET; + freq /= (pred + 1) * (podf + 1); + + return freq; +} + +/* + * This function returns the low power audio clock. + */ +u32 get_lp_apm(void) +{ + u32 ret_val = 0; + u32 ccsr = __raw_readl(&mxc_ccm->ccsr); + + if (((ccsr >> 9) & 1) == 0) + ret_val = CONFIG_MX51_HCLK_FREQ; + else + ret_val = ((32768 * 1024)); + + return ret_val; +} + +/* + * get cspi clock rate. + */ +u32 imx_get_cspiclk(void) +{ + u32 ret_val = 0, pdf, pre_pdf, clk_sel; + u32 cscmr1 = __raw_readl(&mxc_ccm->cscmr1); + u32 cscdr2 = __raw_readl(&mxc_ccm->cscdr2); + + pre_pdf = (cscdr2 & MXC_CCM_CSCDR2_CSPI_CLK_PRED_MASK) \ + >> MXC_CCM_CSCDR2_CSPI_CLK_PRED_OFFSET; + pdf = (cscdr2 & MXC_CCM_CSCDR2_CSPI_CLK_PODF_MASK) \ + >> MXC_CCM_CSCDR2_CSPI_CLK_PODF_OFFSET; + clk_sel = (cscmr1 & MXC_CCM_CSCMR1_CSPI_CLK_SEL_MASK) \ + >> MXC_CCM_CSCMR1_CSPI_CLK_SEL_OFFSET; + + switch (clk_sel) { + case 0: + ret_val = decode_pll(mxc_plls[PLL1_CLOCK], + CONFIG_MX51_HCLK_FREQ) / + ((pre_pdf + 1) * (pdf + 1)); + break; + case 1: + ret_val = decode_pll(mxc_plls[PLL2_CLOCK], + CONFIG_MX51_HCLK_FREQ) / + ((pre_pdf + 1) * (pdf + 1)); + break; + case 2: + ret_val = decode_pll(mxc_plls[PLL3_CLOCK], + CONFIG_MX51_HCLK_FREQ) / + ((pre_pdf + 1) * (pdf + 1)); + break; + default: + ret_val = get_lp_apm() / ((pre_pdf + 1) * (pdf + 1)); + break; + } + + return ret_val; +} + +/* + * The API of get mxc clockes. + */ +unsigned int mxc_get_clock(enum mxc_clock clk) +{ + switch (clk) { + case MXC_ARM_CLK: + return get_mcu_main_clk(); + case MXC_AHB_CLK: + break; + case MXC_IPG_CLK: + return get_ipg_clk(); + case MXC_IPG_PERCLK: + return get_ipg_per_clk(); + case MXC_UART_CLK: + return get_uart_clk(); + case MXC_CSPI_CLK: + return imx_get_cspiclk(); + case MXC_FEC_CLK: + return decode_pll(mxc_plls[PLL1_CLOCK], + CONFIG_MX51_HCLK_FREQ); + default: + break; + } + return -1; +} + +u32 imx_get_uartclk(void) +{ + return get_uart_clk(); +} + + +u32 imx_get_fecclk(void) +{ + return mxc_get_clock(MXC_IPG_CLK); +} + +/* + * Dump some core clockes. + */ +int do_mx51_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + u32 freq; + + freq = decode_pll(mxc_plls[PLL1_CLOCK], CONFIG_MX51_HCLK_FREQ); + printf("mx51 pll1: %dMHz\n", freq / 1000000); + freq = decode_pll(mxc_plls[PLL2_CLOCK], CONFIG_MX51_HCLK_FREQ); + printf("mx51 pll2: %dMHz\n", freq / 1000000); + freq = decode_pll(mxc_plls[PLL3_CLOCK], CONFIG_MX51_HCLK_FREQ); + printf("mx51 pll3: %dMHz\n", freq / 1000000); + printf("ipg clock : %dHz\n", mxc_get_clock(MXC_IPG_CLK)); + printf("ipg per clock : %dHz\n", mxc_get_clock(MXC_IPG_PERCLK)); + + return 0; +} + +/***************************************************/ + +U_BOOT_CMD( + clockinfo, CONFIG_SYS_MAXARGS, 1, do_mx51_showclocks, + "display mx51 clocks\n", + "" +); diff --git a/arch/arm/cpu/arm_cortexa8/mx51/iomux.c b/arch/arm/cpu/arm_cortexa8/mx51/iomux.c new file mode 100644 index 0000000000..62b2954be9 --- /dev/null +++ b/arch/arm/cpu/arm_cortexa8/mx51/iomux.c @@ -0,0 +1,166 @@ +/* + * (C) Copyright 2009 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include + +/* IOMUX register (base) addresses */ +enum iomux_reg_addr { + IOMUXGPR0 = IOMUXC_BASE_ADDR, + IOMUXGPR1 = IOMUXC_BASE_ADDR + 0x004, + IOMUXSW_MUX_CTL = IOMUXC_BASE_ADDR, + IOMUXSW_MUX_END = IOMUXC_BASE_ADDR + MUX_I_END, + IOMUXSW_PAD_CTL = IOMUXC_BASE_ADDR + PAD_I_START, + IOMUXSW_INPUT_CTL = IOMUXC_BASE_ADDR, +}; + +#define MUX_PIN_NUM_MAX (((MUX_I_END - MUX_I_START) >> 2) + 1) + +/* Get the iomux register address of this pin */ +static inline u32 get_mux_reg(iomux_pin_name_t pin) +{ + u32 mux_reg = PIN_TO_IOMUX_MUX(pin); + + if (is_soc_rev(CHIP_REV_2_0) < 0) { + /* + * Fixup register address: + * i.MX51 TO1 has offset with the register + * which is define as TO2. + */ + if ((pin == MX51_PIN_NANDF_RB5) || + (pin == MX51_PIN_NANDF_RB6) || + (pin == MX51_PIN_NANDF_RB7)) + ; /* Do nothing */ + else if (mux_reg >= 0x2FC) + mux_reg += 8; + else if (mux_reg >= 0x130) + mux_reg += 0xC; + } + mux_reg += IOMUXSW_MUX_CTL; + return mux_reg; +} + +/* Get the pad register address of this pin */ +static inline u32 get_pad_reg(iomux_pin_name_t pin) +{ + u32 pad_reg = PIN_TO_IOMUX_PAD(pin); + + if (is_soc_rev(CHIP_REV_2_0) < 0) { + /* + * Fixup register address: + * i.MX51 TO1 has offset with the register + * which is define as TO2. + */ + if ((pin == MX51_PIN_NANDF_RB5) || + (pin == MX51_PIN_NANDF_RB6) || + (pin == MX51_PIN_NANDF_RB7)) + ; /* Do nothing */ + else if (pad_reg == 0x4D0 - PAD_I_START) + pad_reg += 0x4C; + else if (pad_reg == 0x860 - PAD_I_START) + pad_reg += 0x9C; + else if (pad_reg >= 0x804 - PAD_I_START) + pad_reg += 0xB0; + else if (pad_reg >= 0x7FC - PAD_I_START) + pad_reg += 0xB4; + else if (pad_reg >= 0x4E4 - PAD_I_START) + pad_reg += 0xCC; + else + pad_reg += 8; + } + pad_reg += IOMUXSW_PAD_CTL; + return pad_reg; +} + +/* Get the last iomux register address */ +static inline u32 get_mux_end(void) +{ + if (is_soc_rev(CHIP_REV_2_0) < 0) + return IOMUXC_BASE_ADDR + (0x3F8 - 4); + else + return IOMUXC_BASE_ADDR + (0x3F0 - 4); +} + +/* + * This function is used to configure a pin through the IOMUX module. + * @param pin a pin number as defined in iomux_pin_name_t + * @param cfg an output function as defined in iomux_pin_cfg_t + * + * @return 0 if successful; Non-zero otherwise + */ +static void iomux_config_mux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg) +{ + u32 mux_reg = get_mux_reg(pin); + + if ((mux_reg > get_mux_end()) || (mux_reg < IOMUXSW_MUX_CTL)) + return ; + if (cfg == IOMUX_CONFIG_GPIO) + writel(PIN_TO_ALT_GPIO(pin), mux_reg); + else + writel(cfg, mux_reg); +} + +/* + * Request ownership for an IO pin. This function has to be the first one + * being called before that pin is used. The caller has to check the + * return value to make sure it returns 0. + * + * @param pin a name defined by iomux_pin_name_t + * @param cfg an input function as defined in iomux_pin_cfg_t + * + */ +void mxc_request_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg) +{ + iomux_config_mux(pin, cfg); +} + +/* + * Release ownership for an IO pin + * + * @param pin a name defined by iomux_pin_name_t + * @param cfg an input function as defined in iomux_pin_cfg_t + */ +void mxc_free_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg) +{ +} + +/* + * This function configures the pad value for a IOMUX pin. + * + * @param pin a pin number as defined in iomux_pin_name_t + * @param config the ORed value of elements defined in iomux_pad_config_t + */ +void mxc_iomux_set_pad(iomux_pin_name_t pin, u32 config) +{ + u32 pad_reg = get_pad_reg(pin); + writel(config, pad_reg); +} + +unsigned int mxc_iomux_get_pad(iomux_pin_name_t pin) +{ + u32 pad_reg = get_pad_reg(pin); + return readl(pad_reg); +} diff --git a/arch/arm/cpu/arm_cortexa8/mx51/lowlevel_init.S b/arch/arm/cpu/arm_cortexa8/mx51/lowlevel_init.S new file mode 100644 index 0000000000..31af9e2b58 --- /dev/null +++ b/arch/arm/cpu/arm_cortexa8/mx51/lowlevel_init.S @@ -0,0 +1,288 @@ +/* + * Copyright (C) 2007, Guennadi Liakhovetski + * + * (C) Copyright 2009 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +/* + * L2CC Cache setup/invalidation/disable + */ +.macro init_l2cc + /* explicitly disable L2 cache */ + mrc 15, 0, r0, c1, c0, 1 + bic r0, r0, #0x2 + mcr 15, 0, r0, c1, c0, 1 + + /* reconfigure L2 cache aux control reg */ + mov r0, #0xC0 /* tag RAM */ + add r0, r0, #0x4 /* data RAM */ + orr r0, r0, #(1 << 24) /* disable write allocate delay */ + orr r0, r0, #(1 << 23) /* disable write allocate combine */ + orr r0, r0, #(1 << 22) /* disable write allocate */ + + cmp r3, #0x10 /* r3 contains the silicon rev */ + + /* disable write combine for TO 2 and lower revs */ + orrls r0, r0, #(1 << 25) + + mcr 15, 1, r0, c9, c0, 2 +.endm /* init_l2cc */ + +/* AIPS setup - Only setup MPROTx registers. + * The PACR default values are good.*/ +.macro init_aips + /* + * Set all MPROTx to be non-bufferable, trusted for R/W, + * not forced to user-mode. + */ + ldr r0, =AIPS1_BASE_ADDR + ldr r1, =0x77777777 + str r1, [r0, #0x0] + str r1, [r0, #0x4] + ldr r0, =AIPS2_BASE_ADDR + str r1, [r0, #0x0] + str r1, [r0, #0x4] + /* + * Clear the on and off peripheral modules Supervisor Protect bit + * for SDMA to access them. Did not change the AIPS control registers + * (offset 0x20) access type + */ +.endm /* init_aips */ + +/* M4IF setup */ +.macro init_m4if + /* VPU and IPU given higher priority (0x4) + * IPU accesses with ID=0x1 given highest priority (=0xA) + */ + ldr r0, =M4IF_BASE_ADDR + + ldr r1, =0x00000203 + str r1, [r0, #0x40] + + ldr r1, =0x0 + str r1, [r0, #0x44] + + ldr r1, =0x00120125 + str r1, [r0, #0x9C] + + ldr r1, =0x001901A3 + str r1, [r0, #0x48] + +.endm /* init_m4if */ + +.macro setup_pll pll, freq + ldr r2, =\pll + ldr r1, =0x00001232 + str r1, [r2, #PLL_DP_CTL] /* Set DPLL ON (set UPEN bit): BRMO=1 */ + mov r1, #0x2 + str r1, [r2, #PLL_DP_CONFIG] /* Enable auto-restart AREN bit */ + + str r3, [r2, #PLL_DP_OP] + str r3, [r2, #PLL_DP_HFS_OP] + + str r4, [r2, #PLL_DP_MFD] + str r4, [r2, #PLL_DP_HFS_MFD] + + str r5, [r2, #PLL_DP_MFN] + str r5, [r2, #PLL_DP_HFS_MFN] + + ldr r1, =0x00001232 + str r1, [r2, #PLL_DP_CTL] +1: ldr r1, [r2, #PLL_DP_CTL] + ands r1, r1, #0x1 + beq 1b +.endm + +.macro init_clock + ldr r0, =CCM_BASE_ADDR + + /* Gate of clocks to the peripherals first */ + ldr r1, =0x3FFFFFFF + str r1, [r0, #CLKCTL_CCGR0] + ldr r1, =0x0 + str r1, [r0, #CLKCTL_CCGR1] + str r1, [r0, #CLKCTL_CCGR2] + str r1, [r0, #CLKCTL_CCGR3] + + ldr r1, =0x00030000 + str r1, [r0, #CLKCTL_CCGR4] + ldr r1, =0x00FFF030 + str r1, [r0, #CLKCTL_CCGR5] + ldr r1, =0x00000300 + str r1, [r0, #CLKCTL_CCGR6] + + /* Disable IPU and HSC dividers */ + mov r1, #0x60000 + str r1, [r0, #CLKCTL_CCDR] + + /* Make sure to switch the DDR away from PLL 1 */ + ldr r1, =0x19239145 + str r1, [r0, #CLKCTL_CBCDR] + /* make sure divider effective */ +1: ldr r1, [r0, #CLKCTL_CDHIPR] + cmp r1, #0x0 + bne 1b + + /* Switch ARM to step clock */ + mov r1, #0x4 + str r1, [r0, #CLKCTL_CCSR] + mov r3, #DP_OP_800 + mov r4, #DP_MFD_800 + mov r5, #DP_MFN_800 + setup_pll PLL1_BASE_ADDR + + mov r3, #DP_OP_665 + mov r4, #DP_MFD_665 + mov r5, #DP_MFN_665 + setup_pll PLL3_BASE_ADDR + + /* Switch peripheral to PLL 3 */ + ldr r0, =CCM_BASE_ADDR + ldr r1, =0x000010C0 + str r1, [r0, #CLKCTL_CBCMR] + ldr r1, =0x13239145 + str r1, [r0, #CLKCTL_CBCDR] + mov r3, #DP_OP_665 + mov r4, #DP_MFD_665 + mov r5, #DP_MFN_665 + setup_pll PLL2_BASE_ADDR + + /* Switch peripheral to PLL2 */ + ldr r0, =CCM_BASE_ADDR + ldr r1, =0x19239145 + str r1, [r0, #CLKCTL_CBCDR] + ldr r1, =0x000020C0 + str r1, [r0, #CLKCTL_CBCMR] + + mov r3, #DP_OP_216 + mov r4, #DP_MFD_216 + mov r5, #DP_MFN_216 + setup_pll PLL3_BASE_ADDR + + + /* Set the platform clock dividers */ + ldr r0, =ARM_BASE_ADDR + ldr r1, =0x00000725 + str r1, [r0, #0x14] + + ldr r0, =CCM_BASE_ADDR + + /* Run 3.0 at Full speed, for other TO's wait till we increase VDDGP */ + ldr r1, =0x0 + ldr r3, [r1, #ROM_SI_REV] + cmp r3, #0x10 + movls r1, #0x1 + movhi r1, #0 + str r1, [r0, #CLKCTL_CACRR] + + /* Switch ARM back to PLL 1 */ + mov r1, #0 + str r1, [r0, #CLKCTL_CCSR] + + /* setup the rest */ + /* Use lp_apm (24MHz) source for perclk */ + ldr r1, =0x000020C2 + str r1, [r0, #CLKCTL_CBCMR] + /* ddr clock from PLL 1, all perclk dividers are 1 since using 24MHz */ + ldr r1, =0x59E35100 + str r1, [r0, #CLKCTL_CBCDR] + + /* Restore the default values in the Gate registers */ + ldr r1, =0xFFFFFFFF + str r1, [r0, #CLKCTL_CCGR0] + str r1, [r0, #CLKCTL_CCGR1] + str r1, [r0, #CLKCTL_CCGR2] + str r1, [r0, #CLKCTL_CCGR3] + str r1, [r0, #CLKCTL_CCGR4] + str r1, [r0, #CLKCTL_CCGR5] + str r1, [r0, #CLKCTL_CCGR6] + + /* Use PLL 2 for UART's, get 66.5MHz from it */ + ldr r1, =0xA5A2A020 + str r1, [r0, #CLKCTL_CSCMR1] + ldr r1, =0x00C30321 + str r1, [r0, #CLKCTL_CSCDR1] + + /* make sure divider effective */ +1: ldr r1, [r0, #CLKCTL_CDHIPR] + cmp r1, #0x0 + bne 1b + + mov r1, #0x0 + str r1, [r0, #CLKCTL_CCDR] + + /* for cko - for ARM div by 8 */ + mov r1, #0x000A0000 + add r1, r1, #0x00000F0 + str r1, [r0, #CLKCTL_CCOSR] +.endm + +.macro setup_wdog + ldr r0, =WDOG1_BASE_ADDR + mov r1, #0x30 + strh r1, [r0] +.endm + +.section ".text.init", "x" + +.globl lowlevel_init +lowlevel_init: + ldr r0, =GPIO1_BASE_ADDR + ldr r1, [r0, #0x0] + orr r1, r1, #(1 << 23) + str r1, [r0, #0x0] + ldr r1, [r0, #0x4] + orr r1, r1, #(1 << 23) + str r1, [r0, #0x4] + +#ifdef ENABLE_IMPRECISE_ABORT + mrs r1, spsr /* save old spsr */ + mrs r0, cpsr /* read out the cpsr */ + bic r0, r0, #0x100 /* clear the A bit */ + msr spsr, r0 /* update spsr */ + add lr, pc, #0x8 /* update lr */ + movs pc, lr /* update cpsr */ + nop + nop + nop + nop + msr spsr, r1 /* restore old spsr */ +#endif + + init_l2cc + + init_aips + + init_m4if + + init_clock + + /* r12 saved upper lr*/ + mov pc,lr + +/* Board level setting value */ +DDR_PERCHARGE_CMD: .word 0x04008008 +DDR_REFRESH_CMD: .word 0x00008010 +DDR_LMR1_W: .word 0x00338018 +DDR_LMR_CMD: .word 0xB2220000 +DDR_TIMING_W: .word 0xB02567A9 +DDR_MISC_W: .word 0x000A0104 diff --git a/arch/arm/cpu/arm_cortexa8/mx51/soc.c b/arch/arm/cpu/arm_cortexa8/mx51/soc.c new file mode 100644 index 0000000000..2a139b21d5 --- /dev/null +++ b/arch/arm/cpu/arm_cortexa8/mx51/soc.c @@ -0,0 +1,114 @@ +/* + * (C) Copyright 2007 + * Sascha Hauer, Pengutronix + * + * (C) Copyright 2009 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include + +#ifdef CONFIG_FSL_ESDHC +#include +#endif + +u32 get_cpu_rev(void) +{ + int reg; + int system_rev; + + reg = __raw_readl(ROM_SI_REV); + switch (reg) { + case 0x02: + system_rev = 0x51000 | CHIP_REV_1_1; + break; + case 0x10: + if ((__raw_readl(GPIO1_BASE_ADDR + 0x0) & (0x1 << 22)) == 0) + system_rev = 0x51000 | CHIP_REV_2_5; + else + system_rev = 0x51000 | CHIP_REV_2_0; + break; + case 0x20: + system_rev = 0x51000 | CHIP_REV_3_0; + break; + return system_rev; + default: + system_rev = 0x51000 | CHIP_REV_1_0; + break; + } + return system_rev; +} + + +#if defined(CONFIG_DISPLAY_CPUINFO) +int print_cpuinfo(void) +{ + u32 cpurev; + + cpurev = get_cpu_rev(); + printf("CPU: Freescale i.MX51 family %d.%dV at %d MHz\n", + (cpurev & 0xF0) >> 4, + (cpurev & 0x0F) >> 4, + mxc_get_clock(MXC_ARM_CLK) / 1000000); + return 0; +} +#endif + +/* + * Initializes on-chip ethernet controllers. + * to override, implement board_eth_init() + */ +#if defined(CONFIG_FEC_MXC) +extern int fecmxc_initialize(bd_t *bis); +#endif + +int cpu_eth_init(bd_t *bis) +{ + int rc = -ENODEV; + +#if defined(CONFIG_FEC_MXC) + rc = fecmxc_initialize(bis); +#endif + + return rc; +} + +/* + * Initializes on-chip MMC controllers. + * to override, implement board_mmc_init() + */ +int cpu_mmc_init(bd_t *bis) +{ +#ifdef CONFIG_FSL_ESDHC + return fsl_esdhc_mmc_init(bis); +#else + return 0; +#endif +} + + +void reset_cpu(ulong addr) +{ + __raw_writew(4, WDOG1_BASE_ADDR); +} diff --git a/arch/arm/cpu/arm_cortexa8/mx51/speed.c b/arch/arm/cpu/arm_cortexa8/mx51/speed.c new file mode 100644 index 0000000000..a444def7eb --- /dev/null +++ b/arch/arm/cpu/arm_cortexa8/mx51/speed.c @@ -0,0 +1,39 @@ +/* + * (C) Copyright 2000-2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +int get_clocks(void) +{ + DECLARE_GLOBAL_DATA_PTR; + +#ifdef CONFIG_FSL_ESDHC + gd->sdhc_clk = mxc_get_clock(MXC_IPG_PERCLK); +#endif + return 0; +} diff --git a/arch/arm/cpu/arm_cortexa8/mx51/timer.c b/arch/arm/cpu/arm_cortexa8/mx51/timer.c new file mode 100644 index 0000000000..8ecfec66da --- /dev/null +++ b/arch/arm/cpu/arm_cortexa8/mx51/timer.c @@ -0,0 +1,119 @@ +/* + * (C) Copyright 2007 + * Sascha Hauer, Pengutronix + * + * (C) Copyright 2009 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +/* General purpose timers registers */ +struct mxc_gpt { + unsigned int control; + unsigned int prescaler; + unsigned int status; + unsigned int nouse[6]; + unsigned int counter; +}; + +static struct mxc_gpt *cur_gpt = (struct mxc_gpt *)GPT1_BASE_ADDR; + +/* General purpose timers bitfields */ +#define GPTCR_SWR (1<<15) /* Software reset */ +#define GPTCR_FRR (1<<9) /* Freerun / restart */ +#define GPTCR_CLKSOURCE_32 (4<<6) /* Clock source */ +#define GPTCR_TEN (1) /* Timer enable */ + +static ulong timestamp; +static ulong lastinc; + +int timer_init(void) +{ + int i; + + /* setup GP Timer 1 */ + __raw_writel(GPTCR_SWR, &cur_gpt->control); + + /* We have no udelay by now */ + for (i = 0; i < 100; i++) + __raw_writel(0, &cur_gpt->control); + + __raw_writel(0, &cur_gpt->prescaler); /* 32Khz */ + + /* Freerun Mode, PERCLK1 input */ + i = __raw_readl(&cur_gpt->control); + __raw_writel(i | GPTCR_CLKSOURCE_32 | GPTCR_TEN, &cur_gpt->control); + reset_timer_masked(); + return 0; +} + +void reset_timer(void) +{ + reset_timer_masked(); +} + +void reset_timer_masked(void) +{ + ulong val = __raw_readl(&cur_gpt->counter); + lastinc = val / (CONFIG_MX51_CLK32 / CONFIG_SYS_HZ); + timestamp = 0; +} + +ulong get_timer_masked(void) +{ + ulong val = __raw_readl(&cur_gpt->counter); + val /= (CONFIG_MX51_CLK32 / CONFIG_SYS_HZ); + if (val >= lastinc) + timestamp += (val - lastinc); + else + timestamp += ((0xFFFFFFFF / (CONFIG_MX51_CLK32 / CONFIG_SYS_HZ)) + - lastinc) + val; + lastinc = val; + return val; +} + +ulong get_timer(ulong base) +{ + return get_timer_masked() - base; +} + +void set_timer(ulong t) +{ + timestamp = t; +} + +/* delay x useconds AND perserve advance timstamp value */ +void __udelay(unsigned long usec) +{ + unsigned long now, start, tmo; + tmo = usec * (CONFIG_MX51_CLK32 / 1000) / 1000; + + if (!tmo) + tmo = 1; + + now = start = readl(&cur_gpt->counter); + + while ((now - start) < tmo) + now = readl(&cur_gpt->counter); + +} diff --git a/arch/arm/cpu/arm_cortexa8/mx51/u-boot.lds b/arch/arm/cpu/arm_cortexa8/mx51/u-boot.lds new file mode 100644 index 0000000000..2953b93632 --- /dev/null +++ b/arch/arm/cpu/arm_cortexa8/mx51/u-boot.lds @@ -0,0 +1,61 @@ +/* + * January 2004 - Changed to support H4 device + * Copyright (c) 2004 Texas Instruments + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * (C) Copyright 2009 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + arch/arm/cpu/arm_cortexa8/start.o + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss) } + _end = .; +} diff --git a/arch/arm/cpu/arm_cortexa8/omap3/Makefile b/arch/arm/cpu/arm_cortexa8/omap3/Makefile new file mode 100644 index 0000000000..136b163ad7 --- /dev/null +++ b/arch/arm/cpu/arm_cortexa8/omap3/Makefile @@ -0,0 +1,55 @@ +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +SOBJS := lowlevel_init.o +SOBJS += cache.o +SOBJS += reset.o + +COBJS += board.o +COBJS += clock.o +COBJS += gpio.o +COBJS += mem.o +COBJS += syslib.o +COBJS += sys_info.o +COBJS += timer.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm_cortexa8/omap3/board.c b/arch/arm/cpu/arm_cortexa8/omap3/board.c new file mode 100644 index 0000000000..7b78fa448b --- /dev/null +++ b/arch/arm/cpu/arm_cortexa8/omap3/board.c @@ -0,0 +1,361 @@ +/* + * + * Common board functions for OMAP3 based boards. + * + * (C) Copyright 2004-2008 + * Texas Instruments, + * + * Author : + * Sunil Kumar + * Shashi Ranjan + * + * Derived from Beagle Board and 3430 SDP code by + * Richard Woodruff + * Syed Mohammed Khasim + * + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include +#include +#include +#include +#include + +extern omap3_sysinfo sysinfo; + +extern u32 is_mem_sdr(void); + +/****************************************************************************** + * Routine: delay + * Description: spinning delay to use before udelay works + *****************************************************************************/ +static inline void delay(unsigned long loops) +{ + __asm__ volatile ("1:\n" "subs %0, %1, #1\n" + "bne 1b":"=r" (loops):"0"(loops)); +} + +/****************************************************************************** + * Routine: secure_unlock + * Description: Setup security registers for access + * (GP Device only) + *****************************************************************************/ +void secure_unlock_mem(void) +{ + struct pm *pm_rt_ape_base = (struct pm *)PM_RT_APE_BASE_ADDR_ARM; + struct pm *pm_gpmc_base = (struct pm *)PM_GPMC_BASE_ADDR_ARM; + struct pm *pm_ocm_ram_base = (struct pm *)PM_OCM_RAM_BASE_ADDR_ARM; + struct pm *pm_iva2_base = (struct pm *)PM_IVA2_BASE_ADDR_ARM; + struct sms *sms_base = (struct sms *)OMAP34XX_SMS_BASE; + + /* Protection Module Register Target APE (PM_RT) */ + writel(UNLOCK_1, &pm_rt_ape_base->req_info_permission_1); + writel(UNLOCK_1, &pm_rt_ape_base->read_permission_0); + writel(UNLOCK_1, &pm_rt_ape_base->wirte_permission_0); + writel(UNLOCK_2, &pm_rt_ape_base->addr_match_1); + + writel(UNLOCK_3, &pm_gpmc_base->req_info_permission_0); + writel(UNLOCK_3, &pm_gpmc_base->read_permission_0); + writel(UNLOCK_3, &pm_gpmc_base->wirte_permission_0); + + writel(UNLOCK_3, &pm_ocm_ram_base->req_info_permission_0); + writel(UNLOCK_3, &pm_ocm_ram_base->read_permission_0); + writel(UNLOCK_3, &pm_ocm_ram_base->wirte_permission_0); + writel(UNLOCK_2, &pm_ocm_ram_base->addr_match_2); + + /* IVA Changes */ + writel(UNLOCK_3, &pm_iva2_base->req_info_permission_0); + writel(UNLOCK_3, &pm_iva2_base->read_permission_0); + writel(UNLOCK_3, &pm_iva2_base->wirte_permission_0); + + /* SDRC region 0 public */ + writel(UNLOCK_1, &sms_base->rg_att0); +} + +/****************************************************************************** + * Routine: secureworld_exit() + * Description: If chip is EMU and boot type is external + * configure secure registers and exit secure world + * general use. + *****************************************************************************/ +void secureworld_exit() +{ + unsigned long i; + + /* configrue non-secure access control register */ + __asm__ __volatile__("mrc p15, 0, %0, c1, c1, 2":"=r"(i)); + /* enabling co-processor CP10 and CP11 accesses in NS world */ + __asm__ __volatile__("orr %0, %0, #0xC00":"=r"(i)); + /* + * allow allocation of locked TLBs and L2 lines in NS world + * allow use of PLE registers in NS world also + */ + __asm__ __volatile__("orr %0, %0, #0x70000":"=r"(i)); + __asm__ __volatile__("mcr p15, 0, %0, c1, c1, 2":"=r"(i)); + + /* Enable ASA in ACR register */ + __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1":"=r"(i)); + __asm__ __volatile__("orr %0, %0, #0x10":"=r"(i)); + __asm__ __volatile__("mcr p15, 0, %0, c1, c0, 1":"=r"(i)); + + /* Exiting secure world */ + __asm__ __volatile__("mrc p15, 0, %0, c1, c1, 0":"=r"(i)); + __asm__ __volatile__("orr %0, %0, #0x31":"=r"(i)); + __asm__ __volatile__("mcr p15, 0, %0, c1, c1, 0":"=r"(i)); +} + +/****************************************************************************** + * Routine: setup_auxcr() + * Description: Write to AuxCR desired value using SMI. + * general use. + *****************************************************************************/ +void setup_auxcr() +{ + unsigned long i; + volatile unsigned int j; + /* Save r0, r12 and restore them after usage */ + __asm__ __volatile__("mov %0, r12":"=r"(j)); + __asm__ __volatile__("mov %0, r0":"=r"(i)); + + /* + * GP Device ROM code API usage here + * r12 = AUXCR Write function and r0 value + */ + __asm__ __volatile__("mov r12, #0x3"); + __asm__ __volatile__("mrc p15, 0, r0, c1, c0, 1"); + /* Enabling ASA */ + __asm__ __volatile__("orr r0, r0, #0x10"); + /* Enable L1NEON */ + __asm__ __volatile__("orr r0, r0, #1 << 5"); + /* SMI instruction to call ROM Code API */ + __asm__ __volatile__(".word 0xE1600070"); + /* Set PLD_FWD bit in L2AUXCR (Cortex-A8 erratum 725233 workaround) */ + __asm__ __volatile__("mov r12, #0x2"); + __asm__ __volatile__("mrc p15, 1, r0, c9, c0, 2"); + __asm__ __volatile__("orr r0, r0, #1 << 27"); + /* SMI instruction to call ROM Code API */ + __asm__ __volatile__(".word 0xE1600070"); + __asm__ __volatile__("mov r0, %0":"=r"(i)); + __asm__ __volatile__("mov r12, %0":"=r"(j)); +} + +/****************************************************************************** + * Routine: try_unlock_sram() + * Description: If chip is GP/EMU(special) type, unlock the SRAM for + * general use. + *****************************************************************************/ +void try_unlock_memory() +{ + int mode; + int in_sdram = is_running_in_sdram(); + + /* + * if GP device unlock device SRAM for general use + * secure code breaks for Secure/Emulation device - HS/E/T + */ + mode = get_device_type(); + if (mode == GP_DEVICE) + secure_unlock_mem(); + + /* + * If device is EMU and boot is XIP external booting + * Unlock firewalls and disable L2 and put chip + * out of secure world + * + * Assuming memories are unlocked by the demon who put us in SDRAM + */ + if ((mode <= EMU_DEVICE) && (get_boot_type() == 0x1F) + && (!in_sdram)) { + secure_unlock_mem(); + secureworld_exit(); + } + + return; +} + +/****************************************************************************** + * Routine: s_init + * Description: Does early system init of muxing and clocks. + * - Called path is with SRAM stack. + *****************************************************************************/ +void s_init(void) +{ + int in_sdram = is_running_in_sdram(); + + watchdog_init(); + + try_unlock_memory(); + + /* + * Right now flushing at low MPU speed. + * Need to move after clock init + */ + invalidate_dcache(get_device_type()); +#ifndef CONFIG_ICACHE_OFF + icache_enable(); +#endif + +#ifdef CONFIG_L2_OFF + l2_cache_disable(); +#else + l2_cache_enable(); +#endif + /* + * Writing to AuxCR in U-boot using SMI for GP DEV + * Currently SMI in Kernel on ES2 devices seems to have an issue + * Once that is resolved, we can postpone this config to kernel + */ + if (get_device_type() == GP_DEVICE) + setup_auxcr(); + + set_muxconf_regs(); + delay(100); + + prcm_init(); + + per_clocks_enable(); + + if (!in_sdram) + sdrc_init(); +} + +/****************************************************************************** + * Routine: wait_for_command_complete + * Description: Wait for posting to finish on watchdog + *****************************************************************************/ +void wait_for_command_complete(struct watchdog *wd_base) +{ + int pending = 1; + do { + pending = readl(&wd_base->wwps); + } while (pending); +} + +/****************************************************************************** + * Routine: watchdog_init + * Description: Shut down watch dogs + *****************************************************************************/ +void watchdog_init(void) +{ + struct watchdog *wd2_base = (struct watchdog *)WD2_BASE; + struct prcm *prcm_base = (struct prcm *)PRCM_BASE; + + /* + * There are 3 watch dogs WD1=Secure, WD2=MPU, WD3=IVA. WD1 is + * either taken care of by ROM (HS/EMU) or not accessible (GP). + * We need to take care of WD2-MPU or take a PRCM reset. WD3 + * should not be running and does not generate a PRCM reset. + */ + + sr32(&prcm_base->fclken_wkup, 5, 1, 1); + sr32(&prcm_base->iclken_wkup, 5, 1, 1); + wait_on_value(ST_WDT2, 0x20, &prcm_base->idlest_wkup, 5); + + writel(WD_UNLOCK1, &wd2_base->wspr); + wait_for_command_complete(wd2_base); + writel(WD_UNLOCK2, &wd2_base->wspr); +} + +/****************************************************************************** + * Routine: dram_init + * Description: sets uboots idea of sdram size + *****************************************************************************/ +int dram_init(void) +{ + DECLARE_GLOBAL_DATA_PTR; + unsigned int size0 = 0, size1 = 0; + + /* + * If a second bank of DDR is attached to CS1 this is + * where it can be started. Early init code will init + * memory on CS0. + */ + if ((sysinfo.mtype == DDR_COMBO) || (sysinfo.mtype == DDR_STACKED)) { + do_sdrc_init(CS1, NOT_EARLY); + make_cs1_contiguous(); + } + + size0 = get_sdr_cs_size(CS0); + size1 = get_sdr_cs_size(CS1); + + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + gd->bd->bi_dram[0].size = size0; + gd->bd->bi_dram[1].start = PHYS_SDRAM_1 + get_sdr_cs_offset(CS1); + gd->bd->bi_dram[1].size = size1; + + return 0; +} + +/****************************************************************************** + * Dummy function to handle errors for EABI incompatibility + *****************************************************************************/ +void abort(void) +{ +} + +#ifdef CONFIG_NAND_OMAP_GPMC +/****************************************************************************** + * OMAP3 specific command to switch between NAND HW and SW ecc + *****************************************************************************/ +static int do_switch_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ + if (argc != 2) + goto usage; + if (strncmp(argv[1], "hw", 2) == 0) + omap_nand_switch_ecc(1); + else if (strncmp(argv[1], "sw", 2) == 0) + omap_nand_switch_ecc(0); + else + goto usage; + + return 0; + +usage: + printf ("Usage: nandecc %s\n", cmdtp->usage); + return 1; +} + +U_BOOT_CMD( + nandecc, 2, 1, do_switch_ecc, + "switch OMAP3 NAND ECC calculation algorithm", + "[hw/sw] - Switch between NAND hardware (hw) or software (sw) ecc algorithm" +); + +#endif /* CONFIG_NAND_OMAP_GPMC */ + +#ifdef CONFIG_DISPLAY_BOARDINFO +/** + * Print board information + */ +int checkboard (void) +{ + char *mem_s ; + + if (is_mem_sdr()) + mem_s = "mSDR"; + else + mem_s = "LPDDR"; + + printf("%s + %s/%s\n", sysinfo.board_string, mem_s, + sysinfo.nand_string); + + return 0; +} +#endif /* CONFIG_DISPLAY_BOARDINFO */ diff --git a/arch/arm/cpu/arm_cortexa8/omap3/cache.S b/arch/arm/cpu/arm_cortexa8/omap3/cache.S new file mode 100644 index 0000000000..0f63815359 --- /dev/null +++ b/arch/arm/cpu/arm_cortexa8/omap3/cache.S @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2009 Wind River Systems, Inc. + * Tom Rix + * + * This file is based on and replaces the existing cache.c file + * The copyrights for the cache.c file are: + * + * (C) Copyright 2008 Texas Insturments + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +/* + * omap3 cache code + */ + +.align 5 +.global invalidate_dcache +.global l2_cache_enable +.global l2_cache_disable + +/* + * invalidate_dcache() + * + * Invalidate the whole D-cache. + * + * Corrupted registers: r0-r5, r7, r9-r11 + * + * - mm - mm_struct describing address space + */ +invalidate_dcache: + stmfd r13!, {r0 - r5, r7, r9 - r12, r14} + + mov r7, r0 @ take a backup of device type + cmp r0, #0x3 @ check if the device type is + @ GP + moveq r12, #0x1 @ set up to invalide L2 +smi: .word 0x01600070 @ Call SMI monitor (smieq) + cmp r7, #0x3 @ compare again in case its + @ lost + beq finished_inval @ if GP device, inval done + @ above + + mrc p15, 1, r0, c0, c0, 1 @ read clidr + ands r3, r0, #0x7000000 @ extract loc from clidr + mov r3, r3, lsr #23 @ left align loc bit field + beq finished_inval @ if loc is 0, then no need to + @ clean + mov r10, #0 @ start clean at cache level 0 +inval_loop1: + add r2, r10, r10, lsr #1 @ work out 3x current cache + @ level + mov r1, r0, lsr r2 @ extract cache type bits from + @ clidr + and r1, r1, #7 @ mask of the bits for current + @ cache only + cmp r1, #2 @ see what cache we have at + @ this level + blt skip_inval @ skip if no cache, or just + @ i-cache + mcr p15, 2, r10, c0, c0, 0 @ select current cache level + @ in cssr + mov r2, #0 @ operand for mcr SBZ + mcr p15, 0, r2, c7, c5, 4 @ flush prefetch buffer to + @ sych the new cssr&csidr, + @ with armv7 this is 'isb', + @ but we compile with armv5 + mrc p15, 1, r1, c0, c0, 0 @ read the new csidr + and r2, r1, #7 @ extract the length of the + @ cache lines + add r2, r2, #4 @ add 4 (line length offset) + ldr r4, =0x3ff + ands r4, r4, r1, lsr #3 @ find maximum number on the + @ way size + clz r5, r4 @ find bit position of way + @ size increment + ldr r7, =0x7fff + ands r7, r7, r1, lsr #13 @ extract max number of the + @ index size +inval_loop2: + mov r9, r4 @ create working copy of max + @ way size +inval_loop3: + orr r11, r10, r9, lsl r5 @ factor way and cache number + @ into r11 + orr r11, r11, r7, lsl r2 @ factor index number into r11 + mcr p15, 0, r11, c7, c6, 2 @ invalidate by set/way + subs r9, r9, #1 @ decrement the way + bge inval_loop3 + subs r7, r7, #1 @ decrement the index + bge inval_loop2 +skip_inval: + add r10, r10, #2 @ increment cache number + cmp r3, r10 + bgt inval_loop1 +finished_inval: + mov r10, #0 @ swith back to cache level 0 + mcr p15, 2, r10, c0, c0, 0 @ select current cache level + @ in cssr + mcr p15, 0, r10, c7, c5, 4 @ flush prefetch buffer, + @ with armv7 this is 'isb', + @ but we compile with armv5 + + ldmfd r13!, {r0 - r5, r7, r9 - r12, pc} + + +l2_cache_enable: + push {r0, r1, r2, lr} + @ ES2 onwards we can disable/enable L2 ourselves + bl get_cpu_rev + cmp r0, #CPU_3XX_ES20 + blt l2_cache_disable_EARLIER_THAN_ES2 + mrc 15, 0, r3, cr1, cr0, 1 + orr r3, r3, #2 + mcr 15, 0, r3, cr1, cr0, 1 + b l2_cache_enable_END +l2_cache_enable_EARLIER_THAN_ES2: + @ Save r0, r12 and restore them after usage + mov r3, ip + str r3, [sp, #4] + mov r3, r0 + @ + @ GP Device ROM code API usage here + @ r12 = AUXCR Write function and r0 value + @ + mov ip, #3 + mrc 15, 0, r0, cr1, cr0, 1 + orr r0, r0, #2 + @ SMI instruction to call ROM Code API + .word 0xe1600070 + mov r0, r3 + mov ip, r3 + str r3, [sp, #4] +l2_cache_enable_END: + pop {r1, r2, r3, pc} + + +l2_cache_disable: + push {r0, r1, r2, lr} + @ ES2 onwards we can disable/enable L2 ourselves + bl get_cpu_rev + cmp r0, #CPU_3XX_ES20 + blt l2_cache_disable_EARLIER_THAN_ES2 + mrc 15, 0, r3, cr1, cr0, 1 + bic r3, r3, #2 + mcr 15, 0, r3, cr1, cr0, 1 + b l2_cache_disable_END +l2_cache_disable_EARLIER_THAN_ES2: + @ Save r0, r12 and restore them after usage + mov r3, ip + str r3, [sp, #4] + mov r3, r0 + @ + @ GP Device ROM code API usage here + @ r12 = AUXCR Write function and r0 value + @ + mov ip, #3 + mrc 15, 0, r0, cr1, cr0, 1 + bic r0, r0, #2 + @ SMI instruction to call ROM Code API + .word 0xe1600070 + mov r0, r3 + mov ip, r3 + str r3, [sp, #4] +l2_cache_disable_END: + pop {r1, r2, r3, pc} diff --git a/arch/arm/cpu/arm_cortexa8/omap3/clock.c b/arch/arm/cpu/arm_cortexa8/omap3/clock.c new file mode 100644 index 0000000000..6330c9e5da --- /dev/null +++ b/arch/arm/cpu/arm_cortexa8/omap3/clock.c @@ -0,0 +1,416 @@ +/* + * (C) Copyright 2008 + * Texas Instruments, + * + * Author : + * Manikandan Pillai + * + * Derived from Beagle Board and OMAP3 SDP code by + * Richard Woodruff + * Syed Mohammed Khasim + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/****************************************************************************** + * get_sys_clk_speed() - determine reference oscillator speed + * based on known 32kHz clock and gptimer. + *****************************************************************************/ +u32 get_osc_clk_speed(void) +{ + u32 start, cstart, cend, cdiff, cdiv, val; + struct prcm *prcm_base = (struct prcm *)PRCM_BASE; + struct prm *prm_base = (struct prm *)PRM_BASE; + struct gptimer *gpt1_base = (struct gptimer *)OMAP34XX_GPT1; + struct s32ktimer *s32k_base = (struct s32ktimer *)SYNC_32KTIMER_BASE; + + val = readl(&prm_base->clksrc_ctrl); + + if (val & SYSCLKDIV_2) + cdiv = 2; + else if (val & SYSCLKDIV_1) + cdiv = 1; + else + /* + * Should never reach here! (Assume divider as 1) + */ + cdiv = 1; + + /* enable timer2 */ + val = readl(&prcm_base->clksel_wkup) | CLKSEL_GPT1; + + /* select sys_clk for GPT1 */ + writel(val, &prcm_base->clksel_wkup); + + /* Enable I and F Clocks for GPT1 */ + val = readl(&prcm_base->iclken_wkup) | EN_GPT1 | EN_32KSYNC; + writel(val, &prcm_base->iclken_wkup); + + val = readl(&prcm_base->fclken_wkup) | EN_GPT1; + writel(val, &prcm_base->fclken_wkup); + + writel(0, &gpt1_base->tldr); /* start counting at 0 */ + writel(GPT_EN, &gpt1_base->tclr); /* enable clock */ + + /* enable 32kHz source, determine sys_clk via gauging */ + + /* start time in 20 cycles */ + start = 20 + readl(&s32k_base->s32k_cr); + + /* dead loop till start time */ + while (readl(&s32k_base->s32k_cr) < start); + + /* get start sys_clk count */ + cstart = readl(&gpt1_base->tcrr); + + /* wait for 40 cycles */ + while (readl(&s32k_base->s32k_cr) < (start + 20)) ; + cend = readl(&gpt1_base->tcrr); /* get end sys_clk count */ + cdiff = cend - cstart; /* get elapsed ticks */ + + if (cdiv == 2) + { + cdiff *= 2; + } + + /* based on number of ticks assign speed */ + if (cdiff > 19000) + return S38_4M; + else if (cdiff > 15200) + return S26M; + else if (cdiff > 13000) + return S24M; + else if (cdiff > 9000) + return S19_2M; + else if (cdiff > 7600) + return S13M; + else + return S12M; +} + +/****************************************************************************** + * get_sys_clkin_sel() - returns the sys_clkin_sel field value based on + * input oscillator clock frequency. + *****************************************************************************/ +void get_sys_clkin_sel(u32 osc_clk, u32 *sys_clkin_sel) +{ + switch(osc_clk) { + case S38_4M: + *sys_clkin_sel = 4; + break; + case S26M: + *sys_clkin_sel = 3; + break; + case S19_2M: + *sys_clkin_sel = 2; + break; + case S13M: + *sys_clkin_sel = 1; + break; + case S12M: + default: + *sys_clkin_sel = 0; + } +} + +/****************************************************************************** + * prcm_init() - inits clocks for PRCM as defined in clocks.h + * called from SRAM, or Flash (using temp SRAM stack). + *****************************************************************************/ +void prcm_init(void) +{ + void (*f_lock_pll) (u32, u32, u32, u32); + int xip_safe, p0, p1, p2, p3; + u32 osc_clk = 0, sys_clkin_sel; + u32 clk_index, sil_index = 0; + struct prm *prm_base = (struct prm *)PRM_BASE; + struct prcm *prcm_base = (struct prcm *)PRCM_BASE; + dpll_param *dpll_param_p; + + f_lock_pll = (void *) ((u32) &_end_vect - (u32) &_start + + SRAM_VECT_CODE); + + xip_safe = is_running_in_sram(); + + /* + * Gauge the input clock speed and find out the sys_clkin_sel + * value corresponding to the input clock. + */ + osc_clk = get_osc_clk_speed(); + get_sys_clkin_sel(osc_clk, &sys_clkin_sel); + + /* set input crystal speed */ + sr32(&prm_base->clksel, 0, 3, sys_clkin_sel); + + /* If the input clock is greater than 19.2M always divide/2 */ + if (sys_clkin_sel > 2) { + /* input clock divider */ + sr32(&prm_base->clksrc_ctrl, 6, 2, 2); + clk_index = sys_clkin_sel / 2; + } else { + /* input clock divider */ + sr32(&prm_base->clksrc_ctrl, 6, 2, 1); + clk_index = sys_clkin_sel; + } + + /* + * The DPLL tables are defined according to sysclk value and + * silicon revision. The clk_index value will be used to get + * the values for that input sysclk from the DPLL param table + * and sil_index will get the values for that SysClk for the + * appropriate silicon rev. + */ + if (get_cpu_rev()) + sil_index = 1; + + /* Unlock MPU DPLL (slows things down, and needed later) */ + sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOW_POWER_BYPASS); + wait_on_value(ST_MPU_CLK, 0, &prcm_base->idlest_pll_mpu, LDELAY); + + /* Getting the base address of Core DPLL param table */ + dpll_param_p = (dpll_param *) get_core_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + dpll_param_p = dpll_param_p + 3 * clk_index + sil_index; + if (xip_safe) { + /* + * CORE DPLL + * sr32(CM_CLKSEL2_EMU) set override to work when asleep + */ + sr32(&prcm_base->clken_pll, 0, 3, PLL_FAST_RELOCK_BYPASS); + wait_on_value(ST_CORE_CLK, 0, &prcm_base->idlest_ckgen, + LDELAY); + + /* + * For OMAP3 ES1.0 Errata 1.50, default value directly doesn't + * work. write another value and then default value. + */ + + /* m3x2 */ + sr32(&prcm_base->clksel1_emu, 16, 5, CORE_M3X2 + 1); + /* m3x2 */ + sr32(&prcm_base->clksel1_emu, 16, 5, CORE_M3X2); + /* Set M2 */ + sr32(&prcm_base->clksel1_pll, 27, 2, dpll_param_p->m2); + /* Set M */ + sr32(&prcm_base->clksel1_pll, 16, 11, dpll_param_p->m); + /* Set N */ + sr32(&prcm_base->clksel1_pll, 8, 7, dpll_param_p->n); + /* 96M Src */ + sr32(&prcm_base->clksel1_pll, 6, 1, 0); + /* ssi */ + sr32(&prcm_base->clksel_core, 8, 4, CORE_SSI_DIV); + /* fsusb */ + sr32(&prcm_base->clksel_core, 4, 2, CORE_FUSB_DIV); + /* l4 */ + sr32(&prcm_base->clksel_core, 2, 2, CORE_L4_DIV); + /* l3 */ + sr32(&prcm_base->clksel_core, 0, 2, CORE_L3_DIV); + /* gfx */ + sr32(&prcm_base->clksel_gfx, 0, 3, GFX_DIV); + /* reset mgr */ + sr32(&prcm_base->clksel_wkup, 1, 2, WKUP_RSM); + /* FREQSEL */ + sr32(&prcm_base->clken_pll, 4, 4, dpll_param_p->fsel); + /* lock mode */ + sr32(&prcm_base->clken_pll, 0, 3, PLL_LOCK); + + wait_on_value(ST_CORE_CLK, 1, &prcm_base->idlest_ckgen, + LDELAY); + } else if (is_running_in_flash()) { + /* + * if running from flash, jump to small relocated code + * area in SRAM. + */ + p0 = readl(&prcm_base->clken_pll); + sr32(&p0, 0, 3, PLL_FAST_RELOCK_BYPASS); + sr32(&p0, 4, 4, dpll_param_p->fsel); /* FREQSEL */ + + p1 = readl(&prcm_base->clksel1_pll); + sr32(&p1, 27, 2, dpll_param_p->m2); /* Set M2 */ + sr32(&p1, 16, 11, dpll_param_p->m); /* Set M */ + sr32(&p1, 8, 7, dpll_param_p->n); /* Set N */ + sr32(&p1, 6, 1, 0); /* set source for 96M */ + + p2 = readl(&prcm_base->clksel_core); + sr32(&p2, 8, 4, CORE_SSI_DIV); /* ssi */ + sr32(&p2, 4, 2, CORE_FUSB_DIV); /* fsusb */ + sr32(&p2, 2, 2, CORE_L4_DIV); /* l4 */ + sr32(&p2, 0, 2, CORE_L3_DIV); /* l3 */ + + p3 = (u32)&prcm_base->idlest_ckgen; + + (*f_lock_pll) (p0, p1, p2, p3); + } + + /* PER DPLL */ + sr32(&prcm_base->clken_pll, 16, 3, PLL_STOP); + wait_on_value(ST_PERIPH_CLK, 0, &prcm_base->idlest_ckgen, LDELAY); + + /* Getting the base address to PER DPLL param table */ + + /* Set N */ + dpll_param_p = (dpll_param *) get_per_dpll_param(); + + /* Moving it to the right sysclk base */ + dpll_param_p = dpll_param_p + clk_index; + + /* + * Errata 1.50 Workaround for OMAP3 ES1.0 only + * If using default divisors, write default divisor + 1 + * and then the actual divisor value + */ + sr32(&prcm_base->clksel1_emu, 24, 5, PER_M6X2 + 1); /* set M6 */ + sr32(&prcm_base->clksel1_emu, 24, 5, PER_M6X2); /* set M6 */ + sr32(&prcm_base->clksel_cam, 0, 5, PER_M5X2 + 1); /* set M5 */ + sr32(&prcm_base->clksel_cam, 0, 5, PER_M5X2); /* set M5 */ + sr32(&prcm_base->clksel_dss, 0, 5, PER_M4X2 + 1); /* set M4 */ + sr32(&prcm_base->clksel_dss, 0, 5, PER_M4X2); /* set M4 */ + sr32(&prcm_base->clksel_dss, 8, 5, PER_M3X2 + 1); /* set M3 */ + sr32(&prcm_base->clksel_dss, 8, 5, PER_M3X2); /* set M3 */ + sr32(&prcm_base->clksel3_pll, 0, 5, dpll_param_p->m2 + 1); /* set M2 */ + sr32(&prcm_base->clksel3_pll, 0, 5, dpll_param_p->m2); /* set M2 */ + /* Workaround end */ + + sr32(&prcm_base->clksel2_pll, 8, 11, dpll_param_p->m); /* set m */ + sr32(&prcm_base->clksel2_pll, 0, 7, dpll_param_p->n); /* set n */ + sr32(&prcm_base->clken_pll, 20, 4, dpll_param_p->fsel); /* FREQSEL */ + sr32(&prcm_base->clken_pll, 16, 3, PLL_LOCK); /* lock mode */ + wait_on_value(ST_PERIPH_CLK, 2, &prcm_base->idlest_ckgen, LDELAY); + + /* Getting the base address to MPU DPLL param table */ + dpll_param_p = (dpll_param *) get_mpu_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + dpll_param_p = dpll_param_p + 3 * clk_index + sil_index; + + /* MPU DPLL (unlocked already) */ + + /* Set M2 */ + sr32(&prcm_base->clksel2_pll_mpu, 0, 5, dpll_param_p->m2); + /* Set M */ + sr32(&prcm_base->clksel1_pll_mpu, 8, 11, dpll_param_p->m); + /* Set N */ + sr32(&prcm_base->clksel1_pll_mpu, 0, 7, dpll_param_p->n); + /* FREQSEL */ + sr32(&prcm_base->clken_pll_mpu, 4, 4, dpll_param_p->fsel); + /* lock mode */ + sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOCK); + wait_on_value(ST_MPU_CLK, 1, &prcm_base->idlest_pll_mpu, LDELAY); + + /* Getting the base address to IVA DPLL param table */ + dpll_param_p = (dpll_param *) get_iva_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + dpll_param_p = dpll_param_p + 3 * clk_index + sil_index; + + /* IVA DPLL (set to 12*20=240MHz) */ + sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_STOP); + wait_on_value(ST_IVA2_CLK, 0, &prcm_base->idlest_pll_iva2, LDELAY); + /* set M2 */ + sr32(&prcm_base->clksel2_pll_iva2, 0, 5, dpll_param_p->m2); + /* set M */ + sr32(&prcm_base->clksel1_pll_iva2, 8, 11, dpll_param_p->m); + /* set N */ + sr32(&prcm_base->clksel1_pll_iva2, 0, 7, dpll_param_p->n); + /* FREQSEL */ + sr32(&prcm_base->clken_pll_iva2, 4, 4, dpll_param_p->fsel); + /* lock mode */ + sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_LOCK); + wait_on_value(ST_IVA2_CLK, 1, &prcm_base->idlest_pll_iva2, LDELAY); + + /* Set up GPTimers to sys_clk source only */ + sr32(&prcm_base->clksel_per, 0, 8, 0xff); + sr32(&prcm_base->clksel_wkup, 0, 1, 1); + + sdelay(5000); +} + +/****************************************************************************** + * peripheral_enable() - Enable the clks & power for perifs (GPT2, UART1,...) + *****************************************************************************/ +void per_clocks_enable(void) +{ + struct prcm *prcm_base = (struct prcm *)PRCM_BASE; + + /* Enable GP2 timer. */ + sr32(&prcm_base->clksel_per, 0, 1, 0x1); /* GPT2 = sys clk */ + sr32(&prcm_base->iclken_per, 3, 1, 0x1); /* ICKen GPT2 */ + sr32(&prcm_base->fclken_per, 3, 1, 0x1); /* FCKen GPT2 */ + +#ifdef CONFIG_SYS_NS16550 + /* Enable UART1 clocks */ + sr32(&prcm_base->fclken1_core, 13, 1, 0x1); + sr32(&prcm_base->iclken1_core, 13, 1, 0x1); + + /* UART 3 Clocks */ + sr32(&prcm_base->fclken_per, 11, 1, 0x1); + sr32(&prcm_base->iclken_per, 11, 1, 0x1); +#endif + +#ifdef CONFIG_OMAP3_GPIO_2 + sr32(&prcm_base->fclken_per, 13, 1, 1); + sr32(&prcm_base->iclken_per, 13, 1, 1); +#endif +#ifdef CONFIG_OMAP3_GPIO_3 + sr32(&prcm_base->fclken_per, 14, 1, 1); + sr32(&prcm_base->iclken_per, 14, 1, 1); +#endif +#ifdef CONFIG_OMAP3_GPIO_4 + sr32(&prcm_base->fclken_per, 15, 1, 1); + sr32(&prcm_base->iclken_per, 15, 1, 1); +#endif +#ifdef CONFIG_OMAP3_GPIO_5 + sr32(&prcm_base->fclken_per, 16, 1, 1); + sr32(&prcm_base->iclken_per, 16, 1, 1); +#endif +#ifdef CONFIG_OMAP3_GPIO_6 + sr32(&prcm_base->fclken_per, 17, 1, 1); + sr32(&prcm_base->iclken_per, 17, 1, 1); +#endif + +#ifdef CONFIG_DRIVER_OMAP34XX_I2C + /* Turn on all 3 I2C clocks */ + sr32(&prcm_base->fclken1_core, 15, 3, 0x7); + sr32(&prcm_base->iclken1_core, 15, 3, 0x7); /* I2C1,2,3 = on */ +#endif + /* Enable the ICLK for 32K Sync Timer as its used in udelay */ + sr32(&prcm_base->iclken_wkup, 2, 1, 0x1); + + sr32(&prcm_base->fclken_iva2, 0, 32, FCK_IVA2_ON); + sr32(&prcm_base->fclken1_core, 0, 32, FCK_CORE1_ON); + sr32(&prcm_base->iclken1_core, 0, 32, ICK_CORE1_ON); + sr32(&prcm_base->iclken2_core, 0, 32, ICK_CORE2_ON); + sr32(&prcm_base->fclken_wkup, 0, 32, FCK_WKUP_ON); + sr32(&prcm_base->iclken_wkup, 0, 32, ICK_WKUP_ON); + sr32(&prcm_base->fclken_dss, 0, 32, FCK_DSS_ON); + sr32(&prcm_base->iclken_dss, 0, 32, ICK_DSS_ON); + sr32(&prcm_base->fclken_cam, 0, 32, FCK_CAM_ON); + sr32(&prcm_base->iclken_cam, 0, 32, ICK_CAM_ON); + sr32(&prcm_base->fclken_per, 0, 32, FCK_PER_ON); + sr32(&prcm_base->iclken_per, 0, 32, ICK_PER_ON); + + sdelay(1000); +} diff --git a/arch/arm/cpu/arm_cortexa8/omap3/gpio.c b/arch/arm/cpu/arm_cortexa8/omap3/gpio.c new file mode 100644 index 0000000000..aeb6066d89 --- /dev/null +++ b/arch/arm/cpu/arm_cortexa8/omap3/gpio.c @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2009 Wind River Systems, Inc. + * Tom Rix + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * This work is derived from the linux 2.6.27 kernel source + * To fetch, use the kernel repository + * git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git + * Use the v2.6.27 tag. + * + * Below is the original's header including its copyright + * + * linux/arch/arm/plat-omap/gpio.c + * + * Support functions for OMAP GPIO + * + * Copyright (C) 2003-2005 Nokia Corporation + * Written by Juha Yrjölä + * + * 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. + */ +#include +#include +#include +#include + +static struct gpio_bank gpio_bank_34xx[6] = { + { (void *)OMAP34XX_GPIO1_BASE, METHOD_GPIO_24XX }, + { (void *)OMAP34XX_GPIO2_BASE, METHOD_GPIO_24XX }, + { (void *)OMAP34XX_GPIO3_BASE, METHOD_GPIO_24XX }, + { (void *)OMAP34XX_GPIO4_BASE, METHOD_GPIO_24XX }, + { (void *)OMAP34XX_GPIO5_BASE, METHOD_GPIO_24XX }, + { (void *)OMAP34XX_GPIO6_BASE, METHOD_GPIO_24XX }, +}; + +static struct gpio_bank *gpio_bank = &gpio_bank_34xx[0]; + +static inline struct gpio_bank *get_gpio_bank(int gpio) +{ + return &gpio_bank[gpio >> 5]; +} + +static inline int get_gpio_index(int gpio) +{ + return gpio & 0x1f; +} + +static inline int gpio_valid(int gpio) +{ + if (gpio < 0) + return -1; + if (gpio < 192) + return 0; + return -1; +} + +static int check_gpio(int gpio) +{ + if (gpio_valid(gpio) < 0) { + printf("ERROR : check_gpio: invalid GPIO %d\n", gpio); + return -1; + } + return 0; +} + +static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input) +{ + void *reg = bank->base; + u32 l; + + switch (bank->method) { + case METHOD_GPIO_24XX: + reg += OMAP24XX_GPIO_OE; + break; + default: + return; + } + l = __raw_readl(reg); + if (is_input) + l |= 1 << gpio; + else + l &= ~(1 << gpio); + __raw_writel(l, reg); +} + +void omap_set_gpio_direction(int gpio, int is_input) +{ + struct gpio_bank *bank; + + if (check_gpio(gpio) < 0) + return; + bank = get_gpio_bank(gpio); + _set_gpio_direction(bank, get_gpio_index(gpio), is_input); +} + +static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) +{ + void *reg = bank->base; + u32 l = 0; + + switch (bank->method) { + case METHOD_GPIO_24XX: + if (enable) + reg += OMAP24XX_GPIO_SETDATAOUT; + else + reg += OMAP24XX_GPIO_CLEARDATAOUT; + l = 1 << gpio; + break; + default: + printf("omap3-gpio unknown bank method %s %d\n", + __FILE__, __LINE__); + return; + } + __raw_writel(l, reg); +} + +void omap_set_gpio_dataout(int gpio, int enable) +{ + struct gpio_bank *bank; + + if (check_gpio(gpio) < 0) + return; + bank = get_gpio_bank(gpio); + _set_gpio_dataout(bank, get_gpio_index(gpio), enable); +} + +int omap_get_gpio_datain(int gpio) +{ + struct gpio_bank *bank; + void *reg; + + if (check_gpio(gpio) < 0) + return -EINVAL; + bank = get_gpio_bank(gpio); + reg = bank->base; + switch (bank->method) { + case METHOD_GPIO_24XX: + reg += OMAP24XX_GPIO_DATAIN; + break; + default: + return -EINVAL; + } + return (__raw_readl(reg) + & (1 << get_gpio_index(gpio))) != 0; +} + +static void _reset_gpio(struct gpio_bank *bank, int gpio) +{ + _set_gpio_direction(bank, get_gpio_index(gpio), 1); +} + +int omap_request_gpio(int gpio) +{ + if (check_gpio(gpio) < 0) + return -EINVAL; + + return 0; +} + +void omap_free_gpio(int gpio) +{ + struct gpio_bank *bank; + + if (check_gpio(gpio) < 0) + return; + bank = get_gpio_bank(gpio); + + _reset_gpio(bank, gpio); +} diff --git a/arch/arm/cpu/arm_cortexa8/omap3/lowlevel_init.S b/arch/arm/cpu/arm_cortexa8/omap3/lowlevel_init.S new file mode 100644 index 0000000000..73063ec8e6 --- /dev/null +++ b/arch/arm/cpu/arm_cortexa8/omap3/lowlevel_init.S @@ -0,0 +1,361 @@ +/* + * Board specific setup info + * + * (C) Copyright 2008 + * Texas Instruments, + * + * Initial Code by: + * Richard Woodruff + * Syed Mohammed Khasim + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include + +_TEXT_BASE: + .word TEXT_BASE /* sdram load addr from config.mk */ + +#if !defined(CONFIG_SYS_NAND_BOOT) && !defined(CONFIG_SYS_NAND_BOOT) +/************************************************************************** + * cpy_clk_code: relocates clock code into SRAM where its safer to execute + * R1 = SRAM destination address. + *************************************************************************/ +.global cpy_clk_code + cpy_clk_code: + /* Copy DPLL code into SRAM */ + adr r0, go_to_speed /* get addr of clock setting code */ + mov r2, #384 /* r2 size to copy (div by 32 bytes) */ + mov r1, r1 /* r1 <- dest address (passed in) */ + add r2, r2, r0 /* r2 <- source end address */ +next2: + ldmia r0!, {r3 - r10} /* copy from source address [r0] */ + stmia r1!, {r3 - r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end address [r2] */ + bne next2 + mov pc, lr /* back to caller */ + +/* *************************************************************************** + * go_to_speed: -Moves to bypass, -Commits clock dividers, -puts dpll at speed + * -executed from SRAM. + * R0 = CM_CLKEN_PLL-bypass value + * R1 = CM_CLKSEL1_PLL-m, n, and divider values + * R2 = CM_CLKSEL_CORE-divider values + * R3 = CM_IDLEST_CKGEN - addr dpll lock wait + * + * Note: If core unlocks/relocks and SDRAM is running fast already it gets + * confused. A reset of the controller gets it back. Taking away its + * L3 when its not in self refresh seems bad for it. Normally, this + * code runs from flash before SDR is init so that should be ok. + ****************************************************************************/ +.global go_to_speed + go_to_speed: + stmfd sp!, {r4 - r6} + + /* move into fast relock bypass */ + ldr r4, pll_ctl_add + str r0, [r4] +wait1: + ldr r5, [r3] /* get status */ + and r5, r5, #0x1 /* isolate core status */ + cmp r5, #0x1 /* still locked? */ + beq wait1 /* if lock, loop */ + + /* set new dpll dividers _after_ in bypass */ + ldr r5, pll_div_add1 + str r1, [r5] /* set m, n, m2 */ + ldr r5, pll_div_add2 + str r2, [r5] /* set l3/l4/.. dividers*/ + ldr r5, pll_div_add3 /* wkup */ + ldr r2, pll_div_val3 /* rsm val */ + str r2, [r5] + ldr r5, pll_div_add4 /* gfx */ + ldr r2, pll_div_val4 + str r2, [r5] + ldr r5, pll_div_add5 /* emu */ + ldr r2, pll_div_val5 + str r2, [r5] + + /* now prepare GPMC (flash) for new dpll speed */ + /* flash needs to be stable when we jump back to it */ + ldr r5, flash_cfg3_addr + ldr r2, flash_cfg3_val + str r2, [r5] + ldr r5, flash_cfg4_addr + ldr r2, flash_cfg4_val + str r2, [r5] + ldr r5, flash_cfg5_addr + ldr r2, flash_cfg5_val + str r2, [r5] + ldr r5, flash_cfg1_addr + ldr r2, [r5] + orr r2, r2, #0x3 /* up gpmc divider */ + str r2, [r5] + + /* lock DPLL3 and wait a bit */ + orr r0, r0, #0x7 /* set up for lock mode */ + str r0, [r4] /* lock */ + nop /* ARM slow at this point working at sys_clk */ + nop + nop + nop +wait2: + ldr r5, [r3] /* get status */ + and r5, r5, #0x1 /* isolate core status */ + cmp r5, #0x1 /* still locked? */ + bne wait2 /* if lock, loop */ + nop + nop + nop + nop + ldmfd sp!, {r4 - r6} + mov pc, lr /* back to caller, locked */ + +_go_to_speed: .word go_to_speed + +/* these constants need to be close for PIC code */ +/* The Nor has to be in the Flash Base CS0 for this condition to happen */ +flash_cfg1_addr: + .word (GPMC_CONFIG_CS0_BASE + GPMC_CONFIG1) +flash_cfg3_addr: + .word (GPMC_CONFIG_CS0_BASE + GPMC_CONFIG3) +flash_cfg3_val: + .word STNOR_GPMC_CONFIG3 +flash_cfg4_addr: + .word (GPMC_CONFIG_CS0_BASE + GPMC_CONFIG4) +flash_cfg4_val: + .word STNOR_GPMC_CONFIG4 +flash_cfg5_val: + .word STNOR_GPMC_CONFIG5 +flash_cfg5_addr: + .word (GPMC_CONFIG_CS0_BASE + GPMC_CONFIG5) +pll_ctl_add: + .word CM_CLKEN_PLL +pll_div_add1: + .word CM_CLKSEL1_PLL +pll_div_add2: + .word CM_CLKSEL_CORE +pll_div_add3: + .word CM_CLKSEL_WKUP +pll_div_val3: + .word (WKUP_RSM << 1) +pll_div_add4: + .word CM_CLKSEL_GFX +pll_div_val4: + .word (GFX_DIV << 0) +pll_div_add5: + .word CM_CLKSEL1_EMU +pll_div_val5: + .word CLSEL1_EMU_VAL + +#endif + +.globl lowlevel_init +lowlevel_init: + ldr sp, SRAM_STACK + str ip, [sp] /* stash old link register */ + mov ip, lr /* save link reg across call */ + bl s_init /* go setup pll, mux, memory */ + ldr ip, [sp] /* restore save ip */ + mov lr, ip /* restore link reg */ + + /* back to arch calling code */ + mov pc, lr + + /* the literal pools origin */ + .ltorg + +REG_CONTROL_STATUS: + .word CONTROL_STATUS +SRAM_STACK: + .word LOW_LEVEL_SRAM_STACK + +/* DPLL(1-4) PARAM TABLES */ + +/* + * Each of the tables has M, N, FREQSEL, M2 values defined for nominal + * OPP (1.2V). The fields are defined according to dpll_param struct (clock.c). + * The values are defined for all possible sysclk and for ES1 and ES2. + */ + +mpu_dpll_param: +/* 12MHz */ +/* ES1 */ +.word MPU_M_12_ES1, MPU_N_12_ES1, MPU_FSEL_12_ES1, MPU_M2_12_ES1 +/* ES2 */ +.word MPU_M_12_ES2, MPU_N_12_ES2, MPU_FSEL_12_ES2, MPU_M2_ES2 +/* 3410 */ +.word MPU_M_12, MPU_N_12, MPU_FSEL_12, MPU_M2_12 + +/* 13MHz */ +/* ES1 */ +.word MPU_M_13_ES1, MPU_N_13_ES1, MPU_FSEL_13_ES1, MPU_M2_13_ES1 +/* ES2 */ +.word MPU_M_13_ES2, MPU_N_13_ES2, MPU_FSEL_13_ES2, MPU_M2_13_ES2 +/* 3410 */ +.word MPU_M_13, MPU_N_13, MPU_FSEL_13, MPU_M2_13 + +/* 19.2MHz */ +/* ES1 */ +.word MPU_M_19P2_ES1, MPU_N_19P2_ES1, MPU_FSEL_19P2_ES1, MPU_M2_19P2_ES1 +/* ES2 */ +.word MPU_M_19P2_ES2, MPU_N_19P2_ES2, MPU_FSEL_19P2_ES2, MPU_M2_19P2_ES2 +/* 3410 */ +.word MPU_M_19P2, MPU_N_19P2, MPU_FSEL_19P2, MPU_M2_19P2 + +/* 26MHz */ +/* ES1 */ +.word MPU_M_26_ES1, MPU_N_26_ES1, MPU_FSEL_26_ES1, MPU_M2_26_ES1 +/* ES2 */ +.word MPU_M_26_ES2, MPU_N_26_ES2, MPU_FSEL_26_ES2, MPU_M2_26_ES2 +/* 3410 */ +.word MPU_M_26, MPU_N_26, MPU_FSEL_26, MPU_M2_26 + +/* 38.4MHz */ +/* ES1 */ +.word MPU_M_38P4_ES1, MPU_N_38P4_ES1, MPU_FSEL_38P4_ES1, MPU_M2_38P4_ES1 +/* ES2 */ +.word MPU_M_38P4_ES2, MPU_N_38P4_ES2, MPU_FSEL_38P4_ES2, MPU_M2_38P4_ES2 +/* 3410 */ +.word MPU_M_38P4, MPU_N_38P4, MPU_FSEL_38P4, MPU_M2_38P4 + + +.globl get_mpu_dpll_param +get_mpu_dpll_param: + adr r0, mpu_dpll_param + mov pc, lr + +iva_dpll_param: +/* 12MHz */ +/* ES1 */ +.word IVA_M_12_ES1, IVA_N_12_ES1, IVA_FSEL_12_ES1, IVA_M2_12_ES1 +/* ES2 */ +.word IVA_M_12_ES2, IVA_N_12_ES2, IVA_FSEL_12_ES2, IVA_M2_12_ES2 +/* 3410 */ +.word IVA_M_12, IVA_N_12, IVA_FSEL_12, IVA_M2_12 + +/* 13MHz */ +/* ES1 */ +.word IVA_M_13_ES1, IVA_N_13_ES1, IVA_FSEL_13_ES1, IVA_M2_13_ES1 +/* ES2 */ +.word IVA_M_13_ES2, IVA_N_13_ES2, IVA_FSEL_13_ES2, IVA_M2_13_ES2 +/* 3410 */ +.word IVA_M_13, IVA_N_13, IVA_FSEL_13, IVA_M2_13 + +/* 19.2MHz */ +/* ES1 */ +.word IVA_M_19P2_ES1, IVA_N_19P2_ES1, IVA_FSEL_19P2_ES1, IVA_M2_19P2_ES1 +/* ES2 */ +.word IVA_M_19P2_ES2, IVA_N_19P2_ES2, IVA_FSEL_19P2_ES2, IVA_M2_19P2_ES2 +/* 3410 */ +.word IVA_M_19P2, IVA_N_19P2, IVA_FSEL_19P2, IVA_M2_19P2 + +/* 26MHz */ +/* ES1 */ +.word IVA_M_26_ES1, IVA_N_26_ES1, IVA_FSEL_26_ES1, IVA_M2_26_ES1 +/* ES2 */ +.word IVA_M_26_ES2, IVA_N_26_ES2, IVA_FSEL_26_ES2, IVA_M2_26_ES2 +/* 3410 */ +.word IVA_M_26, IVA_N_26, IVA_FSEL_26, IVA_M2_26 + +/* 38.4MHz */ +/* ES1 */ +.word IVA_M_38P4_ES1, IVA_N_38P4_ES1, IVA_FSEL_38P4_ES1, IVA_M2_38P4_ES1 +/* ES2 */ +.word IVA_M_38P4_ES2, IVA_N_38P4_ES2, IVA_FSEL_38P4_ES2, IVA_M2_38P4_ES2 +/* 3410 */ +.word IVA_M_38P4, IVA_N_38P4, IVA_FSEL_38P4, IVA_M2_38P4 + + +.globl get_iva_dpll_param +get_iva_dpll_param: + adr r0, iva_dpll_param + mov pc, lr + +/* Core DPLL targets for L3 at 166 & L133 */ +core_dpll_param: +/* 12MHz */ +/* ES1 */ +.word CORE_M_12_ES1, CORE_N_12_ES1, CORE_FSL_12_ES1, CORE_M2_12_ES1 +/* ES2 */ +.word CORE_M_12, CORE_N_12, CORE_FSEL_12, CORE_M2_12 +/* 3410 */ +.word CORE_M_12, CORE_N_12, CORE_FSEL_12, CORE_M2_12 + +/* 13MHz */ +/* ES1 */ +.word CORE_M_13_ES1, CORE_N_13_ES1, CORE_FSL_13_ES1, CORE_M2_13_ES1 +/* ES2 */ +.word CORE_M_13, CORE_N_13, CORE_FSEL_13, CORE_M2_13 +/* 3410 */ +.word CORE_M_13, CORE_N_13, CORE_FSEL_13, CORE_M2_13 + +/* 19.2MHz */ +/* ES1 */ +.word CORE_M_19P2_ES1, CORE_N_19P2_ES1, CORE_FSL_19P2_ES1, CORE_M2_19P2_ES1 +/* ES2 */ +.word CORE_M_19P2, CORE_N_19P2, CORE_FSEL_19P2, CORE_M2_19P2 +/* 3410 */ +.word CORE_M_19P2, CORE_N_19P2, CORE_FSEL_19P2, CORE_M2_19P2 + +/* 26MHz */ +/* ES1 */ +.word CORE_M_26_ES1, CORE_N_26_ES1, CORE_FSL_26_ES1, CORE_M2_26_ES1 +/* ES2 */ +.word CORE_M_26, CORE_N_26, CORE_FSEL_26, CORE_M2_26 +/* 3410 */ +.word CORE_M_26, CORE_N_26, CORE_FSEL_26, CORE_M2_26 + +/* 38.4MHz */ +/* ES1 */ +.word CORE_M_38P4_ES1, CORE_N_38P4_ES1, CORE_FSL_38P4_ES1, CORE_M2_38P4_ES1 +/* ES2 */ +.word CORE_M_38P4, CORE_N_38P4, CORE_FSEL_38P4, CORE_M2_38P4 +/* 3410 */ +.word CORE_M_38P4, CORE_N_38P4, CORE_FSEL_38P4, CORE_M2_38P4 + +.globl get_core_dpll_param +get_core_dpll_param: + adr r0, core_dpll_param + mov pc, lr + +/* PER DPLL values are same for both ES1 and ES2 */ +per_dpll_param: +/* 12MHz */ +.word PER_M_12, PER_N_12, PER_FSEL_12, PER_M2_12 + +/* 13MHz */ +.word PER_M_13, PER_N_13, PER_FSEL_13, PER_M2_13 + +/* 19.2MHz */ +.word PER_M_19P2, PER_N_19P2, PER_FSEL_19P2, PER_M2_19P2 + +/* 26MHz */ +.word PER_M_26, PER_N_26, PER_FSEL_26, PER_M2_26 + +/* 38.4MHz */ +.word PER_M_38P4, PER_N_38P4, PER_FSEL_38P4, PER_M2_38P4 + +.globl get_per_dpll_param +get_per_dpll_param: + adr r0, per_dpll_param + mov pc, lr diff --git a/arch/arm/cpu/arm_cortexa8/omap3/mem.c b/arch/arm/cpu/arm_cortexa8/omap3/mem.c new file mode 100644 index 0000000000..dfb7e4c2ad --- /dev/null +++ b/arch/arm/cpu/arm_cortexa8/omap3/mem.c @@ -0,0 +1,281 @@ +/* + * (C) Copyright 2008 + * Texas Instruments, + * + * Author : + * Manikandan Pillai + * + * Initial Code from: + * Richard Woodruff + * Syed Mohammed Khasim + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include + +/* + * Only One NAND allowed on board at a time. + * The GPMC CS Base for the same + */ +unsigned int boot_flash_base; +unsigned int boot_flash_off; +unsigned int boot_flash_sec; +unsigned int boot_flash_type; +volatile unsigned int boot_flash_env_addr; + +struct gpmc *gpmc_cfg; + +#if defined(CONFIG_CMD_NAND) +static const u32 gpmc_m_nand[GPMC_MAX_REG] = { + M_NAND_GPMC_CONFIG1, + M_NAND_GPMC_CONFIG2, + M_NAND_GPMC_CONFIG3, + M_NAND_GPMC_CONFIG4, + M_NAND_GPMC_CONFIG5, + M_NAND_GPMC_CONFIG6, 0 +}; + +#if defined(CONFIG_ENV_IS_IN_NAND) +#define GPMC_CS 0 +#else +#define GPMC_CS 1 +#endif + +#endif + +#if defined(CONFIG_CMD_ONENAND) +static const u32 gpmc_onenand[GPMC_MAX_REG] = { + ONENAND_GPMC_CONFIG1, + ONENAND_GPMC_CONFIG2, + ONENAND_GPMC_CONFIG3, + ONENAND_GPMC_CONFIG4, + ONENAND_GPMC_CONFIG5, + ONENAND_GPMC_CONFIG6, 0 +}; + +#if defined(CONFIG_ENV_IS_IN_ONENAND) +#define GPMC_CS 0 +#else +#define GPMC_CS 1 +#endif + +#endif + +static struct sdrc *sdrc_base = (struct sdrc *)OMAP34XX_SDRC_BASE; + +/************************************************************************** + * make_cs1_contiguous() - for es2 and above remap cs1 behind cs0 to allow + * command line mem=xyz use all memory with out discontinuous support + * compiled in. Could do it at the ATAG, but there really is two banks... + * Called as part of 2nd phase DDR init. + **************************************************************************/ +void make_cs1_contiguous(void) +{ + u32 size, a_add_low, a_add_high; + + size = get_sdr_cs_size(CS0); + size >>= 25; /* divide by 32 MiB to find size to offset CS1 */ + a_add_high = (size & 3) << 8; /* set up low field */ + a_add_low = (size & 0x3C) >> 2; /* set up high field */ + writel((a_add_high | a_add_low), &sdrc_base->cs_cfg); + +} + +/******************************************************** + * mem_ok() - test used to see if timings are correct + * for a part. Helps in guessing which part + * we are currently using. + *******************************************************/ +u32 mem_ok(u32 cs) +{ + u32 val1, val2, addr; + u32 pattern = 0x12345678; + + addr = OMAP34XX_SDRC_CS0 + get_sdr_cs_offset(cs); + + writel(0x0, addr + 0x400); /* clear pos A */ + writel(pattern, addr); /* pattern to pos B */ + writel(0x0, addr + 4); /* remove pattern off the bus */ + val1 = readl(addr + 0x400); /* get pos A value */ + val2 = readl(addr); /* get val2 */ + + if ((val1 != 0) || (val2 != pattern)) /* see if pos A val changed */ + return 0; + else + return 1; +} + +/******************************************************** + * sdrc_init() - init the sdrc chip selects CS0 and CS1 + * - early init routines, called from flash or + * SRAM. + *******************************************************/ +void sdrc_init(void) +{ + /* only init up first bank here */ + do_sdrc_init(CS0, EARLY_INIT); +} + +/************************************************************************* + * do_sdrc_init(): initialize the SDRAM for use. + * -code sets up SDRAM basic SDRC timings for CS0 + * -optimal settings can be placed here, or redone after i2c + * inspection of board info + * + * - code called once in C-Stack only context for CS0 and a possible 2nd + * time depending on memory configuration from stack+global context + **************************************************************************/ + +void do_sdrc_init(u32 cs, u32 early) +{ + struct sdrc_actim *sdrc_actim_base; + + if(cs) + sdrc_actim_base = (struct sdrc_actim *)SDRC_ACTIM_CTRL1_BASE; + else + sdrc_actim_base = (struct sdrc_actim *)SDRC_ACTIM_CTRL0_BASE; + + if (early) { + /* reset sdrc controller */ + writel(SOFTRESET, &sdrc_base->sysconfig); + wait_on_value(RESETDONE, RESETDONE, &sdrc_base->status, + 12000000); + writel(0, &sdrc_base->sysconfig); + + /* setup sdrc to ball mux */ + writel(SDRC_SHARING, &sdrc_base->sharing); + + /* Disable Power Down of CKE cuz of 1 CKE on combo part */ + writel(WAKEUPPROC | PWDNEN | SRFRONRESET | PAGEPOLICY_HIGH, + &sdrc_base->power); + + writel(ENADLL | DLLPHASE_90, &sdrc_base->dlla_ctrl); + sdelay(0x20000); + } + + writel(RASWIDTH_13BITS | CASWIDTH_10BITS | ADDRMUXLEGACY | + RAMSIZE_128 | BANKALLOCATION | B32NOT16 | B32NOT16 | + DEEPPD | DDR_SDRAM, &sdrc_base->cs[cs].mcfg); + writel(ARCV | ARE_ARCV_1, &sdrc_base->cs[cs].rfr_ctrl); + writel(V_ACTIMA_165, &sdrc_actim_base->ctrla); + writel(V_ACTIMB_165, &sdrc_actim_base->ctrlb); + + writel(CMD_NOP, &sdrc_base ->cs[cs].manual); + writel(CMD_PRECHARGE, &sdrc_base->cs[cs].manual); + writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual); + writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual); + + /* + * CAS latency 3, Write Burst = Read Burst, Serial Mode, + * Burst length = 4 + */ + writel(CASL3 | BURSTLENGTH4, &sdrc_base->cs[cs].mr); + + if (!mem_ok(cs)) + writel(0, &sdrc_base->cs[cs].mcfg); +} + +void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base, + u32 size) +{ + writel(0, &cs->config7); + sdelay(1000); + /* Delay for settling */ + writel(gpmc_config[0], &cs->config1); + writel(gpmc_config[1], &cs->config2); + writel(gpmc_config[2], &cs->config3); + writel(gpmc_config[3], &cs->config4); + writel(gpmc_config[4], &cs->config5); + writel(gpmc_config[5], &cs->config6); + /* Enable the config */ + writel((((size & 0xF) << 8) | ((base >> 24) & 0x3F) | + (1 << 6)), &cs->config7); + sdelay(2000); +} + +/***************************************************** + * gpmc_init(): init gpmc bus + * Init GPMC for x16, MuxMode (SDRAM in x32). + * This code can only be executed from SRAM or SDRAM. + *****************************************************/ +void gpmc_init(void) +{ + /* putting a blanket check on GPMC based on ZeBu for now */ + gpmc_cfg = (struct gpmc *)GPMC_BASE; +#if defined(CONFIG_CMD_NAND) || defined(CONFIG_CMD_ONENAND) + const u32 *gpmc_config = NULL; + u32 base = 0; + u32 size = 0; +#if defined(CONFIG_ENV_IS_IN_NAND) || defined(CONFIG_ENV_IS_IN_ONENAND) + u32 f_off = CONFIG_SYS_MONITOR_LEN; + u32 f_sec = 0; +#endif +#endif + u32 config = 0; + + /* global settings */ + writel(0, &gpmc_cfg->irqenable); /* isr's sources masked */ + writel(0, &gpmc_cfg->timeout_control);/* timeout disable */ + + config = readl(&gpmc_cfg->config); + config &= (~0xf00); + writel(config, &gpmc_cfg->config); + + /* + * Disable the GPMC0 config set by ROM code + * It conflicts with our MPDB (both at 0x08000000) + */ + writel(0, &gpmc_cfg->cs[0].config7); + sdelay(1000); + +#if defined(CONFIG_CMD_NAND) /* CS 0 */ + gpmc_config = gpmc_m_nand; + + base = PISMO1_NAND_BASE; + size = PISMO1_NAND_SIZE; + enable_gpmc_cs_config(gpmc_config, &gpmc_cfg->cs[0], base, size); +#if defined(CONFIG_ENV_IS_IN_NAND) + f_off = SMNAND_ENV_OFFSET; + f_sec = (128 << 10); /* 128 KiB */ + /* env setup */ + boot_flash_base = base; + boot_flash_off = f_off; + boot_flash_sec = f_sec; + boot_flash_env_addr = f_off; +#endif +#endif + +#if defined(CONFIG_CMD_ONENAND) + gpmc_config = gpmc_onenand; + base = PISMO1_ONEN_BASE; + size = PISMO1_ONEN_SIZE; + enable_gpmc_cs_config(gpmc_config, &gpmc_cfg->cs[0], base, size); +#if defined(CONFIG_ENV_IS_IN_ONENAND) + f_off = ONENAND_ENV_OFFSET; + f_sec = (128 << 10); /* 128 KiB */ + /* env setup */ + boot_flash_base = base; + boot_flash_off = f_off; + boot_flash_sec = f_sec; + boot_flash_env_addr = f_off; +#endif +#endif +} diff --git a/arch/arm/cpu/arm_cortexa8/omap3/reset.S b/arch/arm/cpu/arm_cortexa8/omap3/reset.S new file mode 100644 index 0000000000..a53c408195 --- /dev/null +++ b/arch/arm/cpu/arm_cortexa8/omap3/reset.S @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2009 Samsung Electronics. + * Minkyu Kang + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +.global reset_cpu +reset_cpu: + ldr r1, rstctl @ get addr for global reset + @ reg + mov r3, #0x2 @ full reset pll + mpu + str r3, [r1] @ force reset + mov r0, r0 +_loop_forever: + b _loop_forever +rstctl: + .word PRM_RSTCTRL diff --git a/arch/arm/cpu/arm_cortexa8/omap3/sys_info.c b/arch/arm/cpu/arm_cortexa8/omap3/sys_info.c new file mode 100644 index 0000000000..08fb32eaae --- /dev/null +++ b/arch/arm/cpu/arm_cortexa8/omap3/sys_info.c @@ -0,0 +1,299 @@ +/* + * (C) Copyright 2008 + * Texas Instruments, + * + * Author : + * Manikandan Pillai + * + * Derived from Beagle Board and 3430 SDP code by + * Richard Woodruff + * Syed Mohammed Khasim + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include /* get mem tables */ +#include +#include + +extern omap3_sysinfo sysinfo; +static struct sdrc *sdrc_base = (struct sdrc *)OMAP34XX_SDRC_BASE; +static struct ctrl *ctrl_base = (struct ctrl *)OMAP34XX_CTRL_BASE; +static char *rev_s[CPU_3XX_MAX_REV] = { + "1.0", + "2.0", + "2.1", + "3.0", + "3.1"}; + +/***************************************************************** + * dieid_num_r(void) - read and set die ID + *****************************************************************/ +void dieid_num_r(void) +{ + struct ctrl_id *id_base = (struct ctrl_id *)OMAP34XX_ID_L4_IO_BASE; + char *uid_s, die_id[34]; + u32 id[4]; + + memset(die_id, 0, sizeof(die_id)); + + uid_s = getenv("dieid#"); + + if (uid_s == NULL) { + id[3] = readl(&id_base->die_id_0); + id[2] = readl(&id_base->die_id_1); + id[1] = readl(&id_base->die_id_2); + id[0] = readl(&id_base->die_id_3); + sprintf(die_id, "%08x%08x%08x%08x", id[0], id[1], id[2], id[3]); + setenv("dieid#", die_id); + uid_s = die_id; + } + + printf("Die ID #%s\n", uid_s); +} + +/****************************************** + * get_cpu_type(void) - extract cpu info + ******************************************/ +u32 get_cpu_type(void) +{ + return readl(&ctrl_base->ctrl_omap_stat); +} + +/****************************************** + * get_cpu_rev(void) - extract version info + ******************************************/ +u32 get_cpu_rev(void) +{ + u32 cpuid = 0; + struct ctrl_id *id_base; + + /* + * On ES1.0 the IDCODE register is not exposed on L4 + * so using CPU ID to differentiate between ES1.0 and > ES1.0. + */ + __asm__ __volatile__("mrc p15, 0, %0, c0, c0, 0":"=r"(cpuid)); + if ((cpuid & 0xf) == 0x0) + return CPU_3XX_ES10; + else { + /* Decode the IDs on > ES1.0 */ + id_base = (struct ctrl_id *) OMAP34XX_ID_L4_IO_BASE; + + cpuid = (readl(&id_base->idcode) >> CPU_3XX_ID_SHIFT) & 0xf; + + /* Some early ES2.0 seem to report ID 0, fix this */ + if(cpuid == 0) + cpuid = CPU_3XX_ES20; + + return cpuid; + } +} + +/**************************************************** + * is_mem_sdr() - return 1 if mem type in use is SDR + ****************************************************/ +u32 is_mem_sdr(void) +{ + if (readl(&sdrc_base->cs[CS0].mr) == SDRC_MR_0_SDR) + return 1; + return 0; +} + +/*********************************************************************** + * get_cs0_size() - get size of chip select 0/1 + ************************************************************************/ +u32 get_sdr_cs_size(u32 cs) +{ + u32 size; + + /* get ram size field */ + size = readl(&sdrc_base->cs[cs].mcfg) >> 8; + size &= 0x3FF; /* remove unwanted bits */ + size <<= 21; /* multiply by 2 MiB to find size in MB */ + return size; +} + +/*********************************************************************** + * get_sdr_cs_offset() - get offset of cs from cs0 start + ************************************************************************/ +u32 get_sdr_cs_offset(u32 cs) +{ + u32 offset; + + if (!cs) + return 0; + + offset = readl(&sdrc_base->cs_cfg); + offset = (offset & 15) << 27 | (offset & 0x30) >> 17; + + return offset; +} + +/*************************************************************************** + * get_gpmc0_base() - Return current address hardware will be + * fetching from. The below effectively gives what is correct, its a bit + * mis-leading compared to the TRM. For the most general case the mask + * needs to be also taken into account this does work in practice. + * - for u-boot we currently map: + * -- 0 to nothing, + * -- 4 to flash + * -- 8 to enent + * -- c to wifi + ****************************************************************************/ +u32 get_gpmc0_base(void) +{ + u32 b; + + b = readl(&gpmc_cfg->cs[0].config7); + b &= 0x1F; /* keep base [5:0] */ + b = b << 24; /* ret 0x0b000000 */ + return b; +} + +/******************************************************************* + * get_gpmc0_width() - See if bus is in x8 or x16 (mainly for nand) + *******************************************************************/ +u32 get_gpmc0_width(void) +{ + return WIDTH_16BIT; +} + +/************************************************************************* + * get_board_rev() - setup to pass kernel board revision information + * returns:(bit[0-3] sub version, higher bit[7-4] is higher version) + *************************************************************************/ +u32 get_board_rev(void) +{ + return 0x20; +} + +/******************************************************** + * get_base(); get upper addr of current execution + *******************************************************/ +u32 get_base(void) +{ + u32 val; + + __asm__ __volatile__("mov %0, pc \n":"=r"(val)::"memory"); + val &= 0xF0000000; + val >>= 28; + return val; +} + +/******************************************************** + * is_running_in_flash() - tell if currently running in + * FLASH. + *******************************************************/ +u32 is_running_in_flash(void) +{ + if (get_base() < 4) + return 1; /* in FLASH */ + + return 0; /* running in SRAM or SDRAM */ +} + +/******************************************************** + * is_running_in_sram() - tell if currently running in + * SRAM. + *******************************************************/ +u32 is_running_in_sram(void) +{ + if (get_base() == 4) + return 1; /* in SRAM */ + + return 0; /* running in FLASH or SDRAM */ +} + +/******************************************************** + * is_running_in_sdram() - tell if currently running in + * SDRAM. + *******************************************************/ +u32 is_running_in_sdram(void) +{ + if (get_base() > 4) + return 1; /* in SDRAM */ + + return 0; /* running in SRAM or FLASH */ +} + +/*************************************************************** + * get_boot_type() - Is this an XIP type device or a stream one + * bits 4-0 specify type. Bit 5 says mem/perif + ***************************************************************/ +u32 get_boot_type(void) +{ + return (readl(&ctrl_base->status) & SYSBOOT_MASK); +} + +/************************************************************* + * get_device_type(): tell if GP/HS/EMU/TST + *************************************************************/ +u32 get_device_type(void) +{ + return ((readl(&ctrl_base->status) & (DEVICE_MASK)) >> 8); +} + +#ifdef CONFIG_DISPLAY_CPUINFO +/** + * Print CPU information + */ +int print_cpuinfo (void) +{ + char *cpu_s, *sec_s; + + switch (get_cpu_type()) { + case OMAP3503: + cpu_s = "3503"; + break; + case OMAP3515: + cpu_s = "3515"; + break; + case OMAP3525: + cpu_s = "3525"; + break; + case OMAP3530: + cpu_s = "3530"; + break; + default: + cpu_s = "35XX"; + break; + } + + switch (get_device_type()) { + case TST_DEVICE: + sec_s = "TST"; + break; + case EMU_DEVICE: + sec_s = "EMU"; + break; + case HS_DEVICE: + sec_s = "HS"; + break; + case GP_DEVICE: + sec_s = "GP"; + break; + default: + sec_s = "?"; + } + + printf("OMAP%s-%s ES%s, CPU-OPP2 L3-165MHz\n", + cpu_s, sec_s, rev_s[get_cpu_rev()]); + + return 0; +} +#endif /* CONFIG_DISPLAY_CPUINFO */ diff --git a/arch/arm/cpu/arm_cortexa8/omap3/syslib.c b/arch/arm/cpu/arm_cortexa8/omap3/syslib.c new file mode 100644 index 0000000000..9ced495c8d --- /dev/null +++ b/arch/arm/cpu/arm_cortexa8/omap3/syslib.c @@ -0,0 +1,72 @@ +/* + * (C) Copyright 2008 + * Texas Instruments, + * + * Richard Woodruff + * Syed Mohammed Khasim + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include + +/************************************************************ + * sdelay() - simple spin loop. Will be constant time as + * its generally used in bypass conditions only. This + * is necessary until timers are accessible. + * + * not inline to increase chances its in cache when called + *************************************************************/ +void sdelay(unsigned long loops) +{ + __asm__ volatile ("1:\n" "subs %0, %1, #1\n" + "bne 1b":"=r" (loops):"0"(loops)); +} + +/***************************************************************** + * sr32 - clear & set a value in a bit range for a 32 bit address + *****************************************************************/ +void sr32(void *addr, u32 start_bit, u32 num_bits, u32 value) +{ + u32 tmp, msk = 0; + msk = 1 << num_bits; + --msk; + tmp = readl((u32)addr) & ~(msk << start_bit); + tmp |= value << start_bit; + writel(tmp, (u32)addr); +} + +/********************************************************************* + * wait_on_value() - common routine to allow waiting for changes in + * volatile regs. + *********************************************************************/ +u32 wait_on_value(u32 read_bit_mask, u32 match_value, void *read_addr, + u32 bound) +{ + u32 i = 0, val; + do { + ++i; + val = readl((u32)read_addr) & read_bit_mask; + if (val == match_value) + return 1; + if (i == bound) + return 0; + } while (1); +} diff --git a/arch/arm/cpu/arm_cortexa8/omap3/timer.c b/arch/arm/cpu/arm_cortexa8/omap3/timer.c new file mode 100644 index 0000000000..401bfe6d09 --- /dev/null +++ b/arch/arm/cpu/arm_cortexa8/omap3/timer.c @@ -0,0 +1,138 @@ +/* + * (C) Copyright 2008 + * Texas Instruments + * + * Richard Woodruff + * Syed Moahmmed Khasim + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * Alex Zuepke + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +static ulong timestamp; +static ulong lastinc; +static struct gptimer *timer_base = (struct gptimer *)CONFIG_SYS_TIMERBASE; + +/* + * Nothing really to do with interrupts, just starts up a counter. + * We run the counter with 13MHz, divided by 8, resulting in timer + * frequency of 1.625MHz. With 32bit counter register, counter + * overflows in ~44min + */ + +/* 13MHz / 8 = 1.625MHz */ +#define TIMER_CLOCK (V_SCLK / (2 << CONFIG_SYS_PTV)) +#define TIMER_LOAD_VAL 0xffffffff + +int timer_init(void) +{ + /* start the counter ticking up, reload value on overflow */ + writel(TIMER_LOAD_VAL, &timer_base->tldr); + /* enable timer */ + writel((CONFIG_SYS_PTV << 2) | TCLR_PRE | TCLR_AR | TCLR_ST, + &timer_base->tclr); + + reset_timer_masked(); /* init the timestamp and lastinc value */ + + return 0; +} + +/* + * timer without interrupts + */ +void reset_timer(void) +{ + reset_timer_masked(); +} + +ulong get_timer(ulong base) +{ + return get_timer_masked() - base; +} + +void set_timer(ulong t) +{ + timestamp = t; +} + +/* delay x useconds */ +void __udelay(unsigned long usec) +{ + long tmo = usec * (TIMER_CLOCK / 1000) / 1000; + unsigned long now, last = readl(&timer_base->tcrr); + + while (tmo > 0) { + now = readl(&timer_base->tcrr); + if (last > now) /* count up timer overflow */ + tmo -= TIMER_LOAD_VAL - last + now; + else + tmo -= now - last; + last = now; + } +} + +void reset_timer_masked(void) +{ + /* reset time, capture current incrementer value time */ + lastinc = readl(&timer_base->tcrr) / (TIMER_CLOCK / CONFIG_SYS_HZ); + timestamp = 0; /* start "advancing" time stamp from 0 */ +} + +ulong get_timer_masked(void) +{ + /* current tick value */ + ulong now = readl(&timer_base->tcrr) / (TIMER_CLOCK / CONFIG_SYS_HZ); + + if (now >= lastinc) /* normal mode (non roll) */ + /* move stamp fordward with absoulte diff ticks */ + timestamp += (now - lastinc); + else /* we have rollover of incrementer */ + timestamp += ((TIMER_LOAD_VAL / (TIMER_CLOCK / CONFIG_SYS_HZ)) + - lastinc) + now; + lastinc = now; + return timestamp; +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + return CONFIG_SYS_HZ; +} diff --git a/arch/arm/cpu/arm_cortexa8/s5pc1xx/Makefile b/arch/arm/cpu/arm_cortexa8/s5pc1xx/Makefile new file mode 100644 index 0000000000..01c93feda8 --- /dev/null +++ b/arch/arm/cpu/arm_cortexa8/s5pc1xx/Makefile @@ -0,0 +1,55 @@ +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2008 +# Guennadi Liakhovetki, DENX Software Engineering, +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +SOBJS = cache.o +SOBJS += reset.o + +COBJS += clock.o +COBJS += cpu_info.o +COBJS += gpio.o +COBJS += sromc.o +COBJS += timer.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm_cortexa8/s5pc1xx/cache.S b/arch/arm/cpu/arm_cortexa8/s5pc1xx/cache.S new file mode 100644 index 0000000000..906118d820 --- /dev/null +++ b/arch/arm/cpu/arm_cortexa8/s5pc1xx/cache.S @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2009 Samsung Electronics + * Minkyu Kang + * + * based on arch/arm/cpu/arm_cortexa8/omap3/cache.S + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +.align 5 +.global invalidate_dcache +.global l2_cache_enable +.global l2_cache_disable + +/* + * invalidate_dcache() + * Invalidate the whole D-cache. + * + * Corrupted registers: r0-r5, r7, r9-r11 + */ +invalidate_dcache: + stmfd r13!, {r0 - r5, r7, r9 - r12, r14} + + cmp r0, #0xC100 @ check if the cpu is s5pc100 + + beq finished_inval @ s5pc100 doesn't need this + @ routine + mrc p15, 1, r0, c0, c0, 1 @ read clidr + ands r3, r0, #0x7000000 @ extract loc from clidr + mov r3, r3, lsr #23 @ left align loc bit field + beq finished_inval @ if loc is 0, then no need to + @ clean + mov r10, #0 @ start clean at cache level 0 +inval_loop1: + add r2, r10, r10, lsr #1 @ work out 3x current cache + @ level + mov r1, r0, lsr r2 @ extract cache type bits from + @ clidr + and r1, r1, #7 @ mask of the bits for current + @ cache only + cmp r1, #2 @ see what cache we have at + @ this level + blt skip_inval @ skip if no cache, or just + @ i-cache + mcr p15, 2, r10, c0, c0, 0 @ select current cache level + @ in cssr + mov r2, #0 @ operand for mcr SBZ + mcr p15, 0, r2, c7, c5, 4 @ flush prefetch buffer to + @ sych the new cssr&csidr, + @ with armv7 this is 'isb', + @ but we compile with armv5 + mrc p15, 1, r1, c0, c0, 0 @ read the new csidr + and r2, r1, #7 @ extract the length of the + @ cache lines + add r2, r2, #4 @ add 4 (line length offset) + ldr r4, =0x3ff + ands r4, r4, r1, lsr #3 @ find maximum number on the + @ way size + clz r5, r4 @ find bit position of way + @ size increment + ldr r7, =0x7fff + ands r7, r7, r1, lsr #13 @ extract max number of the + @ index size +inval_loop2: + mov r9, r4 @ create working copy of max + @ way size +inval_loop3: + orr r11, r10, r9, lsl r5 @ factor way and cache number + @ into r11 + orr r11, r11, r7, lsl r2 @ factor index number into r11 + mcr p15, 0, r11, c7, c6, 2 @ invalidate by set/way + subs r9, r9, #1 @ decrement the way + bge inval_loop3 + subs r7, r7, #1 @ decrement the index + bge inval_loop2 +skip_inval: + add r10, r10, #2 @ increment cache number + cmp r3, r10 + bgt inval_loop1 +finished_inval: + mov r10, #0 @ swith back to cache level 0 + mcr p15, 2, r10, c0, c0, 0 @ select current cache level + @ in cssr + mcr p15, 0, r10, c7, c5, 4 @ flush prefetch buffer, + @ with armv7 this is 'isb', + @ but we compile with armv5 + + ldmfd r13!, {r0 - r5, r7, r9 - r12, pc} + +l2_cache_enable: + push {r0, r1, r2, lr} + mrc 15, 0, r3, cr1, cr0, 1 + orr r3, r3, #2 + mcr 15, 0, r3, cr1, cr0, 1 + pop {r1, r2, r3, pc} + +l2_cache_disable: + push {r0, r1, r2, lr} + mrc 15, 0, r3, cr1, cr0, 1 + bic r3, r3, #2 + mcr 15, 0, r3, cr1, cr0, 1 + pop {r1, r2, r3, pc} diff --git a/arch/arm/cpu/arm_cortexa8/s5pc1xx/clock.c b/arch/arm/cpu/arm_cortexa8/s5pc1xx/clock.c new file mode 100644 index 0000000000..19619f92cd --- /dev/null +++ b/arch/arm/cpu/arm_cortexa8/s5pc1xx/clock.c @@ -0,0 +1,303 @@ +/* + * Copyright (C) 2009 Samsung Electronics + * Minkyu Kang + * Heungjun Kim + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include + +#define CLK_M 0 +#define CLK_D 1 +#define CLK_P 2 + +#ifndef CONFIG_SYS_CLK_FREQ_C100 +#define CONFIG_SYS_CLK_FREQ_C100 12000000 +#endif +#ifndef CONFIG_SYS_CLK_FREQ_C110 +#define CONFIG_SYS_CLK_FREQ_C110 24000000 +#endif + +unsigned long (*get_pclk)(void); +unsigned long (*get_arm_clk)(void); +unsigned long (*get_pll_clk)(int); + +/* s5pc110: return pll clock frequency */ +static unsigned long s5pc100_get_pll_clk(int pllreg) +{ + struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE; + unsigned long r, m, p, s, mask, fout; + unsigned int freq; + + switch (pllreg) { + case APLL: + r = readl(&clk->apll_con); + break; + case MPLL: + r = readl(&clk->mpll_con); + break; + case EPLL: + r = readl(&clk->epll_con); + break; + case HPLL: + r = readl(&clk->hpll_con); + break; + default: + printf("Unsupported PLL (%d)\n", pllreg); + return 0; + } + + /* + * APLL_CON: MIDV [25:16] + * MPLL_CON: MIDV [23:16] + * EPLL_CON: MIDV [23:16] + * HPLL_CON: MIDV [23:16] + */ + if (pllreg == APLL) + mask = 0x3ff; + else + mask = 0x0ff; + + m = (r >> 16) & mask; + + /* PDIV [13:8] */ + p = (r >> 8) & 0x3f; + /* SDIV [2:0] */ + s = r & 0x7; + + /* FOUT = MDIV * FIN / (PDIV * 2^SDIV) */ + freq = CONFIG_SYS_CLK_FREQ_C100; + fout = m * (freq / (p * (1 << s))); + + return fout; +} + +/* s5pc100: return pll clock frequency */ +static unsigned long s5pc110_get_pll_clk(int pllreg) +{ + struct s5pc110_clock *clk = (struct s5pc110_clock *)S5PC1XX_CLOCK_BASE; + unsigned long r, m, p, s, mask, fout; + unsigned int freq; + + switch (pllreg) { + case APLL: + r = readl(&clk->apll_con); + break; + case MPLL: + r = readl(&clk->mpll_con); + break; + case EPLL: + r = readl(&clk->epll_con); + break; + case VPLL: + r = readl(&clk->vpll_con); + break; + default: + printf("Unsupported PLL (%d)\n", pllreg); + return 0; + } + + /* + * APLL_CON: MIDV [25:16] + * MPLL_CON: MIDV [25:16] + * EPLL_CON: MIDV [24:16] + * VPLL_CON: MIDV [24:16] + */ + if (pllreg == APLL || pllreg == MPLL) + mask = 0x3ff; + else + mask = 0x1ff; + + m = (r >> 16) & mask; + + /* PDIV [13:8] */ + p = (r >> 8) & 0x3f; + /* SDIV [2:0] */ + s = r & 0x7; + + freq = CONFIG_SYS_CLK_FREQ_C110; + if (pllreg == APLL) { + if (s < 1) + s = 1; + /* FOUT = MDIV * FIN / (PDIV * 2^(SDIV - 1)) */ + fout = m * (freq / (p * (1 << (s - 1)))); + } else + /* FOUT = MDIV * FIN / (PDIV * 2^SDIV) */ + fout = m * (freq / (p * (1 << s))); + + return fout; +} + +/* s5pc110: return ARM clock frequency */ +static unsigned long s5pc110_get_arm_clk(void) +{ + struct s5pc110_clock *clk = (struct s5pc110_clock *)S5PC1XX_CLOCK_BASE; + unsigned long div; + unsigned long dout_apll, armclk; + unsigned int apll_ratio; + + div = readl(&clk->div0); + + /* APLL_RATIO: [2:0] */ + apll_ratio = div & 0x7; + + dout_apll = get_pll_clk(APLL) / (apll_ratio + 1); + armclk = dout_apll; + + return armclk; +} + +/* s5pc100: return ARM clock frequency */ +static unsigned long s5pc100_get_arm_clk(void) +{ + struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE; + unsigned long div; + unsigned long dout_apll, armclk; + unsigned int apll_ratio, arm_ratio; + + div = readl(&clk->div0); + + /* ARM_RATIO: [6:4] */ + arm_ratio = (div >> 4) & 0x7; + /* APLL_RATIO: [0] */ + apll_ratio = div & 0x1; + + dout_apll = get_pll_clk(APLL) / (apll_ratio + 1); + armclk = dout_apll / (arm_ratio + 1); + + return armclk; +} + +/* s5pc100: return HCLKD0 frequency */ +static unsigned long get_hclk(void) +{ + struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE; + unsigned long hclkd0; + uint div, d0_bus_ratio; + + div = readl(&clk->div0); + /* D0_BUS_RATIO: [10:8] */ + d0_bus_ratio = (div >> 8) & 0x7; + + hclkd0 = get_arm_clk() / (d0_bus_ratio + 1); + + return hclkd0; +} + +/* s5pc100: return PCLKD1 frequency */ +static unsigned long get_pclkd1(void) +{ + struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE; + unsigned long d1_bus, pclkd1; + uint div, d1_bus_ratio, pclkd1_ratio; + + div = readl(&clk->div0); + /* D1_BUS_RATIO: [14:12] */ + d1_bus_ratio = (div >> 12) & 0x7; + /* PCLKD1_RATIO: [18:16] */ + pclkd1_ratio = (div >> 16) & 0x7; + + /* ASYNC Mode */ + d1_bus = get_pll_clk(MPLL) / (d1_bus_ratio + 1); + pclkd1 = d1_bus / (pclkd1_ratio + 1); + + return pclkd1; +} + +/* s5pc110: return HCLKs frequency */ +static unsigned long get_hclk_sys(int dom) +{ + struct s5pc110_clock *clk = (struct s5pc110_clock *)S5PC1XX_CLOCK_BASE; + unsigned long hclk; + unsigned int div; + unsigned int offset; + unsigned int hclk_sys_ratio; + + if (dom == CLK_M) + return get_hclk(); + + div = readl(&clk->div0); + + /* + * HCLK_MSYS_RATIO: [10:8] + * HCLK_DSYS_RATIO: [19:16] + * HCLK_PSYS_RATIO: [27:24] + */ + offset = 8 + (dom << 0x3); + + hclk_sys_ratio = (div >> offset) & 0xf; + + hclk = get_pll_clk(MPLL) / (hclk_sys_ratio + 1); + + return hclk; +} + +/* s5pc110: return PCLKs frequency */ +static unsigned long get_pclk_sys(int dom) +{ + struct s5pc110_clock *clk = (struct s5pc110_clock *)S5PC1XX_CLOCK_BASE; + unsigned long pclk; + unsigned int div; + unsigned int offset; + unsigned int pclk_sys_ratio; + + div = readl(&clk->div0); + + /* + * PCLK_MSYS_RATIO: [14:12] + * PCLK_DSYS_RATIO: [22:20] + * PCLK_PSYS_RATIO: [30:28] + */ + offset = 12 + (dom << 0x3); + + pclk_sys_ratio = (div >> offset) & 0x7; + + pclk = get_hclk_sys(dom) / (pclk_sys_ratio + 1); + + return pclk; +} + +/* s5pc110: return peripheral clock frequency */ +static unsigned long s5pc110_get_pclk(void) +{ + return get_pclk_sys(CLK_P); +} + +/* s5pc100: return peripheral clock frequency */ +static unsigned long s5pc100_get_pclk(void) +{ + return get_pclkd1(); +} + +void s5pc1xx_clock_init(void) +{ + if (cpu_is_s5pc110()) { + get_pll_clk = s5pc110_get_pll_clk; + get_arm_clk = s5pc110_get_arm_clk; + get_pclk = s5pc110_get_pclk; + } else { + get_pll_clk = s5pc100_get_pll_clk; + get_arm_clk = s5pc100_get_arm_clk; + get_pclk = s5pc100_get_pclk; + } +} diff --git a/arch/arm/cpu/arm_cortexa8/s5pc1xx/cpu_info.c b/arch/arm/cpu/arm_cortexa8/s5pc1xx/cpu_info.c new file mode 100644 index 0000000000..f16c0ff130 --- /dev/null +++ b/arch/arm/cpu/arm_cortexa8/s5pc1xx/cpu_info.c @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2009 Samsung Electronics + * Minkyu Kang + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include +#include +#include + +/* Default is s5pc100 */ +unsigned int s5pc1xx_cpu_id = 0xC100; + +#ifdef CONFIG_ARCH_CPU_INIT +int arch_cpu_init(void) +{ + s5pc1xx_cpu_id = readl(S5PC1XX_PRO_ID); + s5pc1xx_cpu_id = 0xC000 | ((s5pc1xx_cpu_id & 0x00FFF000) >> 12); + + s5pc1xx_clock_init(); + + return 0; +} +#endif + +u32 get_device_type(void) +{ + return s5pc1xx_cpu_id; +} + +#ifdef CONFIG_DISPLAY_CPUINFO +int print_cpuinfo(void) +{ + char buf[32]; + + printf("CPU:\tS5P%X@%sMHz\n", + s5pc1xx_cpu_id, strmhz(buf, get_arm_clk())); + + return 0; +} +#endif diff --git a/arch/arm/cpu/arm_cortexa8/s5pc1xx/gpio.c b/arch/arm/cpu/arm_cortexa8/s5pc1xx/gpio.c new file mode 100644 index 0000000000..a97244bf30 --- /dev/null +++ b/arch/arm/cpu/arm_cortexa8/s5pc1xx/gpio.c @@ -0,0 +1,143 @@ +/* + * (C) Copyright 2009 Samsung Electronics + * Minkyu Kang + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +#define CON_MASK(x) (0xf << ((x) << 2)) +#define CON_SFR(x, v) ((v) << ((x) << 2)) + +#define DAT_MASK(x) (0x1 << (x)) +#define DAT_SET(x) (0x1 << (x)) + +#define PULL_MASK(x) (0x3 << ((x) << 1)) +#define PULL_MODE(x, v) ((v) << ((x) << 1)) + +#define DRV_MASK(x) (0x3 << ((x) << 1)) +#define DRV_SET(x, m) ((m) << ((x) << 1)) +#define RATE_MASK(x) (0x1 << (x + 16)) +#define RATE_SET(x) (0x1 << (x + 16)) + +void gpio_cfg_pin(struct s5pc1xx_gpio_bank *bank, int gpio, int cfg) +{ + unsigned int value; + + value = readl(&bank->con); + value &= ~CON_MASK(gpio); + value |= CON_SFR(gpio, cfg); + writel(value, &bank->con); +} + +void gpio_direction_output(struct s5pc1xx_gpio_bank *bank, int gpio, int en) +{ + unsigned int value; + + gpio_cfg_pin(bank, gpio, GPIO_OUTPUT); + + value = readl(&bank->dat); + value &= ~DAT_MASK(gpio); + if (en) + value |= DAT_SET(gpio); + writel(value, &bank->dat); +} + +void gpio_direction_input(struct s5pc1xx_gpio_bank *bank, int gpio) +{ + gpio_cfg_pin(bank, gpio, GPIO_INPUT); +} + +void gpio_set_value(struct s5pc1xx_gpio_bank *bank, int gpio, int en) +{ + unsigned int value; + + value = readl(&bank->dat); + value &= ~DAT_MASK(gpio); + if (en) + value |= DAT_SET(gpio); + writel(value, &bank->dat); +} + +unsigned int gpio_get_value(struct s5pc1xx_gpio_bank *bank, int gpio) +{ + unsigned int value; + + value = readl(&bank->dat); + return !!(value & DAT_MASK(gpio)); +} + +void gpio_set_pull(struct s5pc1xx_gpio_bank *bank, int gpio, int mode) +{ + unsigned int value; + + value = readl(&bank->pull); + value &= ~PULL_MASK(gpio); + + switch (mode) { + case GPIO_PULL_DOWN: + case GPIO_PULL_UP: + value |= PULL_MODE(gpio, mode); + break; + default: + return; + } + + writel(value, &bank->pull); +} + +void gpio_set_drv(struct s5pc1xx_gpio_bank *bank, int gpio, int mode) +{ + unsigned int value; + + value = readl(&bank->drv); + value &= ~DRV_MASK(gpio); + + switch (mode) { + case GPIO_DRV_1X: + case GPIO_DRV_2X: + case GPIO_DRV_3X: + case GPIO_DRV_4X: + value |= DRV_SET(gpio, mode); + break; + default: + return; + } + + writel(value, &bank->drv); +} + +void gpio_set_rate(struct s5pc1xx_gpio_bank *bank, int gpio, int mode) +{ + unsigned int value; + + value = readl(&bank->drv); + value &= ~RATE_MASK(gpio); + + switch (mode) { + case GPIO_DRV_FAST: + case GPIO_DRV_SLOW: + value |= RATE_SET(gpio); + break; + default: + return; + } + + writel(value, &bank->drv); +} diff --git a/arch/arm/cpu/arm_cortexa8/s5pc1xx/reset.S b/arch/arm/cpu/arm_cortexa8/s5pc1xx/reset.S new file mode 100644 index 0000000000..7f6ff9c35f --- /dev/null +++ b/arch/arm/cpu/arm_cortexa8/s5pc1xx/reset.S @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2009 Samsung Electronics. + * Minkyu Kang + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +#define S5PC100_SWRESET 0xE0200000 +#define S5PC110_SWRESET 0xE0102000 + +.globl reset_cpu +reset_cpu: + ldr r1, =S5PC1XX_PRO_ID + ldr r2, [r1] + ldr r4, =0x00010000 + and r4, r2, r4 + cmp r4, #0 + bne 110f + /* S5PC100 */ + ldr r1, =S5PC100_SWRESET + ldr r2, =0xC100 + b 200f +110: /* S5PC110 */ + ldr r1, =S5PC110_SWRESET + mov r2, #1 +200: + str r2, [r1] +_loop_forever: + b _loop_forever diff --git a/arch/arm/cpu/arm_cortexa8/s5pc1xx/sromc.c b/arch/arm/cpu/arm_cortexa8/s5pc1xx/sromc.c new file mode 100644 index 0000000000..380be81be5 --- /dev/null +++ b/arch/arm/cpu/arm_cortexa8/s5pc1xx/sromc.c @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2010 Samsung Electronics + * Naveen Krishna Ch + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +/* + * s5pc1xx_config_sromc() - select the proper SROMC Bank and configure the + * band width control and bank control registers + * srom_bank - SROM Bank 0 to 5 + * smc_bw_conf - SMC Band witdh reg configuration value + * smc_bc_conf - SMC Bank Control reg configuration value + */ +void s5pc1xx_config_sromc(u32 srom_bank, u32 smc_bw_conf, u32 smc_bc_conf) +{ + u32 tmp; + struct s5pc1xx_smc *srom; + + if (cpu_is_s5pc100()) + srom = (struct s5pc1xx_smc *)S5PC100_SROMC_BASE; + else + srom = (struct s5pc1xx_smc *)S5PC110_SROMC_BASE; + + /* Configure SMC_BW register to handle proper SROMC bank */ + tmp = srom->bw; + tmp &= ~(0xF << (srom_bank * 4)); + tmp |= smc_bw_conf; + srom->bw = tmp; + + /* Configure SMC_BC register */ + srom->bc[srom_bank] = smc_bc_conf; +} diff --git a/arch/arm/cpu/arm_cortexa8/s5pc1xx/timer.c b/arch/arm/cpu/arm_cortexa8/s5pc1xx/timer.c new file mode 100644 index 0000000000..c5df5c5ab5 --- /dev/null +++ b/arch/arm/cpu/arm_cortexa8/s5pc1xx/timer.c @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2009 Samsung Electronics + * Heungjun Kim + * Inki Dae + * Minkyu Kang + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include + +#define PRESCALER_1 (16 - 1) /* prescaler of timer 2, 3, 4 */ +#define MUX_DIV_2 1 /* 1/2 period */ +#define MUX_DIV_4 2 /* 1/4 period */ +#define MUX_DIV_8 3 /* 1/8 period */ +#define MUX_DIV_16 4 /* 1/16 period */ +#define MUX4_DIV_SHIFT 16 + +#define TCON_TIMER4_SHIFT 20 + +static unsigned long count_value; + +/* Internal tick units */ +static unsigned long long timestamp; /* Monotonic incrementing timer */ +static unsigned long lastdec; /* Last decremneter snapshot */ + +/* macro to read the 16 bit timer */ +static inline struct s5pc1xx_timer *s5pc1xx_get_base_timer(void) +{ + if (cpu_is_s5pc110()) + return (struct s5pc1xx_timer *)S5PC110_TIMER_BASE; + else + return (struct s5pc1xx_timer *)S5PC100_TIMER_BASE; +} + +int timer_init(void) +{ + struct s5pc1xx_timer *const timer = s5pc1xx_get_base_timer(); + u32 val; + + /* + * @ PWM Timer 4 + * Timer Freq(HZ) = + * PCLK / { (prescaler_value + 1) * (divider_value) } + */ + + /* set prescaler : 16 */ + /* set divider : 2 */ + writel((PRESCALER_1 & 0xff) << 8, &timer->tcfg0); + writel((MUX_DIV_2 & 0xf) << MUX4_DIV_SHIFT, &timer->tcfg1); + + if (count_value == 0) { + /* reset initial value */ + /* count_value = 2085937.5(HZ) (per 1 sec)*/ + count_value = get_pclk() / ((PRESCALER_1 + 1) * + (MUX_DIV_2 + 1)); + + /* count_value / 100 = 20859.375(HZ) (per 10 msec) */ + count_value = count_value / 100; + } + + /* set count value */ + writel(count_value, &timer->tcntb4); + lastdec = count_value; + + val = (readl(&timer->tcon) & ~(0x07 << TCON_TIMER4_SHIFT)) | + S5PC1XX_TCON4_AUTO_RELOAD; + + /* auto reload & manual update */ + writel(val | S5PC1XX_TCON4_UPDATE, &timer->tcon); + + /* start PWM timer 4 */ + writel(val | S5PC1XX_TCON4_START, &timer->tcon); + + timestamp = 0; + + return 0; +} + +/* + * timer without interrupts + */ +void reset_timer(void) +{ + reset_timer_masked(); +} + +unsigned long get_timer(unsigned long base) +{ + return get_timer_masked() - base; +} + +void set_timer(unsigned long t) +{ + timestamp = t; +} + +/* delay x useconds */ +void __udelay(unsigned long usec) +{ + unsigned long tmo, tmp; + + if (usec >= 1000) { + /* + * if "big" number, spread normalization + * to seconds + * 1. start to normalize for usec to ticks per sec + * 2. find number of "ticks" to wait to achieve target + * 3. finish normalize. + */ + tmo = usec / 1000; + tmo *= (CONFIG_SYS_HZ * count_value / 10); + tmo /= 1000; + } else { + /* else small number, don't kill it prior to HZ multiply */ + tmo = usec * CONFIG_SYS_HZ * count_value / 10; + tmo /= (1000 * 1000); + } + + /* get current timestamp */ + tmp = get_timer(0); + + /* if setting this fordward will roll time stamp */ + /* reset "advancing" timestamp to 0, set lastdec value */ + /* else, set advancing stamp wake up time */ + if ((tmo + tmp + 1) < tmp) + reset_timer_masked(); + else + tmo += tmp; + + /* loop till event */ + while (get_timer_masked() < tmo) + ; /* nop */ +} + +void reset_timer_masked(void) +{ + struct s5pc1xx_timer *const timer = s5pc1xx_get_base_timer(); + + /* reset time */ + lastdec = readl(&timer->tcnto4); + timestamp = 0; +} + +unsigned long get_timer_masked(void) +{ + struct s5pc1xx_timer *const timer = s5pc1xx_get_base_timer(); + unsigned long now = readl(&timer->tcnto4); + + if (lastdec >= now) + timestamp += lastdec - now; + else + timestamp += lastdec + count_value - now; + + lastdec = now; + + return timestamp; +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +unsigned long get_tbclk(void) +{ + return CONFIG_SYS_HZ; +} diff --git a/arch/arm/cpu/arm_cortexa8/start.S b/arch/arm/cpu/arm_cortexa8/start.S new file mode 100644 index 0000000000..29dae2f282 --- /dev/null +++ b/arch/arm/cpu/arm_cortexa8/start.S @@ -0,0 +1,416 @@ +/* + * armboot - Startup Code for OMAP3530/ARM Cortex CPU-core + * + * Copyright (c) 2004 Texas Instruments + * + * Copyright (c) 2001 Marius Gröger + * Copyright (c) 2002 Alex Züpke + * Copyright (c) 2002 Gary Jennejohn + * Copyright (c) 2003 Richard Woodruff + * Copyright (c) 2003 Kshitij + * Copyright (c) 2006-2008 Syed Mohammed Khasim + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +.globl _start +_start: b 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 + +_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 +_pad: .word 0x12345678 /* now 16*4=64 */ +.global _end_vect +_end_vect: + + .balignl 16,0xdeadbeef +/************************************************************************* + * + * Startup Code (reset vector) + * + * do important init only if we don't start from memory! + * setup Memory and board specific bits prior to relocation. + * relocate armboot to ram + * setup stack + * + *************************************************************************/ + +_TEXT_BASE: + .word TEXT_BASE + +.globl _armboot_start +_armboot_start: + .word _start + +/* + * These are defined in the board-specific linker script. + */ +.globl _bss_start +_bss_start: + .word __bss_start + +.globl _bss_end +_bss_end: + .word _end + +#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 + +/* + * the actual reset code + */ + +reset: + /* + * set the cpu to SVC32 mode + */ + mrs r0, cpsr + bic r0, r0, #0x1f + orr r0, r0, #0xd3 + msr cpsr,r0 + +#if (CONFIG_OMAP34XX) + /* Copy vectors to mask ROM indirect addr */ + adr r0, _start @ r0 <- current position of code + add r0, r0, #4 @ skip reset vector + mov r2, #64 @ r2 <- size to copy + add r2, r0, r2 @ r2 <- source end address + mov r1, #SRAM_OFFSET0 @ build vect addr + mov r3, #SRAM_OFFSET1 + add r1, r1, r3 + mov r3, #SRAM_OFFSET2 + add r1, r1, r3 +next: + ldmia r0!, {r3 - r10} @ copy from source address [r0] + stmia r1!, {r3 - r10} @ copy to target address [r1] + cmp r0, r2 @ until source end address [r2] + bne next @ loop until equal */ +#if !defined(CONFIG_SYS_NAND_BOOT) && !defined(CONFIG_SYS_ONENAND_BOOT) + /* No need to copy/exec the clock code - DPLL adjust already done + * in NAND/oneNAND Boot. + */ + bl cpy_clk_code @ put dpll adjust code behind vectors +#endif /* NAND Boot */ +#endif + /* the mask ROM code should have PLL and others stable */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl cpu_init_crit +#endif + +#ifndef CONFIG_SKIP_RELOCATE_UBOOT +relocate: @ relocate U-Boot to RAM + adr r0, _start @ r0 <- current position of code + ldr r1, _TEXT_BASE @ test if we run from flash or RAM + cmp r0, r1 @ don't reloc during debug + beq stack_setup + + ldr r2, _armboot_start + ldr r3, _bss_start + sub r2, r3, r2 @ r2 <- size of armboot + add r2, r0, r2 @ r2 <- source end address + +copy_loop: @ copy 32 bytes at a time + ldmia r0!, {r3 - r10} @ copy from source address [r0] + stmia r1!, {r3 - r10} @ copy to target address [r1] + cmp r0, r2 @ until source end addreee [r2] + ble copy_loop +#endif /* CONFIG_SKIP_RELOCATE_UBOOT */ + + /* Set up the stack */ +stack_setup: + ldr r0, _TEXT_BASE @ upper 128 KiB: relocated uboot + sub r0, r0, #CONFIG_SYS_MALLOC_LEN @ malloc area + sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE @ bdinfo +#ifdef CONFIG_USE_IRQ + sub r0, r0, #(CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ) +#endif + sub sp, r0, #12 @ leave 3 words for abort-stack + and sp, sp, #~7 @ 8 byte alinged for (ldr/str)d + + /* Clear BSS (if any). Is below tx (watch load addr - need space) */ +clear_bss: + ldr r0, _bss_start @ find start of bss segment + ldr r1, _bss_end @ stop here + mov r2, #0x00000000 @ clear value +clbss_l: + str r2, [r0] @ clear BSS location + cmp r0, r1 @ are we at the end yet + add r0, r0, #4 @ increment clear index pointer + bne clbss_l @ keep clearing till at end + + ldr pc, _start_armboot @ jump to C code + +_start_armboot: .word start_armboot + + +/************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + *************************************************************************/ +cpu_init_crit: + /* + * Invalidate L1 I/D + */ + mov r0, #0 @ set up for MCR + mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs + mcr p15, 0, r0, c7, c5, 0 @ invalidate icache + + /* + * disable MMU stuff and caches + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x00002000 @ clear bits 13 (--V-) + bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM) + orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align + orr r0, r0, #0x00000800 @ set bit 12 (Z---) BTB + mcr p15, 0, r0, c1, c0, 0 + + /* + * Jump to board specific initialization... + * The Mask ROM will have already initialized + * basic memory. Go here to bump up clock rate and handle + * wake up conditions. + */ + mov ip, lr @ persevere link reg across call + bl lowlevel_init @ go setup pll,mux,memory + mov lr, ip @ restore link + mov pc, lr @ back to my caller +/* + ************************************************************************* + * + * 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 +#define I_BIT 0x80 + +/* + * use bad_save_user_regs for abort/prefetch/undef/swi ... + * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling + */ + + .macro bad_save_user_regs + sub sp, sp, #S_FRAME_SIZE @ carve out a frame on current + @ user stack + stmia sp, {r0 - r12} @ Save user registers (now in + @ svc mode) r0-r12 + + ldr r2, _armboot_start + sub r2, r2, #(CONFIG_SYS_MALLOC_LEN) + sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE + 8) @ set base 2 words into abort + @ stack + ldmia r2, {r2 - r3} @ get values for "aborted" pc + @ and cpsr (into parm regs) + add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack + + add r5, sp, #S_SP + mov r1, lr + stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr + mov r0, sp @ save current stack into r0 + @ (param register) + .endm + + .macro irq_save_user_regs + sub sp, sp, #S_FRAME_SIZE + stmia sp, {r0 - r12} @ Calling r0-r12 + add r8, sp, #S_PC @ !! R8 NEEDS to be saved !! + @ a reserved stack spot would + @ be good. + 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, _armboot_start @ setup our mode stack (enter + @ in banked mode) + sub r13, r13, #(CONFIG_SYS_MALLOC_LEN) @ move past malloc pool + sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE + 8) @ move to reserved a couple + @ spots for abort stack + + str lr, [r13] @ save caller lr in position 0 + @ of saved stack + mrs lr, spsr @ get the spsr + str lr, [r13, #4] @ save spsr in position 1 of + @ saved stack + + mov r13, #MODE_SVC @ prepare SVC-Mode + @ msr spsr_c, r13 + msr spsr, r13 @ switch modes, make sure + @ moves will execute + mov lr, pc @ capture return pc + movs pc, lr @ jump to next instruction & + @ switch modes. + .endm + + .macro get_bad_stack_swi + sub r13, r13, #4 @ space on current stack for + @ scratch reg. + str r0, [r13] @ save R0's value. + ldr r0, _armboot_start @ get data regions start + sub r0, r0, #(CONFIG_SYS_MALLOC_LEN) @ move past malloc pool + sub r0, r0, #(CONFIG_SYS_GBL_DATA_SIZE + 8) @ move past gbl and a couple + @ spots for abort stack + str lr, [r0] @ save caller lr in position 0 + @ of saved stack + mrs r0, spsr @ get the spsr + str lr, [r0, #4] @ save spsr in position 1 of + @ saved stack + ldr r0, [r13] @ restore r0 + add r13, r13, #4 @ pop stack entry + .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_swi + 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 + /* someone ought to write a more effective fiq_save_user_regs */ + irq_save_user_regs + bl do_fiq + 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 diff --git a/arch/arm/cpu/arm_cortexa8/u-boot.lds b/arch/arm/cpu/arm_cortexa8/u-boot.lds new file mode 100644 index 0000000000..820e3a1043 --- /dev/null +++ b/arch/arm/cpu/arm_cortexa8/u-boot.lds @@ -0,0 +1,58 @@ +/* + * January 2004 - Changed to support H4 device + * Copyright (c) 2004-2008 Texas Instruments + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + arch/arm/cpu/arm_cortexa8/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss) } + _end = .; +} diff --git a/arch/arm/cpu/arm_intcm/Makefile b/arch/arm/cpu/arm_intcm/Makefile new file mode 100644 index 0000000000..7701b03bbe --- /dev/null +++ b/arch/arm/cpu/arm_intcm/Makefile @@ -0,0 +1,47 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(CPU).a + +START = start.o +COBJS = cpu.o + +SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm_intcm/config.mk b/arch/arm/cpu/arm_intcm/config.mk new file mode 100644 index 0000000000..e783f697a1 --- /dev/null +++ b/arch/arm/cpu/arm_intcm/config.mk @@ -0,0 +1,32 @@ +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float + +PLATFORM_CPPFLAGS += -march=armv4 +# ========================================================================= +# +# Supply options according to compiler version +# +# ========================================================================= +PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/arch/arm/cpu/arm_intcm/cpu.c b/arch/arm/cpu/arm_intcm/cpu.c new file mode 100644 index 0000000000..c0748e872e --- /dev/null +++ b/arch/arm/cpu/arm_intcm/cpu.c @@ -0,0 +1,52 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * CPU specific code for an unknown cpu + * - hence fairly empty...... + */ + +#include +#include + +int cleanup_before_linux (void) +{ + /* + * this function is called just before we call linux + * it prepares the processor for linux + * + * we turn off caches etc ... + */ + + disable_interrupts (); + + /* Since the CM has unknown processor we do not support + * cache operations + */ + + return (0); +} diff --git a/arch/arm/cpu/arm_intcm/start.S b/arch/arm/cpu/arm_intcm/start.S new file mode 100644 index 0000000000..bb1f003592 --- /dev/null +++ b/arch/arm/cpu/arm_intcm/start.S @@ -0,0 +1,372 @@ +/* + * armboot - Startup Code for ARM926EJS CPU-core + * + * Copyright (c) 2003 Texas Instruments + * + * ----- Adapted for OMAP1610 OMAP730 from ARM925t code ------ + * + * Copyright (c) 2001 Marius Gröger + * Copyright (c) 2002 Alex Züpke + * Copyright (c) 2002 Gary Jennejohn + * Copyright (c) 2003 Richard Woodruff + * Copyright (c) 2003 Kshitij + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + +#include +#include + +/* + ************************************************************************* + * + * Jump vector table + * + ************************************************************************* + */ + +.globl _start +_start: + b 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 + +_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! + * setup memory and board specific bits prior to relocation. + * relocate armboot to ram + * setup stack + * + ************************************************************************* + */ + +_TEXT_BASE: + .word TEXT_BASE /* address of _start in the linked image */ + +.globl _armboot_start +_armboot_start: + .word _start + +/* + * These are defined in the board-specific linker script. + */ +.globl _bss_start +_bss_start: + .word __bss_start + +.globl _bss_end +_bss_end: + .word _end + +#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 + + +/* + * the actual reset code + */ +.globl reset +reset: + /* + * set the cpu to SVC32 mode + */ + mrs r0,cpsr + bic r0,r0,#0x1f + orr r0,r0,#0xd3 + msr cpsr,r0 + + /* + * we do sys-critical inits only at reboot, + * not when booting from ram! + */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl cpu_init_crit +#endif + +relocate: /* relocate U-Boot to RAM */ + adr r0, _start /* pc relative address of label */ + ldr r1, _TEXT_BASE /* linked image address of label */ + cmp r0, r1 /* test if we run from flash or RAM */ + beq stack_setup /* ifeq we are in the RAM copy */ + + ldr r2, _armboot_start + ldr r3, _bss_start + sub r2, r3, r2 /* r2 <- size of armboot */ + add r2, r0, r2 /* r2 <- source end address */ + +copy_loop: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end addreee [r2] */ + ble copy_loop + + /* Set up the stack */ +stack_setup: + ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ + sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */ + sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ +#ifdef CONFIG_USE_IRQ + sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) +#endif + sub sp, r0, #12 /* leave 3 words for abort-stack */ + +clear_bss: + ldr r0, _bss_start /* find start of bss segment */ + ldr r1, _bss_end /* stop here */ + mov r2, #0x00000000 /* clear */ + +clbss_l:str r2, [r0] /* clear loop... */ + add r0, r0, #4 + cmp r0, r1 + ble clbss_l + + ldr pc, _start_armboot + +_start_armboot: + .word start_armboot + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + ************************************************************************* + */ + +#ifndef CONFIG_SKIP_LOWLEVEL_INIT +cpu_init_crit: + /* arm_int_generic assumes the ARM boot monitor, or user software, + * has initialized the platform + */ + mov pc, lr /* back to my caller */ +#endif +/* + ************************************************************************* + * + * 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 +#define I_BIT 0x80 + +/* + * use bad_save_user_regs for abort/prefetch/undef/swi ... + * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling + */ + + .macro bad_save_user_regs + @ carve out a frame on current user stack + sub sp, sp, #S_FRAME_SIZE + stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12 + + ldr r2, _armboot_start + sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) + sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack + @ get values for "aborted" pc and cpsr (into parm regs) + ldmia r2, {r2 - r3} + add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack + add r5, sp, #S_SP + mov r1, lr + stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr + mov r0, sp @ save current stack into r0 (param register) + .endm + + .macro irq_save_user_regs + sub sp, sp, #S_FRAME_SIZE + stmia sp, {r0 - r12} @ Calling r0-r12 + @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good. + 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, _armboot_start @ setup our mode stack + sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) + sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack + + str lr, [r13] @ save caller lr in position 0 of saved stack + mrs lr, spsr @ get the spsr + str lr, [r13, #4] @ save spsr in position 1 of saved stack + mov r13, #MODE_SVC @ prepare SVC-Mode + @ msr spsr_c, r13 + msr spsr, r13 @ switch modes, make sure moves will execute + mov lr, pc @ capture return pc + movs pc, lr @ jump to next instruction & switch modes. + .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 +.globl undefined_instruction +undefined_instruction: + get_bad_stack + bad_save_user_regs + bl do_undefined_instruction + + .align 5 +.globl software_interrupt +software_interrupt: + get_bad_stack + bad_save_user_regs + bl do_software_interrupt + + .align 5 +.globl prefetch_abort +prefetch_abort: + get_bad_stack + bad_save_user_regs + bl do_prefetch_abort + + .align 5 +.globl data_abort +data_abort: + get_bad_stack + bad_save_user_regs + bl do_data_abort + + .align 5 +.globl not_used +not_used: + get_bad_stack + bad_save_user_regs + bl do_not_used + +#ifdef CONFIG_USE_IRQ + .align 5 +.globl irq +irq: + get_irq_stack + irq_save_user_regs + bl do_irq + irq_restore_user_regs + + .align 5 +.globl fiq +fiq: + get_fiq_stack + /* someone ought to write a more effiction fiq_save_user_regs */ + irq_save_user_regs + bl do_fiq + irq_restore_user_regs + +#else + + .align 5 +.globl irq +irq: + get_bad_stack + bad_save_user_regs + bl do_irq + + .align 5 +.globl fiq +fiq: + get_bad_stack + bad_save_user_regs + bl do_fiq + +#endif diff --git a/arch/arm/cpu/arm_intcm/u-boot.lds b/arch/arm/cpu/arm_intcm/u-boot.lds new file mode 100644 index 0000000000..4ed7d8906d --- /dev/null +++ b/arch/arm/cpu/arm_intcm/u-boot.lds @@ -0,0 +1,56 @@ +/* + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + arch/arm/cpu/arm_intcm/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = ALIGN(4); + __bss_start = .; + .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } + _end = .; +} diff --git a/arch/arm/cpu/ixp/Makefile b/arch/arm/cpu/ixp/Makefile new file mode 100644 index 0000000000..1403c4f390 --- /dev/null +++ b/arch/arm/cpu/ixp/Makefile @@ -0,0 +1,50 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(CPU).a + +START = start.o + +COBJS-y += cpu.o +COBJS-$(CONFIG_USE_IRQ) += interrupts.o +COBJS-y += timer.o + +SRCS := $(START:.o=.S) $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/ixp/config.mk b/arch/arm/cpu/ixp/config.mk new file mode 100644 index 0000000000..deca3f4d55 --- /dev/null +++ b/arch/arm/cpu/ixp/config.mk @@ -0,0 +1,35 @@ +# +# (C) Copyright 2002 +# Sysgo Real-Time Solutions, GmbH +# Marius Groeger +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +BIG_ENDIAN = y + +PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float -mbig-endian + +PLATFORM_CPPFLAGS += -mbig-endian -march=armv5te -mtune=strongarm1100 +# ========================================================================= +# +# Supply options according to compiler version +# +# ========================================================================= +PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/arch/arm/cpu/ixp/cpu.c b/arch/arm/cpu/ixp/cpu.c new file mode 100644 index 0000000000..ce275e5f3c --- /dev/null +++ b/arch/arm/cpu/ixp/cpu.c @@ -0,0 +1,143 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * CPU specific code + */ + +#include +#include +#include +#include +#include + +ulong loops_per_jiffy; + +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: + loops_per_jiffy = 887467; + speed = 533; + break; + + case 0x1d: + loops_per_jiffy = 666016; + speed = 400; + break; + + case 0x1f: + loops_per_jiffy = 442901; + 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; +} +*/ + +#ifdef CONFIG_BOOTCOUNT_LIMIT + +void bootcount_store (ulong a) +{ + volatile ulong *save_addr = (volatile ulong *)(CONFIG_SYS_BOOTCOUNT_ADDR); + + save_addr[0] = a; + save_addr[1] = BOOTCOUNT_MAGIC; +} + +ulong bootcount_load (void) +{ + volatile ulong *save_addr = (volatile ulong *)(CONFIG_SYS_BOOTCOUNT_ADDR); + + if (save_addr[1] != BOOTCOUNT_MAGIC) + return 0; + else + return save_addr[0]; +} + +#endif /* CONFIG_BOOTCOUNT_LIMIT */ + +int cpu_eth_init(bd_t *bis) +{ +#ifdef CONFIG_IXP4XX_NPE + npe_initialize(bis); +#endif + return 0; +} diff --git a/arch/arm/cpu/ixp/interrupts.c b/arch/arm/cpu/ixp/interrupts.c new file mode 100644 index 0000000000..06a826af63 --- /dev/null +++ b/arch/arm/cpu/ixp/interrupts.c @@ -0,0 +1,82 @@ +/* + * (C) Copyright 2006 + * Stefan Roese, DENX Software Engineering, sr@denx.de. + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +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); +} diff --git a/arch/arm/cpu/ixp/npe/IxEthAcc.c b/arch/arm/cpu/ixp/npe/IxEthAcc.c new file mode 100644 index 0000000000..061b24bb50 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxEthAcc.c @@ -0,0 +1,261 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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_ACC_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); +} + + diff --git a/arch/arm/cpu/ixp/npe/IxEthAccCommon.c b/arch/arm/cpu/ixp/npe/IxEthAccCommon.c new file mode 100644 index 0000000000..211203dffd --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxEthAccCommon.c @@ -0,0 +1,1049 @@ +/** + * @file IxEthAccCommon.c + * + * @author Intel Corporation + * @date 12-Feb-2002 + * + * @brief This file contains the implementation common support routines for the component + * + * Design Notes: + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +/* + * Component header files + */ + +#include "IxOsal.h" +#include "IxEthAcc.h" +#include "IxEthDB.h" +#include "IxNpeMh.h" +#include "IxEthDBPortDefs.h" +#include "IxFeatureCtrl.h" +#include "IxEthAcc_p.h" +#include "IxEthAccQueueAssign_p.h" + +#include "IxEthAccDataPlane_p.h" +#include "IxEthAccMii_p.h" + +/** + * @addtogroup IxEthAccPri + *@{ + */ + +extern IxEthAccInfo ixEthAccDataInfo; + +/** + * + * @brief Maximum number of RX queues set to be the maximum number + * of traffic calsses. + * + */ +#define IX_ETHACC_MAX_RX_QUEUES \ + (IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY \ + - IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY \ + + 1) + +/** + * + * @brief Maximum number of 128 entry RX queues + * + */ +#define IX_ETHACC_MAX_LARGE_RX_QUEUES 4 + +/** + * + * @brief Data structure template for Default RX Queues + * + */ +IX_ETH_ACC_PRIVATE +IxEthAccQregInfo ixEthAccQmgrRxDefaultTemplate = + { + IX_ETH_ACC_RX_FRAME_ETH_Q, /**< Queue ID */ + "Eth Rx Q", + ixEthRxFrameQMCallback, /**< Functional callback */ + (IxQMgrCallbackId) 0, /**< Callback tag */ + IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */ + IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */ + TRUE, /**< Enable Q notification at startup */ + IX_ETH_ACC_RX_FRAME_ETH_Q_SOURCE,/**< Q Condition to drive callback */ + IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */ + IX_QMGR_Q_WM_LEVEL1, /**< Q High water mark - needed by NPE */ + }; + +/** + * + * @brief Data structure template for Small RX Queues + * + */ +IX_ETH_ACC_PRIVATE +IxEthAccQregInfo ixEthAccQmgrRxSmallTemplate = + { + IX_ETH_ACC_RX_FRAME_ETH_Q, /**< Queue ID */ + "Eth Rx Q", + ixEthRxFrameQMCallback, /**< Functional callback */ + (IxQMgrCallbackId) 0, /**< Callback tag */ + IX_QMGR_Q_SIZE64, /**< Allocate Smaller Q */ + IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */ + TRUE, /**< Enable Q notification at startup */ + IX_ETH_ACC_RX_FRAME_ETH_Q_SOURCE,/**< Q Condition to drive callback */ + IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */ + IX_QMGR_Q_WM_LEVEL1, /**< Q High water mark - needed by NPE */ + }; + + +/** + * + * @brief Data structure used to register & initialize the Queues + * + */ +IX_ETH_ACC_PRIVATE +IxEthAccQregInfo ixEthAccQmgrStaticInfo[]= +{ + { + IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q, + "Eth Rx Fr Q 1", + ixEthRxFreeQMCallback, + (IxQMgrCallbackId) IX_ETH_PORT_1, + IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */ + IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */ + FALSE, /**< Disable Q notification at startup */ + IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q_SOURCE, /**< Q Condition to drive callback */ + IX_QMGR_Q_WM_LEVEL0, /***< Q Low water mark */ + IX_QMGR_Q_WM_LEVEL64, /**< Q High water mark */ + }, + + { + IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q, + "Eth Rx Fr Q 2", + ixEthRxFreeQMCallback, + (IxQMgrCallbackId) IX_ETH_PORT_2, + IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */ + IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */ + FALSE, /**< Disable Q notification at startup */ + IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q_SOURCE, /**< Q Condition to drive callback */ + IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */ + IX_QMGR_Q_WM_LEVEL64, /**< Q High water mark */ + }, +#ifdef __ixp46X + { + IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q, + "Eth Rx Fr Q 3", + ixEthRxFreeQMCallback, + (IxQMgrCallbackId) IX_ETH_PORT_3, + IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */ + IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */ + FALSE, /**< Disable Q notification at startup */ + IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q_SOURCE, /**< Q Condition to drive callback */ + IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */ + IX_QMGR_Q_WM_LEVEL64, /**< Q High water mark */ + }, +#endif + { + IX_ETH_ACC_TX_FRAME_ENET0_Q, + "Eth Tx Q 1", + ixEthTxFrameQMCallback, + (IxQMgrCallbackId) IX_ETH_PORT_1, + IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */ + IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */ + FALSE, /**< Disable Q notification at startup */ + IX_ETH_ACC_TX_FRAME_ENET0_Q_SOURCE, /**< Q Condition to drive callback */ + IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */ + IX_QMGR_Q_WM_LEVEL64, /**< Q High water mark */ + }, + + { + IX_ETH_ACC_TX_FRAME_ENET1_Q, + "Eth Tx Q 2", + ixEthTxFrameQMCallback, + (IxQMgrCallbackId) IX_ETH_PORT_2, + IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */ + IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */ + FALSE, /**< Disable Q notification at startup */ + IX_ETH_ACC_TX_FRAME_ENET1_Q_SOURCE, /**< Q Condition to drive callback */ + IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */ + IX_QMGR_Q_WM_LEVEL64, /**< Q High water mark */ + }, +#ifdef __ixp46X + { + IX_ETH_ACC_TX_FRAME_ENET2_Q, + "Eth Tx Q 3", + ixEthTxFrameQMCallback, + (IxQMgrCallbackId) IX_ETH_PORT_3, + IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */ + IX_QMGR_Q_ENTRY_SIZE1, /** Queue Entry Sizes - all Q entries are single ord entries */ + FALSE, /** Disable Q notification at startup */ + IX_ETH_ACC_TX_FRAME_ENET2_Q_SOURCE, /** Q Condition to drive callback */ + IX_QMGR_Q_WM_LEVEL0, /* No queues use almost empty */ + IX_QMGR_Q_WM_LEVEL64, /** Q High water mark - needed used */ + }, +#endif + { + IX_ETH_ACC_TX_FRAME_DONE_ETH_Q, + "Eth Tx Done Q", + ixEthTxFrameDoneQMCallback, + (IxQMgrCallbackId) 0, + IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */ + IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */ + TRUE, /**< Enable Q notification at startup */ + IX_ETH_ACC_TX_FRAME_DONE_ETH_Q_SOURCE, /**< Q Condition to drive callback */ + IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */ + IX_QMGR_Q_WM_LEVEL2, /**< Q High water mark - needed by NPE */ + }, + + { /* Null Termination entry + */ + (IxQMgrQId)0, + (char *) NULL, + (IxQMgrCallback) NULL, + (IxQMgrCallbackId) 0, + 0, + 0, + 0, + 0, + 0, + 0 + } + +}; + +/** + * + * @brief Data structure used to register & initialize the Queues + * + * The structure will be filled at run time depending on the NPE + * image already loaded and the QoS configured in ethDB. + * + */ +IX_ETH_ACC_PRIVATE +IxEthAccQregInfo ixEthAccQmgrRxQueuesInfo[IX_ETHACC_MAX_RX_QUEUES+1]= +{ + { /* PlaceHolder for rx queues + * depending on the QoS configured + */ + (IxQMgrQId)0, + (char *) NULL, + (IxQMgrCallback) NULL, + (IxQMgrCallbackId) 0, + 0, + 0, + 0, + 0, + 0, + 0 + }, + + { /* PlaceHolder for rx queues + * depending on the QoS configured + */ + (IxQMgrQId)0, + (char *) NULL, + (IxQMgrCallback) NULL, + (IxQMgrCallbackId) 0, + 0, + 0, + 0, + 0, + 0, + 0 + }, + + { /* PlaceHolder for rx queues + * depending on the QoS configured + */ + (IxQMgrQId)0, + (char *) NULL, + (IxQMgrCallback) NULL, + (IxQMgrCallbackId) 0, + 0, + 0, + 0, + 0, + 0, + 0 + }, + + { /* PlaceHolder for rx queues + * depending on the QoS configured + */ + (IxQMgrQId)0, + (char *) NULL, + (IxQMgrCallback) NULL, + (IxQMgrCallbackId) 0, + 0, + 0, + 0, + 0, + 0, + 0 + }, + + { /* PlaceHolder for rx queues + * depending on the QoS configured + */ + (IxQMgrQId)0, + (char *) NULL, + (IxQMgrCallback) NULL, + (IxQMgrCallbackId) 0, + 0, + 0, + 0, + 0, + 0, + 0 + }, + + { /* PlaceHolder for rx queues + * depending on the QoS configured + */ + (IxQMgrQId)0, + (char *) NULL, + (IxQMgrCallback) NULL, + (IxQMgrCallbackId) 0, + 0, + 0, + 0, + 0, + 0, + 0 + }, + + { /* PlaceHolder for rx queues + * depending on the QoS configured + */ + (IxQMgrQId)0, + (char *) NULL, + (IxQMgrCallback) NULL, + (IxQMgrCallbackId) 0, + 0, + 0, + 0, + 0, + 0, + 0 + }, + + { /* PlaceHolder for rx queues + * depending on the QoS configured + */ + (IxQMgrQId)0, + (char *) NULL, + (IxQMgrCallback) NULL, + (IxQMgrCallbackId) 0, + 0, + 0, + 0, + 0, + 0, + 0 + }, + + { /* Null Termination entry + */ + (IxQMgrQId)0, + (char *) NULL, + (IxQMgrCallback) NULL, + (IxQMgrCallbackId) 0, + 0, + 0, + 0, + 0, + 0, + 0 + } + +}; + +/* forward declarations */ +IX_ETH_ACC_PRIVATE IxEthAccStatus +ixEthAccQMgrQueueSetup(IxEthAccQregInfo *qInfoDes); + +/** + * @fn ixEthAccQMgrQueueSetup(void) + * + * @brief Setup one queue and its event, and register the callback required + * by this component to the QMgr + * + * @internal + */ +IX_ETH_ACC_PRIVATE IxEthAccStatus +ixEthAccQMgrQueueSetup(IxEthAccQregInfo *qInfoDes) +{ + /* + * Configure each Q. + */ + if ( ixQMgrQConfig( qInfoDes->qName, + qInfoDes->qId, + qInfoDes->qSize, + qInfoDes->qWords) != IX_SUCCESS) + { + return IX_ETH_ACC_FAIL; + } + + if ( ixQMgrWatermarkSet( qInfoDes->qId, + qInfoDes->AlmostEmptyThreshold, + qInfoDes->AlmostFullThreshold + ) != IX_SUCCESS) + { + return IX_ETH_ACC_FAIL; + } + + /* + * Set dispatcher priority. + */ + if ( ixQMgrDispatcherPrioritySet( qInfoDes->qId, + IX_ETH_ACC_QM_QUEUE_DISPATCH_PRIORITY) + != IX_SUCCESS) + { + return IX_ETH_ACC_FAIL; + } + + /* + * Register callbacks for each Q. + */ + if ( ixQMgrNotificationCallbackSet(qInfoDes->qId, + qInfoDes->qCallback, + qInfoDes->callbackTag) + != IX_SUCCESS ) + { + return IX_ETH_ACC_FAIL; + } + + /* + * Set notification condition for Q + */ + if ( qInfoDes->qNotificationEnableAtStartup == TRUE ) + { + if ( ixQMgrNotificationEnable(qInfoDes->qId, + qInfoDes->qConditionSource) + != IX_SUCCESS ) + { + return IX_ETH_ACC_FAIL; + } + } + + return(IX_ETH_ACC_SUCCESS); +} + +/** + * @fn ixEthAccQMgrQueuesConfig(void) + * + * @brief Setup all the queues and register all callbacks required + * by this component to the QMgr + * + * The RxFree queues, tx queues, rx queues are configured statically + * + * Rx queues configuration is driven by QoS setup. + * Many Rx queues may be required when QoS is enabled (this depends + * on IxEthDB setup and the images being downloaded). The configuration + * of the rxQueues is done in many steps as follows: + * + * @li select all Rx queues as configured by ethDB for all ports + * @li sort the queues by traffic class + * @li build the priority dependency for all queues + * @li fill the configuration for all rx queues + * @li configure all statically configured queues + * @li configure all dynamically configured queues + * + * @param none + * + * @return IxEthAccStatus + * + * @internal + */ +IX_ETH_ACC_PUBLIC +IxEthAccStatus ixEthAccQMgrQueuesConfig(void) +{ + struct + { + int npeCount; + UINT32 npeId; + IxQMgrQId qId; + IxEthDBProperty trafficClass; + } rxQueues[IX_ETHACC_MAX_RX_QUEUES]; + + UINT32 rxQueue = 0; + UINT32 rxQueueCount = 0; + IxQMgrQId ixQId =IX_QMGR_MAX_NUM_QUEUES; + IxEthDBStatus ixEthDBStatus = IX_ETH_DB_SUCCESS; + IxEthDBPortId ixEthDbPortId = 0; + IxEthAccPortId ixEthAccPortId = 0; + UINT32 ixNpeId = 0; + UINT32 ixHighestNpeId = 0; + UINT32 sortIterations = 0; + IxEthAccStatus ret = IX_ETH_ACC_SUCCESS; + IxEthAccQregInfo *qInfoDes = NULL; + IxEthDBProperty ixEthDBTrafficClass = IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY; + IxEthDBPropertyType ixEthDBPropertyType = IX_ETH_DB_INTEGER_PROPERTY; + UINT32 ixEthDBParameter = 0; + BOOL completelySorted = FALSE; + + /* Fill the corspondance between ports and queues + * This defines the mapping from port to queue Ids. + */ + + ixEthAccPortData[IX_ETH_PORT_1].ixEthAccRxData.rxFreeQueue + = IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q; + ixEthAccPortData[IX_ETH_PORT_2].ixEthAccRxData.rxFreeQueue + = IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q; +#ifdef __ixp46X + ixEthAccPortData[IX_ETH_PORT_3].ixEthAccRxData.rxFreeQueue + = IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q; +#endif + ixEthAccPortData[IX_ETH_PORT_1].ixEthAccTxData.txQueue + = IX_ETH_ACC_TX_FRAME_ENET0_Q; + ixEthAccPortData[IX_ETH_PORT_2].ixEthAccTxData.txQueue + = IX_ETH_ACC_TX_FRAME_ENET1_Q; +#ifdef __ixp46X + ixEthAccPortData[IX_ETH_PORT_3].ixEthAccTxData.txQueue + = IX_ETH_ACC_TX_FRAME_ENET2_Q; +#endif + /* Fill the corspondance between ports and NPEs + * This defines the mapping from port to npeIds. + */ + + ixEthAccPortData[IX_ETH_PORT_1].npeId = IX_NPEMH_NPEID_NPEB; + ixEthAccPortData[IX_ETH_PORT_2].npeId = IX_NPEMH_NPEID_NPEC; +#ifdef __ixp46X + ixEthAccPortData[IX_ETH_PORT_3].npeId = IX_NPEMH_NPEID_NPEA; +#endif + /* set the default rx scheduling discipline */ + ixEthAccDataInfo.schDiscipline = FIFO_NO_PRIORITY; + + /* + * Queue Selection step: + * + * The following code selects all the queues and build + * a temporary array which contains for each queue + * - the queue Id, + * - the highest traffic class (in case of many + * priorities configured for the same queue on different + * ports) + * - the number of different Npes which are + * configured to write to this queue. + * + * The output of this loop is a temporary array of RX queues + * in any order. + * + */ +#ifdef CONFIG_IXP425_COMPONENT_ETHDB + for (ixEthAccPortId = 0; + (ixEthAccPortId < IX_ETH_ACC_NUMBER_OF_PORTS) + && (ret == IX_ETH_ACC_SUCCESS); + ixEthAccPortId++) + { + /* map between ethDb and ethAcc port Ids */ + ixEthDbPortId = (IxEthDBPortId)ixEthAccPortId; + + /* map between npeId and ethAcc port Ids */ + ixNpeId = IX_ETH_ACC_PORT_TO_NPE_ID(ixEthAccPortId); + + /* Iterate thru the different priorities */ + for (ixEthDBTrafficClass = IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY; + ixEthDBTrafficClass <= IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY; + ixEthDBTrafficClass++) + { + ixEthDBStatus = ixEthDBFeaturePropertyGet( + ixEthDbPortId, + IX_ETH_DB_VLAN_QOS, + ixEthDBTrafficClass, + &ixEthDBPropertyType, + (void *)&ixEthDBParameter); + + if (ixEthDBStatus == IX_ETH_DB_SUCCESS) + { + /* This port and QoS class are mapped to + * a RX queue. + */ + if (ixEthDBPropertyType == IX_ETH_DB_INTEGER_PROPERTY) + { + /* remember the highest npe Id supporting ethernet */ + if (ixNpeId > ixHighestNpeId) + { + ixHighestNpeId = ixNpeId; + } + + /* search the queue in the list of queues + * already used by an other port or QoS + */ + for (rxQueue = 0; + rxQueue < rxQueueCount; + rxQueue++) + { + if (rxQueues[rxQueue].qId == (IxQMgrQId)ixEthDBParameter) + { + /* found an existing setup, update the number of ports + * for this queue if the port maps to + * a different NPE. + */ + if (rxQueues[rxQueue].npeId != ixNpeId) + { + rxQueues[rxQueue].npeCount++; + rxQueues[rxQueue].npeId = ixNpeId; + } + /* get the highest traffic class for this queue */ + if (rxQueues[rxQueue].trafficClass > ixEthDBTrafficClass) + { + rxQueues[rxQueue].trafficClass = ixEthDBTrafficClass; + } + break; + } + } + if (rxQueue == rxQueueCount) + { + /* new queue not found in the current list, + * add a new entry. + */ + IX_OSAL_ASSERT(rxQueueCount < IX_ETHACC_MAX_RX_QUEUES); + rxQueues[rxQueueCount].qId = ixEthDBParameter; + rxQueues[rxQueueCount].npeCount = 1; + rxQueues[rxQueueCount].npeId = ixNpeId; + rxQueues[rxQueueCount].trafficClass = ixEthDBTrafficClass; + rxQueueCount++; + } + } + else + { + /* unexpected property type (not Integer) */ + ret = IX_ETH_ACC_FAIL; + + IX_ETH_ACC_WARNING_LOG("ixEthAccQMgrQueuesConfig: unexpected property type returned by EthDB\n", 0, 0, 0, 0, 0, 0); + + /* no point to continue to iterate */ + break; + } + } + else + { + /* No Rx queue configured for this port + * and this traffic class. Do nothing. + */ + } + } + + /* notify EthDB that queue initialization is complete and traffic class allocation is frozen */ + ixEthDBFeaturePropertySet(ixEthDbPortId, + IX_ETH_DB_VLAN_QOS, + IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE, + NULL /* ignored */); + } + +#else + + ixNpeId = IX_ETH_ACC_PORT_TO_NPE_ID(ixEthAccPortId); + rxQueues[0].qId = 4; + rxQueues[0].npeCount = 1; + rxQueues[0].npeId = ixNpeId; + rxQueues[0].trafficClass = IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY; + rxQueueCount++; + +#endif + + /* check there is at least 1 rx queue : there is no point + * to continue if there is no rx queue configured + */ + if ((rxQueueCount == 0) || (ret == IX_ETH_ACC_FAIL)) + { + IX_ETH_ACC_WARNING_LOG("ixEthAccQMgrQueuesConfig: no queues configured, bailing out\n", 0, 0, 0, 0, 0, 0); + return (IX_ETH_ACC_FAIL); + } + + /* Queue sort step: + * + * Re-order the array of queues by decreasing traffic class + * using a bubble sort. (trafficClass 0 is the lowest + * priority traffic, trafficClass 7 is the highest priority traffic) + * + * Primary sort order is traffic class + * Secondary sort order is npeId + * + * Note that a bubble sort algorithm is not very efficient when + * the number of queues grows . However, this is not a very bad choice + * considering the very small number of entries to sort. Also, bubble + * sort is extremely fast when the list is already sorted. + * + * The output of this loop is a sorted array of queues. + * + */ + sortIterations = 0; + do + { + sortIterations++; + completelySorted = TRUE; + for (rxQueue = 0; + rxQueue < rxQueueCount - sortIterations; + rxQueue++) + { + /* compare adjacent elements */ + if ((rxQueues[rxQueue].trafficClass < + rxQueues[rxQueue+1].trafficClass) + || ((rxQueues[rxQueue].trafficClass == + rxQueues[rxQueue+1].trafficClass) + &&(rxQueues[rxQueue].npeId < + rxQueues[rxQueue+1].npeId))) + { + /* swap adjacent elements */ + int npeCount = rxQueues[rxQueue].npeCount; + UINT32 npeId = rxQueues[rxQueue].npeId; + IxQMgrQId qId = rxQueues[rxQueue].qId; + IxEthDBProperty trafficClass = rxQueues[rxQueue].trafficClass; + rxQueues[rxQueue].npeCount = rxQueues[rxQueue+1].npeCount; + rxQueues[rxQueue].npeId = rxQueues[rxQueue+1].npeId; + rxQueues[rxQueue].qId = rxQueues[rxQueue+1].qId; + rxQueues[rxQueue].trafficClass = rxQueues[rxQueue+1].trafficClass; + rxQueues[rxQueue+1].npeCount = npeCount; + rxQueues[rxQueue+1].npeId = npeId; + rxQueues[rxQueue+1].qId = qId; + rxQueues[rxQueue+1].trafficClass = trafficClass; + completelySorted = FALSE; + } + } + } + while (!completelySorted); + + /* Queue traffic class list: + * + * Fill an array of rx queues linked by ascending traffic classes. + * + * If the queues are configured as follows + * qId 6 -> traffic class 0 (lowest) + * qId 7 -> traffic class 0 + * qId 8 -> traffic class 6 + * qId 12 -> traffic class 7 (highest) + * + * Then the output of this loop will be + * + * higherPriorityQueue[6] = 8 + * higherPriorityQueue[7] = 8 + * higherPriorityQueue[8] = 12 + * higherPriorityQueue[12] = Invalid queueId + * higherPriorityQueue[...] = Invalid queueId + * + * Note that this queue ordering does not handle all possibilities + * that could result from different rules associated with different + * ports, and inconsistencies in the rules. In all cases, the + * output of this algorithm is a simple linked list of queues, + * without closed circuit. + + * This list is implemented as an array with invalid values initialized + * with an "invalid" queue id which is the maximum number of queues. + * + */ + + /* + * Initialise the rx queue list. + */ + for (rxQueue = 0; rxQueue < IX_QMGR_MAX_NUM_QUEUES; rxQueue++) + { + ixEthAccDataInfo.higherPriorityQueue[rxQueue] = IX_QMGR_MAX_NUM_QUEUES; + } + + /* build the linked list for this NPE. + */ + for (ixNpeId = 0; + ixNpeId <= ixHighestNpeId; + ixNpeId++) + { + /* iterate thru the sorted list of queues + */ + ixQId = IX_QMGR_MAX_NUM_QUEUES; + for (rxQueue = 0; + rxQueue < rxQueueCount; + rxQueue++) + { + if (rxQueues[rxQueue].npeId == ixNpeId) + { + ixEthAccDataInfo.higherPriorityQueue[rxQueues[rxQueue].qId] = ixQId; + /* iterate thru queues with the same traffic class + * than the current queue. (queues are ordered by descending + * traffic classes and npeIds). + */ + while ((rxQueue < rxQueueCount - 1) + && (rxQueues[rxQueue].trafficClass + == rxQueues[rxQueue+1].trafficClass) + && (ixNpeId == rxQueues[rxQueue].npeId)) + { + rxQueue++; + ixEthAccDataInfo.higherPriorityQueue[rxQueues[rxQueue].qId] = ixQId; + } + ixQId = rxQueues[rxQueue].qId; + } + } + } + + /* point on the first dynamic queue description */ + qInfoDes = ixEthAccQmgrRxQueuesInfo; + + /* update the list of queues with the rx queues */ + for (rxQueue = 0; + (rxQueue < rxQueueCount) && (ret == IX_ETH_ACC_SUCCESS); + rxQueue++) + { + /* Don't utilize more than IX_ETHACC_MAX_LARGE_RX_QUEUES queues + * with the full 128 entries. For the lower priority queues, use + * a smaller number of entries. This ensures queue resources + * remain available for other components. + */ + if( (rxQueueCount > IX_ETHACC_MAX_LARGE_RX_QUEUES) && + (rxQueue < rxQueueCount - IX_ETHACC_MAX_LARGE_RX_QUEUES) ) + { + /* add the small RX Queue setup template to the list of queues */ + memcpy(qInfoDes, &ixEthAccQmgrRxSmallTemplate, sizeof(*qInfoDes)); + } else { + /* add the default RX Queue setup template to the list of queues */ + memcpy(qInfoDes, &ixEthAccQmgrRxDefaultTemplate, sizeof(*qInfoDes)); + } + + /* setup the RxQueue ID */ + qInfoDes->qId = rxQueues[rxQueue].qId; + + /* setup the RxQueue watermark level + * + * Each queue can be filled by many NPEs. To avoid the + * NPEs to write to a full queue, need to set the + * high watermark level for nearly full condition. + * (the high watermark level are a power of 2 + * starting from the top of the queue) + * + * Number of watermark + * ports level + * 1 0 + * 2 1 + * 3 2 + * 4 4 + * 5 4 + * 6 8 + * n approx. 2**ceil(log2(n)) + */ + if (rxQueues[rxQueue].npeCount == 1) + { + qInfoDes->AlmostFullThreshold = IX_QMGR_Q_WM_LEVEL0; + } + else if (rxQueues[rxQueue].npeCount == 2) + { + qInfoDes->AlmostFullThreshold = IX_QMGR_Q_WM_LEVEL1; + } + else if (rxQueues[rxQueue].npeCount == 3) + { + qInfoDes->AlmostFullThreshold = IX_QMGR_Q_WM_LEVEL2; + } + else + { + /* reach the maximum number for CSR 2.0 */ + IX_ETH_ACC_WARNING_LOG("ixEthAccQMgrQueuesConfig: maximum number of NPEs per queue reached, bailing out\n", 0, 0, 0, 0, 0, 0); + ret = IX_ETH_ACC_FAIL; + break; + } + + /* move to next queue entry */ + ++qInfoDes; + } + + /* configure the static list (RxFree, Tx and TxDone queues) */ + for (qInfoDes = ixEthAccQmgrStaticInfo; + (qInfoDes->qCallback != (IxQMgrCallback) NULL ) + && (ret == IX_ETH_ACC_SUCCESS); + ++qInfoDes) + { + ret = ixEthAccQMgrQueueSetup(qInfoDes); + } + + /* configure the dynamic list (Rx queues) */ + for (qInfoDes = ixEthAccQmgrRxQueuesInfo; + (qInfoDes->qCallback != (IxQMgrCallback) NULL ) + && (ret == IX_ETH_ACC_SUCCESS); + ++qInfoDes) + { + ret = ixEthAccQMgrQueueSetup(qInfoDes); + } + + return(ret); +} + +/** + * @fn ixEthAccQMgrRxQEntryGet(UINT32 *rxQueueEntries) + * + * @brief Add and return the total number of entries in all Rx queues + * + * @param UINT32 rxQueueEntries[in] number of entries in all queues + * + * @return void + * + * @note Rx queues configuration is driven by Qos Setup. There is a + * variable number of rx queues which are set at initialisation. + * + * @internal + */ +IX_ETH_ACC_PUBLIC +void ixEthAccQMgrRxQEntryGet(UINT32 *numRxQueueEntries) +{ + UINT32 rxQueueLevel; + IxEthAccQregInfo *qInfoDes;; + + *numRxQueueEntries = 0; + + /* iterate thru rx queues */ + for (qInfoDes = ixEthAccQmgrRxQueuesInfo; + qInfoDes->qCallback != (IxQMgrCallback)NULL; + ++qInfoDes) + { + /* retrieve the rx queue level */ + rxQueueLevel = 0; + ixQMgrQNumEntriesGet(qInfoDes->qId, &rxQueueLevel); + (*numRxQueueEntries) += rxQueueLevel; + } +} + +/** + * @fn ixEthAccQMgrRxCallbacksRegister(IxQMgrCallback ixQMgrCallback) + * + * @brief Change the callback registered to all rx queues. + * + * @param IxQMgrCallback ixQMgrCallback[in] QMgr callback to register + * + * @return IxEthAccStatus + * + * @note The user may decide to use different Rx mechanisms + * (e.g. receive many frames at the same time , or receive + * one frame at a time, depending on the overall application + * performances). A different QMgr callback is registered. This + * way, there is no excessive pointer checks in the datapath. + * + * @internal + */ +IX_ETH_ACC_PUBLIC +IxEthAccStatus ixEthAccQMgrRxCallbacksRegister(IxQMgrCallback ixQMgrCallback) +{ + IxEthAccQregInfo *qInfoDes; + IxEthAccStatus ret = IX_ETH_ACC_SUCCESS; + + /* parameter check */ + if (NULL == ixQMgrCallback) + { + ret = IX_ETH_ACC_FAIL; + } + + /* iterate thru rx queues */ + for (qInfoDes = ixEthAccQmgrRxQueuesInfo; + (qInfoDes->qCallback != (IxQMgrCallback) NULL ) + && (ret == IX_ETH_ACC_SUCCESS); + ++qInfoDes) + { + /* register the rx callback for all queues */ + if (ixQMgrNotificationCallbackSet(qInfoDes->qId, + ixQMgrCallback, + qInfoDes->callbackTag + ) != IX_SUCCESS) + { + ret = IX_ETH_ACC_FAIL; + } + } + return(ret); +} + +/** + * @fn ixEthAccSingleEthNpeCheck(IxEthAccPortId portId) + * + * @brief Check the npe exists for this port + * + * @param IxEthAccPortId portId[in] port + * + * @return IxEthAccStatus + * + * @internal + */ +IX_ETH_ACC_PUBLIC +IxEthAccStatus ixEthAccSingleEthNpeCheck(IxEthAccPortId 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 ((IX_ETH_PORT_1 == portId) && + (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) == + IX_FEATURE_CTRL_COMPONENT_ENABLED)) + { + return IX_ETH_ACC_SUCCESS; + } + + if ((IX_ETH_PORT_2 == portId) && + (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) == + IX_FEATURE_CTRL_COMPONENT_ENABLED)) + { + return IX_ETH_ACC_SUCCESS; + } + + if ((IX_ETH_PORT_3 == portId) && + (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA_ETH) == + IX_FEATURE_CTRL_COMPONENT_ENABLED)) + { + return IX_ETH_ACC_SUCCESS; + } + + return IX_ETH_ACC_FAIL; + } + + return IX_ETH_ACC_SUCCESS; +} + +/** + * @fn ixEthAccStatsShow(void) + * + * @brief Displays all EthAcc stats + * + * @return void + * + */ +void ixEthAccStatsShow(IxEthAccPortId portId) +{ + ixEthAccMdioShow(); + + printf("\nPort %u\nUnicast MAC : ", portId); + ixEthAccPortUnicastAddressShow(portId); + ixEthAccPortMulticastAddressShow(portId); + printf("\n"); + + ixEthAccDataPlaneShow(); +} + + + diff --git a/arch/arm/cpu/ixp/npe/IxEthAccControlInterface.c b/arch/arm/cpu/ixp/npe/IxEthAccControlInterface.c new file mode 100644 index 0000000000..44328473e6 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxEthAccControlInterface.c @@ -0,0 +1,533 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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; +} diff --git a/arch/arm/cpu/ixp/npe/IxEthAccDataPlane.c b/arch/arm/cpu/ixp/npe/IxEthAccDataPlane.c new file mode 100644 index 0000000000..b62f0d016e --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxEthAccDataPlane.c @@ -0,0 +1,2483 @@ +/** + * @file IxEthDataPlane.c + * + * @author Intel Corporation + * @date 12-Feb-2002 + * + * @brief This file contains the implementation of the IXPxxx + * Ethernet Access Data plane component + * + * Design Notes: + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#include "IxNpeMh.h" +#include "IxEthAcc.h" +#include "IxEthDB.h" +#include "IxOsal.h" +#include "IxEthDBPortDefs.h" +#include "IxFeatureCtrl.h" +#include "IxEthAcc_p.h" +#include "IxEthAccQueueAssign_p.h" + +extern PUBLIC IxEthAccMacState ixEthAccMacState[]; +extern PUBLIC UINT32 ixEthAccNewSrcMask; + +/** + * private functions prototype + */ +PRIVATE IX_OSAL_MBUF * +ixEthAccEntryFromQConvert(UINT32 qEntry, UINT32 mask); + +PRIVATE UINT32 +ixEthAccMbufRxQPrepare(IX_OSAL_MBUF *mbuf); + +PRIVATE UINT32 +ixEthAccMbufTxQPrepare(IX_OSAL_MBUF *mbuf); + +PRIVATE IxEthAccStatus +ixEthAccTxSwQHighestPriorityGet(IxEthAccPortId portId, + IxEthAccTxPriority *priorityPtr); + +PRIVATE IxEthAccStatus +ixEthAccTxFromSwQ(IxEthAccPortId portId, + IxEthAccTxPriority priority); + +PRIVATE IxEthAccStatus +ixEthAccRxFreeFromSwQ(IxEthAccPortId portId); + +PRIVATE void +ixEthAccMbufFromTxQ(IX_OSAL_MBUF *mbuf); + +PRIVATE void +ixEthAccMbufFromRxQ(IX_OSAL_MBUF *mbuf); + +PRIVATE IX_STATUS +ixEthAccQmgrLockTxWrite(IxEthAccPortId portId, + UINT32 qBuffer); + +PRIVATE IX_STATUS +ixEthAccQmgrLockRxWrite(IxEthAccPortId portId, + UINT32 qBuffer); + +PRIVATE IX_STATUS +ixEthAccQmgrTxWrite(IxEthAccPortId portId, + UINT32 qBuffer, + UINT32 priority); + +/** + * @addtogroup IxEthAccPri + *@{ + */ + +/* increment a counter only when stats are enabled */ +#define TX_STATS_INC(port,field) \ + IX_ETH_ACC_STATS_INC(ixEthAccPortData[port].ixEthAccTxData.stats.field) +#define RX_STATS_INC(port,field) \ + IX_ETH_ACC_STATS_INC(ixEthAccPortData[port].ixEthAccRxData.stats.field) + +/* always increment the counter (mainly used for unexpected errors) */ +#define TX_INC(port,field) \ + ixEthAccPortData[port].ixEthAccTxData.stats.field++ +#define RX_INC(port,field) \ + ixEthAccPortData[port].ixEthAccRxData.stats.field++ + +PRIVATE IxEthAccDataPlaneStats ixEthAccDataStats; + +extern IxEthAccPortDataInfo ixEthAccPortData[]; +extern IxEthAccInfo ixEthAccDataInfo; + +PRIVATE IxOsalFastMutex txWriteMutex[IX_ETH_ACC_NUMBER_OF_PORTS]; +PRIVATE IxOsalFastMutex rxWriteMutex[IX_ETH_ACC_NUMBER_OF_PORTS]; + +/** + * + * @brief Mbuf header conversion macros : they implement the + * different conversions using a temporary value. They also double-check + * that the parameters can be converted to/from NPE format. + * + */ +#if defined(__wince) && !defined(IN_KERNEL) +#define PTR_VIRT2NPE(ptrSrc,dst) \ + do { UINT32 temp; \ + IX_OSAL_ENSURE(sizeof(ptrSrc) == sizeof(UINT32), "Wrong parameter type"); \ + IX_OSAL_ENSURE(sizeof(dst) == sizeof(UINT32), "Wrong parameter type"); \ + temp = (UINT32)IX_OSAL_MBUF_MBUF_VIRTUAL_TO_PHYSICAL_TRANSLATION((IX_OSAL_MBUF*)ptrSrc); \ + (dst) = IX_OSAL_SWAP_BE_SHARED_LONG(temp); } \ + while(0) + +#define PTR_NPE2VIRT(type,src,ptrDst) \ + do { void *temp; \ + IX_OSAL_ENSURE(sizeof(type) == sizeof(UINT32), "Wrong parameter type"); \ + IX_OSAL_ENSURE(sizeof(src) == sizeof(UINT32), "Wrong parameter type"); \ + IX_OSAL_ENSURE(sizeof(ptrDst) == sizeof(UINT32), "Wrong parameter type"); \ + temp = (void *)IX_OSAL_SWAP_BE_SHARED_LONG(src); \ + (ptrDst) = (type)IX_OSAL_MBUF_MBUF_PHYSICAL_TO_VIRTUAL_TRANSLATION(temp); } \ + while(0) +#else +#define PTR_VIRT2NPE(ptrSrc,dst) \ + do { UINT32 temp; \ + IX_OSAL_ENSURE(sizeof(ptrSrc) == sizeof(UINT32), "Wrong parameter type"); \ + IX_OSAL_ENSURE(sizeof(dst) == sizeof(UINT32), "Wrong parameter type"); \ + temp = (UINT32)IX_OSAL_MMU_VIRT_TO_PHYS(ptrSrc); \ + (dst) = IX_OSAL_SWAP_BE_SHARED_LONG(temp); } \ + while(0) + +#define PTR_NPE2VIRT(type,src,ptrDst) \ + do { void *temp; \ + IX_OSAL_ENSURE(sizeof(type) == sizeof(UINT32), "Wrong parameter type"); \ + IX_OSAL_ENSURE(sizeof(src) == sizeof(UINT32), "Wrong parameter type"); \ + IX_OSAL_ENSURE(sizeof(ptrDst) == sizeof(UINT32), "Wrong parameter type"); \ + temp = (void *)IX_OSAL_SWAP_BE_SHARED_LONG(src); \ + (ptrDst) = (type)IX_OSAL_MMU_PHYS_TO_VIRT(temp); } \ + while(0) +#endif + +/** + * + * @brief Mbuf payload pointer conversion macros : Wince has its own + * method to convert the buffer pointers + */ +#if defined(__wince) && !defined(IN_KERNEL) +#define DATAPTR_VIRT2NPE(ptrSrc,dst) \ + do { UINT32 temp; \ + temp = (UINT32)IX_OSAL_MBUF_DATA_VIRTUAL_TO_PHYSICAL_TRANSLATION(ptrSrc); \ + (dst) = IX_OSAL_SWAP_BE_SHARED_LONG(temp); } \ + while(0) + +#else +#define DATAPTR_VIRT2NPE(ptrSrc,dst) PTR_VIRT2NPE(IX_OSAL_MBUF_MDATA(ptrSrc),dst) +#endif + + +/* Flush the shared part of the mbuf header */ +#define IX_ETHACC_NE_CACHE_FLUSH(mbufPtr) \ + do { \ + IX_OSAL_CACHE_FLUSH(IX_ETHACC_NE_SHARED(mbufPtr), \ + sizeof(IxEthAccNe)); \ + } \ + while(0) + +/* Invalidate the shared part of the mbuf header */ +#define IX_ETHACC_NE_CACHE_INVALIDATE(mbufPtr) \ + do { \ + IX_OSAL_CACHE_INVALIDATE(IX_ETHACC_NE_SHARED(mbufPtr), \ + sizeof(IxEthAccNe)); \ + } \ + while(0) + +/* Preload one cache line (shared mbuf headers are aligned + * and their size is 1 cache line) + * + * IX_OSAL_CACHED is defined when the mbuf headers are + * allocated from cached memory. + * + * Other processor on emulation environment may not implement + * preload function + */ +#ifdef IX_OSAL_CACHED + #if (CPU!=SIMSPARCSOLARIS) && !defined (__wince) + #define IX_ACC_DATA_CACHE_PRELOAD(ptr) \ + do { /* preload a cache line (Xscale Processor) */ \ + __asm__ (" pld [%0]\n": : "r" (ptr)); \ + } \ + while(0) + #else + /* preload not implemented on different processor */ + #define IX_ACC_DATA_CACHE_PRELOAD(mbufPtr) \ + do { /* nothing */ } while (0) + #endif +#else + /* preload not needed if cache is not enabled */ + #define IX_ACC_DATA_CACHE_PRELOAD(mbufPtr) \ + do { /* nothing */ } while (0) +#endif + +/** + * + * @brief function to retrieve the correct pointer from + * a queue entry posted by the NPE + * + * @param qEntry : entry from qmgr queue + * mask : applicable mask for this queue + * (4 most significant bits are used for additional informations) + * + * @return IX_OSAL_MBUF * pointer to mbuf header + * + * @internal + */ +PRIVATE IX_OSAL_MBUF * +ixEthAccEntryFromQConvert(UINT32 qEntry, UINT32 mask) +{ + IX_OSAL_MBUF *mbufPtr; + + if (qEntry != 0) + { + /* mask NPE bits (e.g. priority, port ...) */ + qEntry &= mask; + +#if IX_ACC_DRAM_PHYS_OFFSET != 0 + /* restore the original address pointer (if PHYS_OFFSET is not 0) */ + qEntry |= (IX_ACC_DRAM_PHYS_OFFSET & ~IX_ETHNPE_QM_Q_RXENET_ADDR_MASK); +#endif + /* get the mbuf pointer address from the npe-shared address */ + qEntry -= offsetof(IX_OSAL_MBUF,ix_ne); + + /* phys2virt mbuf */ + mbufPtr = (IX_OSAL_MBUF *)IX_OSAL_MMU_PHYS_TO_VIRT(qEntry); + + /* preload the cacheline shared with NPE */ + IX_ACC_DATA_CACHE_PRELOAD(IX_ETHACC_NE_SHARED(mbufPtr)); + + /* preload the cacheline used by xscale */ + IX_ACC_DATA_CACHE_PRELOAD(mbufPtr); + } + else + { + mbufPtr = NULL; + } + + return mbufPtr; +} + +/* Convert the mbuf header for NPE transmission */ +PRIVATE UINT32 +ixEthAccMbufTxQPrepare(IX_OSAL_MBUF *mbuf) +{ + UINT32 qbuf; + UINT32 len; + + /* endianess swap for tci and flags + note: this is done only once, even for chained buffers */ + IX_ETHACC_NE_FLAGS(mbuf) = IX_OSAL_SWAP_BE_SHARED_SHORT(IX_ETHACC_NE_FLAGS(mbuf)); + IX_ETHACC_NE_VLANTCI(mbuf) = IX_OSAL_SWAP_BE_SHARED_SHORT(IX_ETHACC_NE_VLANTCI(mbuf)); + + /* test for unchained mbufs */ + if (IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbuf) == NULL) + { + /* "best case" scenario : unchained mbufs */ + IX_ETH_ACC_STATS_INC(ixEthAccDataStats.unchainedTxMBufs); + + /* payload pointer conversion */ + DATAPTR_VIRT2NPE(mbuf, IX_ETHACC_NE_DATA(mbuf)); + + /* unchained mbufs : the frame length is the mbuf length + * and the 2 identical lengths are stored in the same + * word. + */ + len = IX_OSAL_MBUF_MLEN(mbuf); + + /* set the length in both length and pktLen 16-bits fields */ + len |= (len << IX_ETHNPE_ACC_LENGTH_OFFSET); + IX_ETHACC_NE_LEN(mbuf) = IX_OSAL_SWAP_BE_SHARED_LONG(len); + + /* unchained mbufs : next contains 0 */ + IX_ETHACC_NE_NEXT(mbuf) = 0; + + /* flush shared header after all address conversions */ + IX_ETHACC_NE_CACHE_FLUSH(mbuf); + } + else + { + /* chained mbufs */ + IX_OSAL_MBUF *ptr = mbuf; + IX_OSAL_MBUF *nextPtr; + UINT32 frmLen; + + /* get the frame length from the header of the first buffer */ + frmLen = IX_OSAL_MBUF_PKT_LEN(mbuf); + + do + { + IX_ETH_ACC_STATS_INC(ixEthAccDataStats.chainedTxMBufs); + + /* payload pointer */ + DATAPTR_VIRT2NPE(ptr,IX_ETHACC_NE_DATA(ptr)); + /* Buffer length and frame length are stored in the same word */ + len = IX_OSAL_MBUF_MLEN(ptr); + len = frmLen | (len << IX_ETHNPE_ACC_LENGTH_OFFSET); + IX_ETHACC_NE_LEN(ptr) = IX_OSAL_SWAP_BE_SHARED_LONG(len); + + /* get the virtual next chain pointer */ + nextPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(ptr); + if (nextPtr != NULL) + { + /* shared pointer of the next buffer is chained */ + PTR_VIRT2NPE(IX_ETHACC_NE_SHARED(nextPtr), + IX_ETHACC_NE_NEXT(ptr)); + } + else + { + IX_ETHACC_NE_NEXT(ptr) = 0; + } + + /* flush shared header after all address conversions */ + IX_ETHACC_NE_CACHE_FLUSH(ptr); + + /* move to next buffer */ + ptr = nextPtr; + + /* the frame length field is set only in the first buffer + * and is zeroed in the next buffers + */ + frmLen = 0; + } + while(ptr != NULL); + + } + + /* virt2phys mbuf itself */ + qbuf = (UINT32)IX_OSAL_MMU_VIRT_TO_PHYS( + IX_ETHACC_NE_SHARED(mbuf)); + + /* Ensure the bits which are reserved to exchange information with + * the NPE are cleared + * + * If the mbuf address is not correctly aligned, or from an + * incompatible memory range, there is no point to continue + */ + IX_OSAL_ENSURE(((qbuf & ~IX_ETHNPE_QM_Q_TXENET_ADDR_MASK) == 0), + "Invalid address range"); + + return qbuf; +} + +/* Convert the mbuf header for NPE reception */ +PRIVATE UINT32 +ixEthAccMbufRxQPrepare(IX_OSAL_MBUF *mbuf) +{ + UINT32 len; + UINT32 qbuf; + + if (IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbuf) == NULL) + { + /* "best case" scenario : unchained mbufs */ + IX_ETH_ACC_STATS_INC(ixEthAccDataStats.unchainedRxFreeMBufs); + + /* unchained mbufs : payload pointer */ + DATAPTR_VIRT2NPE(mbuf, IX_ETHACC_NE_DATA(mbuf)); + + /* unchained mbufs : set the buffer length + * and the frame length field is zeroed + */ + len = (IX_OSAL_MBUF_MLEN(mbuf) << IX_ETHNPE_ACC_LENGTH_OFFSET); + IX_ETHACC_NE_LEN(mbuf) = IX_OSAL_SWAP_BE_SHARED_LONG(len); + + /* unchained mbufs : next pointer is null */ + IX_ETHACC_NE_NEXT(mbuf) = 0; + + /* flush shared header after all address conversions */ + IX_ETHACC_NE_CACHE_FLUSH(mbuf); + + /* remove shared header cache line */ + IX_ETHACC_NE_CACHE_INVALIDATE(mbuf); + } + else + { + /* chained mbufs */ + IX_OSAL_MBUF *ptr = mbuf; + IX_OSAL_MBUF *nextPtr; + + do + { + /* chained mbufs */ + IX_ETH_ACC_STATS_INC(ixEthAccDataStats.chainedRxFreeMBufs); + + /* we must save virtual next chain pointer */ + nextPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(ptr); + + if (nextPtr != NULL) + { + /* chaining pointer for NPE */ + PTR_VIRT2NPE(IX_ETHACC_NE_SHARED(nextPtr), + IX_ETHACC_NE_NEXT(ptr)); + } + else + { + IX_ETHACC_NE_NEXT(ptr) = 0; + } + + /* payload pointer */ + DATAPTR_VIRT2NPE(ptr,IX_ETHACC_NE_DATA(ptr)); + + /* buffer length */ + len = (IX_OSAL_MBUF_MLEN(ptr) << IX_ETHNPE_ACC_LENGTH_OFFSET); + IX_ETHACC_NE_LEN(ptr) = IX_OSAL_SWAP_BE_SHARED_LONG(len); + + /* flush shared header after all address conversions */ + IX_ETHACC_NE_CACHE_FLUSH(ptr); + + /* remove shared header cache line */ + IX_ETHACC_NE_CACHE_INVALIDATE(ptr); + + /* next mbuf in the chain */ + ptr = nextPtr; + } + while(ptr != NULL); + } + + /* virt2phys mbuf itself */ + qbuf = (UINT32)IX_OSAL_MMU_VIRT_TO_PHYS( + IX_ETHACC_NE_SHARED(mbuf)); + + /* Ensure the bits which are reserved to exchange information with + * the NPE are cleared + * + * If the mbuf address is not correctly aligned, or from an + * incompatible memory range, there is no point to continue + */ + IX_OSAL_ENSURE(((qbuf & ~IX_ETHNPE_QM_Q_RXENET_ADDR_MASK) == 0), + "Invalid address range"); + + return qbuf; +} + +/* Convert the mbuf header after NPE transmission + * Since there is nothing changed by the NPE, there is no need + * to process anything but the update of internal stats + * when they are enabled +*/ +PRIVATE void +ixEthAccMbufFromTxQ(IX_OSAL_MBUF *mbuf) +{ +#ifndef NDEBUG + /* test for unchained mbufs */ + if (IX_ETHACC_NE_NEXT(mbuf) == 0) + { + /* unchained mbufs : update the stats */ + IX_ETH_ACC_STATS_INC(ixEthAccDataStats.unchainedTxDoneMBufs); + } + else + { + /* chained mbufs : walk the chain and update the stats */ + IX_OSAL_MBUF *ptr = mbuf; + + do + { + IX_ETH_ACC_STATS_INC(ixEthAccDataStats.chainedTxDoneMBufs); + ptr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(ptr); + } + while (ptr != NULL); + } +#endif +} + +/* Convert the mbuf header after NPE reception */ +PRIVATE void +ixEthAccMbufFromRxQ(IX_OSAL_MBUF *mbuf) +{ + UINT32 len; + + /* endianess swap for tci and flags + note: this is done only once, even for chained buffers */ + IX_ETHACC_NE_FLAGS(mbuf) = IX_OSAL_SWAP_BE_SHARED_SHORT(IX_ETHACC_NE_FLAGS(mbuf)); + IX_ETHACC_NE_VLANTCI(mbuf) = IX_OSAL_SWAP_BE_SHARED_SHORT(IX_ETHACC_NE_VLANTCI(mbuf)); + + /* test for unchained mbufs */ + if (IX_ETHACC_NE_NEXT(mbuf) == 0) + { + /* unchained mbufs */ + IX_ETH_ACC_STATS_INC(ixEthAccDataStats.unchainedRxMBufs); + + /* get the frame length. it is the same than the buffer length */ + len = IX_OSAL_SWAP_BE_SHARED_LONG(IX_ETHACC_NE_LEN(mbuf)); + len &= IX_ETHNPE_ACC_PKTLENGTH_MASK; + IX_OSAL_MBUF_PKT_LEN(mbuf) = IX_OSAL_MBUF_MLEN(mbuf) = len; + + /* clears the next packet field */ + IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbuf) = NULL; + } + else + { + IX_OSAL_MBUF *ptr = mbuf; + IX_OSAL_MBUF *nextPtr; + UINT32 frmLen; + + /* convert the frame length */ + frmLen = IX_OSAL_SWAP_BE_SHARED_LONG(IX_ETHACC_NE_LEN(mbuf)); + IX_OSAL_MBUF_PKT_LEN(mbuf) = (frmLen & IX_ETHNPE_ACC_PKTLENGTH_MASK); + + /* chained mbufs */ + do + { + IX_ETH_ACC_STATS_INC(ixEthAccDataStats.chainedRxMBufs); + + /* convert the length */ + len = IX_OSAL_SWAP_BE_SHARED_LONG(IX_ETHACC_NE_LEN(ptr)); + IX_OSAL_MBUF_MLEN(ptr) = (len >> IX_ETHNPE_ACC_LENGTH_OFFSET); + + /* get the next pointer */ + PTR_NPE2VIRT(IX_OSAL_MBUF *,IX_ETHACC_NE_NEXT(ptr), nextPtr); + if (nextPtr != NULL) + { + nextPtr = (IX_OSAL_MBUF *)((UINT8 *)nextPtr - offsetof(IX_OSAL_MBUF,ix_ne)); + } + /* set the next pointer */ + IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(ptr) = nextPtr; + + /* move to the next buffer */ + ptr = nextPtr; + } + while (ptr != NULL); + } +} + +/* write to qmgr if possible and report an overflow if not possible + * Use a fast lock to protect the queue write. + * This way, the tx feature is reentrant. + */ +PRIVATE IX_STATUS +ixEthAccQmgrLockTxWrite(IxEthAccPortId portId, UINT32 qBuffer) +{ + IX_STATUS qStatus; + if (ixOsalFastMutexTryLock(&txWriteMutex[portId]) == IX_SUCCESS) + { + qStatus = ixQMgrQWrite( + IX_ETH_ACC_PORT_TO_TX_Q_ID(portId), + &qBuffer); +#ifndef NDEBUG + if (qStatus != IX_SUCCESS) + { + TX_STATS_INC(portId, txOverflow); + } +#endif + ixOsalFastMutexUnlock(&txWriteMutex[portId]); + } + else + { + TX_STATS_INC(portId, txLock); + qStatus = IX_QMGR_Q_OVERFLOW; + } + return qStatus; +} + +/* write to qmgr if possible and report an overflow if not possible + * Use a fast lock to protect the queue write. + * This way, the Rx feature is reentrant. + */ +PRIVATE IX_STATUS +ixEthAccQmgrLockRxWrite(IxEthAccPortId portId, UINT32 qBuffer) +{ + IX_STATUS qStatus; + if (ixOsalFastMutexTryLock(&rxWriteMutex[portId]) == IX_SUCCESS) + { + qStatus = ixQMgrQWrite( + IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(portId), + &qBuffer); +#ifndef NDEBUG + if (qStatus != IX_SUCCESS) + { + RX_STATS_INC(portId, rxFreeOverflow); + } +#endif + ixOsalFastMutexUnlock(&rxWriteMutex[portId]); + } + else + { + RX_STATS_INC(portId, rxFreeLock); + qStatus = IX_QMGR_Q_OVERFLOW; + } + return qStatus; +} + +/* + * Set the priority and write to a qmgr queue. + */ +PRIVATE IX_STATUS +ixEthAccQmgrTxWrite(IxEthAccPortId portId, UINT32 qBuffer, UINT32 priority) +{ + /* fill the priority field */ + qBuffer |= (priority << IX_ETHNPE_QM_Q_FIELD_PRIOR_R); + + return ixEthAccQmgrLockTxWrite(portId, qBuffer); +} + +/** + * + * @brief This function will discover the highest priority S/W Tx Q that + * has entries in it + * + * @param portId - (in) the id of the port whose S/W Tx queues are to be searched + * priorityPtr - (out) the priority of the highest priority occupied q will be written + * here + * + * @return IX_ETH_ACC_SUCCESS if an occupied Q is found + * IX_ETH_ACC_FAIL if no Q has entries + * + * @internal + */ +PRIVATE IxEthAccStatus +ixEthAccTxSwQHighestPriorityGet(IxEthAccPortId portId, + IxEthAccTxPriority *priorityPtr) +{ + if (ixEthAccPortData[portId].ixEthAccTxData.schDiscipline + == FIFO_NO_PRIORITY) + { + if(IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(ixEthAccPortData[portId]. + ixEthAccTxData.txQ[IX_ETH_ACC_TX_DEFAULT_PRIORITY])) + { + return IX_ETH_ACC_FAIL; + } + else + { + *priorityPtr = IX_ETH_ACC_TX_DEFAULT_PRIORITY; + TX_STATS_INC(portId,txPriority[*priorityPtr]); + return IX_ETH_ACC_SUCCESS; + } + } + else + { + IxEthAccTxPriority highestPriority = IX_ETH_ACC_TX_PRIORITY_7; + while(1) + { + if(!IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(ixEthAccPortData[portId]. + ixEthAccTxData.txQ[highestPriority])) + { + + *priorityPtr = highestPriority; + TX_STATS_INC(portId,txPriority[highestPriority]); + return IX_ETH_ACC_SUCCESS; + + } + if (highestPriority == IX_ETH_ACC_TX_PRIORITY_0) + { + return IX_ETH_ACC_FAIL; + } + highestPriority--; + } + } +} + +/** + * + * @brief This function will take a buffer from a TX S/W Q and attempt + * to add it to the relevant TX H/W Q + * + * @param portId - the port whose TX queue is to be written to + * priority - identifies the queue from which the entry is to be read + * + * @internal + */ +PRIVATE IxEthAccStatus +ixEthAccTxFromSwQ(IxEthAccPortId portId, + IxEthAccTxPriority priority) +{ + IX_OSAL_MBUF *mbuf; + IX_STATUS qStatus; + + IX_OSAL_ENSURE((UINT32)priority <= (UINT32)7, "Invalid priority"); + + IX_ETH_ACC_DATAPLANE_REMOVE_MBUF_FROM_Q_HEAD( + ixEthAccPortData[portId].ixEthAccTxData.txQ[priority], + mbuf); + + if (mbuf != NULL) + { + /* + * Add the Tx buffer to the H/W Tx Q + * We do not need to flush here as it is already done + * in TxFrameSubmit(). + */ + qStatus = ixEthAccQmgrTxWrite( + portId, + IX_OSAL_MMU_VIRT_TO_PHYS((UINT32)IX_ETHACC_NE_SHARED(mbuf)), + priority); + + if (qStatus == IX_SUCCESS) + { + TX_STATS_INC(portId,txFromSwQOK); + return IX_SUCCESS; + } + else if (qStatus == IX_QMGR_Q_OVERFLOW) + { + /* + * H/W Q overflow, need to save the buffer + * back on the s/w Q. + * we must put it back on the head of the q to avoid + * reordering packet tx + */ + TX_STATS_INC(portId,txFromSwQDelayed); + IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD( + ixEthAccPortData[portId].ixEthAccTxData.txQ[priority], + mbuf); + + /*enable Q notification*/ + qStatus = ixQMgrNotificationEnable( + IX_ETH_ACC_PORT_TO_TX_Q_ID(portId), + IX_ETH_ACC_PORT_TO_TX_Q_SOURCE(portId)); + + if (qStatus != IX_SUCCESS && qStatus != IX_QMGR_WARNING) + { + TX_INC(portId,txUnexpectedError); + IX_ETH_ACC_FATAL_LOG( + "ixEthAccTxFromSwQ:Unexpected Error: %u\n", + qStatus, 0, 0, 0, 0, 0); + } + } + else + { + TX_INC(portId,txUnexpectedError); + + /* recovery attempt */ + IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD( + ixEthAccPortData[portId].ixEthAccTxData.txQ[priority], + mbuf); + + IX_ETH_ACC_FATAL_LOG( + "ixEthAccTxFromSwQ:Error: unexpected QM status 0x%08X\n", + qStatus, 0, 0, 0, 0, 0); + } + } + else + { + /* sw queue is empty */ + } + return IX_ETH_ACC_FAIL; +} + +/** + * + * @brief This function will take a buffer from a RXfree S/W Q and attempt + * to add it to the relevant RxFree H/W Q + * + * @param portId - the port whose RXFree queue is to be written to + * + * @internal + */ +PRIVATE IxEthAccStatus +ixEthAccRxFreeFromSwQ(IxEthAccPortId portId) +{ + IX_OSAL_MBUF *mbuf; + IX_STATUS qStatus = IX_SUCCESS; + + IX_ETH_ACC_DATAPLANE_REMOVE_MBUF_FROM_Q_HEAD( + ixEthAccPortData[portId].ixEthAccRxData.freeBufferList, + mbuf); + if (mbuf != NULL) + { + /* + * Add The Rx Buffer to the H/W Free buffer Q if possible + */ + qStatus = ixEthAccQmgrLockRxWrite(portId, + IX_OSAL_MMU_VIRT_TO_PHYS( + (UINT32)IX_ETHACC_NE_SHARED(mbuf))); + + if (qStatus == IX_SUCCESS) + { + RX_STATS_INC(portId,rxFreeRepFromSwQOK); + /* + * Buffer added to h/w Q. + */ + return IX_SUCCESS; + } + else if (qStatus == IX_QMGR_Q_OVERFLOW) + { + /* + * H/W Q overflow, need to save the buffer back on the s/w Q. + */ + RX_STATS_INC(portId,rxFreeRepFromSwQDelayed); + + IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD( + ixEthAccPortData[portId].ixEthAccRxData.freeBufferList, + mbuf); + } + else + { + /* unexpected qmgr error */ + RX_INC(portId,rxUnexpectedError); + + IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD( + ixEthAccPortData[portId].ixEthAccRxData.freeBufferList, + mbuf); + + IX_ETH_ACC_FATAL_LOG("IxEthAccRxFreeFromSwQ:Error: unexpected QM status 0x%08X\n", + qStatus, 0, 0, 0, 0, 0); + } + } + else + { + /* sw queue is empty */ + } + return IX_ETH_ACC_FAIL; +} + + +IX_ETH_ACC_PUBLIC +IxEthAccStatus ixEthAccInitDataPlane() +{ + UINT32 portId; + + /* + * Initialize the service and register callback to other services. + */ + + IX_ETH_ACC_MEMSET(&ixEthAccDataStats, + 0, + sizeof(ixEthAccDataStats)); + + for(portId=0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) + { + ixOsalFastMutexInit(&txWriteMutex[portId]); + ixOsalFastMutexInit(&rxWriteMutex[portId]); + + IX_ETH_ACC_MEMSET(&ixEthAccPortData[portId], + 0, + sizeof(ixEthAccPortData[portId])); + + ixEthAccPortData[portId].ixEthAccTxData.schDiscipline = FIFO_NO_PRIORITY; + } + + return (IX_ETH_ACC_SUCCESS); +} + + +IX_ETH_ACC_PUBLIC +IxEthAccStatus ixEthAccPortTxDoneCallbackRegister(IxEthAccPortId portId, + IxEthAccPortTxDoneCallback + txCallbackFn, + UINT32 callbackTag) +{ + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + if (!IX_ETH_ACC_IS_PORT_VALID(portId)) + { + return (IX_ETH_ACC_INVALID_PORT); + } + +/* HACK: removing this code to enable NPE-A preliminary testing + * if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + * { + * IX_ETH_ACC_WARNING_LOG("ixEthAccPortTxDoneCallbackRegister: Unavailable Eth %d: Cannot register TxDone Callback.\n",(INT32)portId,0,0,0,0,0); + * return IX_ETH_ACC_SUCCESS ; + * } + */ + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + if (txCallbackFn == 0) + /* Check for null function pointer here. */ + { + return (IX_ETH_ACC_INVALID_ARG); + } + ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn = txCallbackFn; + ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag = callbackTag; + return (IX_ETH_ACC_SUCCESS); +} + + +IX_ETH_ACC_PUBLIC +IxEthAccStatus ixEthAccPortRxCallbackRegister(IxEthAccPortId portId, + IxEthAccPortRxCallback + rxCallbackFn, + UINT32 callbackTag) +{ + IxEthAccPortId port; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + 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("ixEthAccPortRxCallbackRegister: Unavailable Eth %d: Cannot register Rx Callback.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + /* Check for null function pointer here. */ + if (rxCallbackFn == NULL) + { + return (IX_ETH_ACC_INVALID_ARG); + } + + /* Check the user is not changing the callback type + * when the port is enabled. + */ + if (ixEthAccMacState[portId].portDisableState == ACTIVE) + { + for (port = 0; port < IX_ETH_ACC_NUMBER_OF_PORTS; port++) + { + if ((ixEthAccMacState[port].portDisableState == ACTIVE) + && (ixEthAccPortData[port].ixEthAccRxData.rxMultiBufferCallbackInUse == TRUE)) + { + /* one of the active ports has a different rx callback type. + * Changing the callback type when the port is enabled + * is not safe + */ + return (IX_ETH_ACC_INVALID_ARG); + } + } + } + + /* update the callback pointer : this is done before + * registering the new qmgr callback + */ + ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn = rxCallbackFn; + ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag = callbackTag; + + /* update the qmgr callback for rx queues */ + if (ixEthAccQMgrRxCallbacksRegister(ixEthRxFrameQMCallback) + != IX_ETH_ACC_SUCCESS) + { + /* unexpected qmgr error */ + IX_ETH_ACC_FATAL_LOG("ixEthAccPortRxCallbackRegister: unexpected QMgr error, " \ + "could not register Rx single-buffer callback\n", 0, 0, 0, 0, 0, 0); + + RX_INC(portId,rxUnexpectedError); + return (IX_ETH_ACC_INVALID_ARG); + } + + ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackInUse = FALSE; + + return (IX_ETH_ACC_SUCCESS); +} + +IX_ETH_ACC_PUBLIC +IxEthAccStatus ixEthAccPortMultiBufferRxCallbackRegister( + IxEthAccPortId portId, + IxEthAccPortMultiBufferRxCallback + rxCallbackFn, + UINT32 callbackTag) +{ + IxEthAccPortId port; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + 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("ixEthAccPortMultiBufferRxCallbackRegister: Unavailable Eth %d: Cannot register Rx Callback.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + /* Check for null function pointer here. */ + if (rxCallbackFn == NULL) + { + return (IX_ETH_ACC_INVALID_ARG); + } + + /* Check the user is not changing the callback type + * when the port is enabled. + */ + if (ixEthAccMacState[portId].portDisableState == ACTIVE) + { + for (port = 0; port < IX_ETH_ACC_NUMBER_OF_PORTS; port++) + { + if ((ixEthAccMacState[port].portDisableState == ACTIVE) + && (ixEthAccPortData[port].ixEthAccRxData.rxMultiBufferCallbackInUse == FALSE)) + { + /* one of the active ports has a different rx callback type. + * Changing the callback type when the port is enabled + * is not safe + */ + return (IX_ETH_ACC_INVALID_ARG); + } + } + } + + /* update the callback pointer : this is done before + * registering the new qmgr callback + */ + ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn = rxCallbackFn; + ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag = callbackTag; + + /* update the qmgr callback for rx queues */ + if (ixEthAccQMgrRxCallbacksRegister(ixEthRxMultiBufferQMCallback) + != IX_ETH_ACC_SUCCESS) + { + /* unexpected qmgr error */ + RX_INC(portId,rxUnexpectedError); + + IX_ETH_ACC_FATAL_LOG("ixEthAccPortMultiBufferRxCallbackRegister: unexpected QMgr error, " \ + "could not register Rx multi-buffer callback\n", 0, 0, 0, 0, 0, 0); + + return (IX_ETH_ACC_INVALID_ARG); + } + + ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackInUse = TRUE; + + return (IX_ETH_ACC_SUCCESS); +} + +IX_ETH_ACC_PUBLIC +IxEthAccStatus ixEthAccPortTxFrameSubmit(IxEthAccPortId portId, + IX_OSAL_MBUF *buffer, + IxEthAccTxPriority priority) +{ + IX_STATUS qStatus = IX_SUCCESS; + UINT32 qBuffer; + IxEthAccTxPriority highestPriority; + IxQMgrQStatus txQStatus; + +#ifndef NDEBUG + if (buffer == NULL) + { + return (IX_ETH_ACC_FAIL); + } + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + if (!IX_ETH_ACC_IS_PORT_VALID(portId)) + { + return (IX_ETH_ACC_INVALID_PORT); + } + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_FATAL_LOG("ixEthAccPortTxFrameSubmit: Unavailable Eth %d: Cannot submit Tx Frame.\n", + (INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_PORT_UNINITIALIZED ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + if ((UINT32)priority > (UINT32)IX_ETH_ACC_TX_PRIORITY_7) + { + return (IX_ETH_ACC_INVALID_ARG); + } +#endif + + /* + * Need to Flush the MBUF and its contents (data) as it may be + * read from the NPE. Convert virtual addresses to physical addresses also. + */ + qBuffer = ixEthAccMbufTxQPrepare(buffer); + + /* + * If no fifo priority set on Xscale ... + */ + if (ixEthAccPortData[portId].ixEthAccTxData.schDiscipline == + FIFO_NO_PRIORITY) + { + /* + * Add The Tx Buffer to the H/W Tx Q if possible + * (the priority is passed to the NPE, because + * the NPE is able to reorder the frames + * before transmission to the underlying hardware) + */ + qStatus = ixEthAccQmgrTxWrite(portId, + qBuffer, + IX_ETH_ACC_TX_DEFAULT_PRIORITY); + + if (qStatus == IX_SUCCESS) + { + TX_STATS_INC(portId,txQOK); + + /* + * "best case" scenario : Buffer added to h/w Q. + */ + return (IX_SUCCESS); + } + else if (qStatus == IX_QMGR_Q_OVERFLOW) + { + /* + * We were unable to write the buffer to the + * appropriate H/W Q, Save it in the sw Q. + * (use the default priority queue regardless of + * input parameter) + */ + priority = IX_ETH_ACC_TX_DEFAULT_PRIORITY; + } + else + { + /* unexpected qmgr error */ + TX_INC(portId,txUnexpectedError); + IX_ETH_ACC_FATAL_LOG( + "ixEthAccPortTxFrameSubmit:Error: qStatus = %u\n", + (UINT32)qStatus, 0, 0, 0, 0, 0); + return (IX_ETH_ACC_FAIL); + } + } + else if (ixEthAccPortData[portId].ixEthAccTxData.schDiscipline == + FIFO_PRIORITY) + { + + /* + * For priority transmission, put the frame directly on the H/W queue + * if the H/W queue is empty, otherwise, put it in a S/W Q + */ + ixQMgrQStatusGet(IX_ETH_ACC_PORT_TO_TX_Q_ID(portId), &txQStatus); + if((txQStatus & IX_QMGR_Q_STATUS_E_BIT_MASK) != 0) + { + /*The tx queue is empty, check whether there are buffers on the s/w queues*/ + if(ixEthAccTxSwQHighestPriorityGet(portId, &highestPriority) + !=IX_ETH_ACC_FAIL) + { + /*there are buffers on the s/w queues, submit them*/ + ixEthAccTxFromSwQ(portId, highestPriority); + + /* the queue was empty, 1 buffer is already supplied + * but is likely to be immediately transmitted and the + * hw queue is likely to be empty again, so submit + * more from the sw queues + */ + if(ixEthAccTxSwQHighestPriorityGet(portId, &highestPriority) + !=IX_ETH_ACC_FAIL) + { + ixEthAccTxFromSwQ(portId, highestPriority); + /* + * and force the buffer supplied to be placed + * on a priority queue + */ + qStatus = IX_QMGR_Q_OVERFLOW; + } + else + { + /*there are no buffers in the s/w queues, submit directly*/ + qStatus = ixEthAccQmgrTxWrite(portId, qBuffer, priority); + } + } + else + { + /*there are no buffers in the s/w queues, submit directly*/ + qStatus = ixEthAccQmgrTxWrite(portId, qBuffer, priority); + } + } + else + { + qStatus = IX_QMGR_Q_OVERFLOW; + } + } + else + { + TX_INC(portId,txUnexpectedError); + IX_ETH_ACC_FATAL_LOG( + "ixEthAccPortTxFrameSubmit:Error: wrong schedule discipline setup\n", + 0, 0, 0, 0, 0, 0); + return (IX_ETH_ACC_FAIL); + } + + if(qStatus == IX_SUCCESS ) + { + TX_STATS_INC(portId,txQOK); + return IX_ETH_ACC_SUCCESS; + } + else if(qStatus == IX_QMGR_Q_OVERFLOW) + { + TX_STATS_INC(portId,txQDelayed); + /* + * We were unable to write the buffer to the + * appropriate H/W Q, Save it in a s/w Q. + */ + IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_TAIL( + ixEthAccPortData[portId]. + ixEthAccTxData.txQ[priority], + buffer); + + qStatus = ixQMgrNotificationEnable( + IX_ETH_ACC_PORT_TO_TX_Q_ID(portId), + IX_ETH_ACC_PORT_TO_TX_Q_SOURCE(portId)); + + if (qStatus != IX_SUCCESS) + { + if (qStatus == IX_QMGR_WARNING) + { + /* notification is enabled for a queue + * which is already empty (the condition is already met) + * and there will be no more queue event to drain the sw queue + */ + TX_STATS_INC(portId,txLateNotificationEnabled); + + /* pull a buffer from the sw queue */ + if(ixEthAccTxSwQHighestPriorityGet(portId, &highestPriority) + !=IX_ETH_ACC_FAIL) + { + /*there are buffers on the s/w queues, submit from them*/ + ixEthAccTxFromSwQ(portId, highestPriority); + } + } + else + { + TX_INC(portId,txUnexpectedError); + IX_ETH_ACC_FATAL_LOG( + "ixEthAccPortTxFrameSubmit: unexpected Error: %u\n", + qStatus, 0, 0, 0, 0, 0); + } + } + } + else + { + TX_INC(portId,txUnexpectedError); + IX_ETH_ACC_FATAL_LOG( + "ixEthAccPortTxFrameSubmit: unexpected Error: %u\n", + qStatus, 0, 0, 0, 0, 0); + return (IX_ETH_ACC_FAIL); + } + + return (IX_ETH_ACC_SUCCESS); +} + + +/** + * + * @brief replenish: convert a chain of mbufs to the format + * expected by the NPE + * + */ + +IX_ETH_ACC_PUBLIC +IxEthAccStatus ixEthAccPortRxFreeReplenish(IxEthAccPortId portId, + IX_OSAL_MBUF *buffer) +{ + IX_STATUS qStatus = IX_SUCCESS; + UINT32 qBuffer; + + /* + * Check buffer is valid. + */ + +#ifndef NDEBUG + /* check parameter value */ + if (buffer == 0) + { + return (IX_ETH_ACC_FAIL); + } + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + if (!IX_ETH_ACC_IS_PORT_VALID(portId)) + { + return (IX_ETH_ACC_INVALID_PORT); + } + + /* check initialisation is done */ + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_FATAL_LOG(" ixEthAccPortRxFreeReplenish: Unavailable Eth %d: Cannot replenish Rx Free Q.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_PORT_UNINITIALIZED ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + /* check boundaries and constraints */ + if (IX_OSAL_MBUF_MLEN(buffer) < IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN) + { + return (IX_ETH_ACC_FAIL); + } +#endif + + qBuffer = ixEthAccMbufRxQPrepare(buffer); + + /* + * Add The Rx Buffer to the H/W Free buffer Q if possible + */ + qStatus = ixEthAccQmgrLockRxWrite(portId, qBuffer); + + if (qStatus == IX_SUCCESS) + { + RX_STATS_INC(portId,rxFreeRepOK); + /* + * Buffer added to h/w Q. + */ + return (IX_SUCCESS); + } + else if (qStatus == IX_QMGR_Q_OVERFLOW) + { + RX_STATS_INC(portId,rxFreeRepDelayed); + /* + * We were unable to write the buffer to the approprate H/W Q, + * Save it in a s/w Q. + */ + IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_TAIL( + ixEthAccPortData[portId].ixEthAccRxData.freeBufferList, + buffer); + + qStatus = ixQMgrNotificationEnable( + IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(portId), + IX_ETH_ACC_PORT_TO_RX_FREE_Q_SOURCE(portId)); + + if (qStatus != IX_SUCCESS) + { + if (qStatus == IX_QMGR_WARNING) + { + /* notification is enabled for a queue + * which is already empty (the condition is already met) + * and there will be no more queue event to drain the sw queue + * move an entry from the sw queue to the hw queue */ + RX_STATS_INC(portId,rxFreeLateNotificationEnabled); + ixEthAccRxFreeFromSwQ(portId); + } + else + { + RX_INC(portId,rxUnexpectedError); + IX_ETH_ACC_FATAL_LOG( + "ixEthAccRxPortFreeReplenish:Error: %u\n", + qStatus, 0, 0, 0, 0, 0); + } + } + } + else + { + RX_INC(portId,rxUnexpectedError); + IX_ETH_ACC_FATAL_LOG( + "ixEthAccRxPortFreeReplenish:Error: qStatus = %u\n", + (UINT32)qStatus, 0, 0, 0, 0, 0); + return(IX_ETH_ACC_FAIL); + } + return (IX_ETH_ACC_SUCCESS); +} + + +IX_ETH_ACC_PUBLIC +IxEthAccStatus ixEthAccTxSchedulingDisciplineSetPriv(IxEthAccPortId portId, + IxEthAccSchedulerDiscipline + sched) +{ + 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("ixEthAccTxSchedulingDisciplineSet: Unavailable Eth %d: Cannot set Tx Scheduling Discipline.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + if (sched != FIFO_PRIORITY && sched != FIFO_NO_PRIORITY) + { + return (IX_ETH_ACC_INVALID_ARG); + } + + ixEthAccPortData[portId].ixEthAccTxData.schDiscipline = sched; + return (IX_ETH_ACC_SUCCESS); +} + +IX_ETH_ACC_PUBLIC +IxEthAccStatus ixEthAccRxSchedulingDisciplineSetPriv(IxEthAccSchedulerDiscipline + sched) +{ + if (sched != FIFO_PRIORITY && sched != FIFO_NO_PRIORITY) + { + return (IX_ETH_ACC_INVALID_ARG); + } + + ixEthAccDataInfo.schDiscipline = sched; + + return (IX_ETH_ACC_SUCCESS); +} + + +/** + * @fn ixEthRxFrameProcess(IxEthAccPortId portId, IX_OSAL_MBUF *mbufPtr) + * + * @brief process incoming frame : + * + * @param @ref IxQMgrCallback IxQMgrMultiBufferCallback + * + * @return none + * + * @internal + * + */ +IX_ETH_ACC_PRIVATE BOOL +ixEthRxFrameProcess(IxEthAccPortId portId, IX_OSAL_MBUF *mbufPtr) +{ + UINT32 flags; + IxEthDBStatus result; + +#ifndef NDEBUG + /* Prudent to at least check the port is within range */ + if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS) + { + ixEthAccDataStats.unexpectedError++; + IX_ETH_ACC_FATAL_LOG( + "ixEthRxFrameProcess: Illegal port: %u\n", + (UINT32)portId, 0, 0, 0, 0, 0); + return FALSE; + } +#endif + + /* convert fields from mbuf header */ + ixEthAccMbufFromRxQ(mbufPtr); + + /* check about any special processing for this frame */ + flags = IX_ETHACC_NE_FLAGS(mbufPtr); + if ((flags & (IX_ETHACC_NE_FILTERMASK | IX_ETHACC_NE_NEWSRCMASK)) == 0) + { + /* "best case" scenario : nothing special to do for this frame */ + return TRUE; + } + +#ifdef CONFIG_IXP425_COMPONENT_ETHDB + /* if a new source MAC address is detected by the NPE, + * update IxEthDB with the portId and the MAC address. + */ + if ((flags & IX_ETHACC_NE_NEWSRCMASK & ixEthAccNewSrcMask) != 0) + { + result = ixEthDBFilteringDynamicEntryProvision(portId, + (IxEthDBMacAddr *) IX_ETHACC_NE_SOURCEMAC(mbufPtr)); + + if (result != IX_ETH_DB_SUCCESS && result != IX_ETH_DB_FEATURE_UNAVAILABLE) + { + if ((ixEthAccMacState[portId].portDisableState == ACTIVE) && (result != IX_ETH_DB_BUSY)) + { + RX_STATS_INC(portId, rxUnexpectedError); + IX_ETH_ACC_FATAL_LOG("ixEthRxFrameProcess: Failed to add source MAC \ + to the Learning/Filtering database\n", 0, 0, 0, 0, 0, 0); + } + else + { + /* we expect this to fail during PortDisable, as EthDB is disabled for + * that port and will refuse to learn new addresses + */ + } + } + else + { + RX_STATS_INC(portId, rxUnlearnedMacAddress); + } + } +#endif + + /* check if this frame should have been filtered + * by the NPE and take the appropriate action + */ + if (((flags & IX_ETHACC_NE_FILTERMASK) != 0) + && (ixEthAccMacState[portId].portDisableState == ACTIVE)) + { + /* If the mbuf was allocated with a small data size, or the current data pointer is not + * within the allocated data area, then the buffer is non-standard and has to be + * replenished with the minimum size only + */ + if( (IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(mbufPtr) < IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN) + || ((UINT8 *)IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(mbufPtr) > IX_OSAL_MBUF_MDATA(mbufPtr)) + || ((UINT8 *)(IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(mbufPtr) + + IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(mbufPtr)) + < IX_OSAL_MBUF_MDATA(mbufPtr)) ) + { + /* set to minimum length */ + IX_OSAL_MBUF_MLEN(mbufPtr) = IX_OSAL_MBUF_PKT_LEN(mbufPtr) = + IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN; + } + else + { + /* restore original length */ + IX_OSAL_MBUF_MLEN(mbufPtr) = IX_OSAL_MBUF_PKT_LEN(mbufPtr) = + ( IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(mbufPtr) - + (IX_OSAL_MBUF_MDATA(mbufPtr) - (UINT8 *)IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(mbufPtr)) ); + } + + /* replenish from here */ + if (ixEthAccPortRxFreeReplenish(portId, mbufPtr) != IX_ETH_ACC_SUCCESS) + { + IX_ETH_ACC_FATAL_LOG("ixEthRxFrameProcess: Failed to replenish with filtered frame\ + on port %d\n", portId, 0, 0, 0, 0, 0); + } + + RX_STATS_INC(portId, rxFiltered); + + /* indicate that frame should not be subjected to further processing */ + return FALSE; + } + + return TRUE; +} + + +/** + * @fn ixEthRxFrameQMCallback + * + * @brief receive callback for Frame receive Q from NPE + * + * Frames are passed one-at-a-time to the user + * + * @param @ref IxQMgrCallback + * + * @return none + * + * @internal + * + * Design note : while processing the entry X, entry X+1 is preloaded + * into memory to reduce the number of stall cycles + * + */ +void ixEthRxFrameQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId) +{ + IX_OSAL_MBUF *mbufPtr; + IX_OSAL_MBUF *nextMbufPtr; + UINT32 qEntry; + UINT32 nextQEntry; + UINT32 *qEntryPtr; + UINT32 portId; + UINT32 destPortId; + UINT32 npeId; + UINT32 rxQReadStatus; + + /* + * Design note : entries are read in a buffer, This buffer contains + * an extra zeroed entry so the loop will + * always terminate on a null entry, whatever the result of Burst read is. + */ + UINT32 rxQEntry[IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK + 1]; + + /* + * Indication of the number of times the callback is used. + */ + IX_ETH_ACC_STATS_INC(ixEthAccDataStats.rxCallbackCounter); + + do + { + /* + * Indication of the number of times the queue is drained + */ + IX_ETH_ACC_STATS_INC(ixEthAccDataStats.rxCallbackBurstRead); + + /* ensure the last entry of the array contains a zeroed value */ + qEntryPtr = rxQEntry; + qEntryPtr[IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK] = 0; + + rxQReadStatus = ixQMgrQBurstRead(qId, + IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK, + qEntryPtr); + +#ifndef NDEBUG + if ((rxQReadStatus != IX_QMGR_Q_UNDERFLOW) + && (rxQReadStatus != IX_SUCCESS)) + { + ixEthAccDataStats.unexpectedError++; + /*major error*/ + IX_ETH_ACC_FATAL_LOG( + "ixEthRxFrameQMCallback:Error: %u\n", + (UINT32)rxQReadStatus, 0, 0, 0, 0, 0); + return; + } +#endif + + /* convert and preload the next entry + * (the conversion function takes care about null pointers which + * are used to mark the end of the loop) + */ + nextQEntry = *qEntryPtr; + nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry, + IX_ETHNPE_QM_Q_RXENET_ADDR_MASK); + + while(nextQEntry != 0) + { + /* get the next entry */ + qEntry = nextQEntry; + mbufPtr = nextMbufPtr; + +#ifndef NDEBUG + if (mbufPtr == NULL) + { + ixEthAccDataStats.unexpectedError++; + IX_ETH_ACC_FATAL_LOG( + "ixEthRxFrameQMCallback: Null Mbuf Ptr\n", + 0, 0, 0, 0, 0, 0); + return; + } +#endif + + /* convert the next entry + * (the conversion function takes care about null pointers which + * are used to mark the end of the loop) + */ + nextQEntry = *(++qEntryPtr); + nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry, + IX_ETHNPE_QM_Q_RXENET_ADDR_MASK); + + /* + * Get Port and Npe ID from message. + */ + npeId = ((IX_ETHNPE_QM_Q_RXENET_NPEID_MASK & + qEntry) >> IX_ETHNPE_QM_Q_FIELD_NPEID_R); + portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId); + + /* process frame, check the return code and skip the remaining of + * the loop if the frame is to be filtered out + */ + if (ixEthRxFrameProcess(portId, mbufPtr)) + { + /* destination portId for this packet */ + destPortId = IX_ETHACC_NE_DESTPORTID(mbufPtr); + + if (destPortId != IX_ETH_DB_UNKNOWN_PORT) + { + destPortId = IX_ETH_DB_NPE_LOGICAL_ID_TO_PORT_ID(destPortId); + } + + /* test if QoS is enabled in ethAcc + */ + if (ixEthAccDataInfo.schDiscipline == FIFO_PRIORITY) + { + /* check if there is a higher priority queue + * which may require processing and then process it. + */ + if (ixEthAccDataInfo.higherPriorityQueue[qId] < IX_QMGR_MAX_NUM_QUEUES) + { + ixEthRxFrameQMCallback(ixEthAccDataInfo.higherPriorityQueue[qId], + callbackId); + } + } + + /* + * increment priority stats + */ + RX_STATS_INC(portId,rxPriority[IX_ETHACC_NE_QOS(mbufPtr)]); + + /* + * increment callback count stats + */ + RX_STATS_INC(portId,rxFrameClientCallback); + + /* + * Call user level callback. + */ + ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn( + ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag, + mbufPtr, + destPortId); + } + } + } while (rxQReadStatus == IX_SUCCESS); +} + +/** + * @fn ixEthRxMultiBufferQMCallback + * + * @brief receive callback for Frame receive Q from NPE + * + * Frames are passed as an array to the user + * + * @param @ref IxQMgrCallback + * + * @return none + * + * @internal + * + * Design note : while processing the entry X, entry X+1 is preloaded + * into memory to reduce the number of stall cycles + * + */ +void ixEthRxMultiBufferQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId) +{ + IX_OSAL_MBUF *mbufPtr; + IX_OSAL_MBUF *nextMbufPtr; + UINT32 qEntry; + UINT32 nextQEntry; + UINT32 *qEntryPtr; + UINT32 portId; + UINT32 npeId; + UINT32 rxQReadStatus; + /* + * Design note : entries are read in a static buffer, This buffer contains + * an extra zeroed entry so the loop will + * always terminate on a null entry, whatever the result of Burst read is. + */ + static UINT32 rxQEntry[IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK + 1]; + static IX_OSAL_MBUF *rxMbufPortArray[IX_ETH_ACC_NUMBER_OF_PORTS][IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK + 1]; + IX_OSAL_MBUF **rxMbufPtr[IX_ETH_ACC_NUMBER_OF_PORTS]; + + for (portId = 0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) + { + rxMbufPtr[portId] = rxMbufPortArray[portId]; + } + + /* + * Indication of the number of times the callback is used. + */ + IX_ETH_ACC_STATS_INC(ixEthAccDataStats.rxCallbackCounter); + + do + { + /* + * Indication of the number of times the queue is drained + */ + IX_ETH_ACC_STATS_INC(ixEthAccDataStats.rxCallbackBurstRead); + + /* ensure the last entry of the array contains a zeroed value */ + qEntryPtr = rxQEntry; + qEntryPtr[IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK] = 0; + + rxQReadStatus = ixQMgrQBurstRead(qId, + IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK, + qEntryPtr); + +#ifndef NDEBUG + if ((rxQReadStatus != IX_QMGR_Q_UNDERFLOW) + && (rxQReadStatus != IX_SUCCESS)) + { + ixEthAccDataStats.unexpectedError++; + /*major error*/ + IX_ETH_ACC_FATAL_LOG( + "ixEthRxFrameMultiBufferQMCallback:Error: %u\n", + (UINT32)rxQReadStatus, 0, 0, 0, 0, 0); + return; + } +#endif + + /* convert and preload the next entry + * (the conversion function takes care about null pointers which + * are used to mark the end of the loop) + */ + nextQEntry = *qEntryPtr; + nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry, + IX_ETHNPE_QM_Q_RXENET_ADDR_MASK); + + while(nextQEntry != 0) + { + /* get the next entry */ + qEntry = nextQEntry; + mbufPtr = nextMbufPtr; + +#ifndef NDEBUG + if (mbufPtr == NULL) + { + ixEthAccDataStats.unexpectedError++; + IX_ETH_ACC_FATAL_LOG( + "ixEthRxFrameMultiBufferQMCallback:Error: Null Mbuf Ptr\n", + 0, 0, 0, 0, 0, 0); + return; + } +#endif + + /* convert the next entry + * (the conversion function takes care about null pointers which + * are used to mark the end of the loop) + */ + nextQEntry = *(++qEntryPtr); + nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry, + IX_ETHNPE_QM_Q_RXENET_ADDR_MASK); + + /* + * Get Port and Npe ID from message. + */ + npeId = ((IX_ETHNPE_QM_Q_RXENET_NPEID_MASK & + qEntry) >> + IX_ETHNPE_QM_Q_FIELD_NPEID_R); + portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId); + + /* skip the remaining of the loop if the frame is + * to be filtered out + */ + if (ixEthRxFrameProcess(portId, mbufPtr)) + { + /* store a mbuf pointer in an array */ + *rxMbufPtr[portId]++ = mbufPtr; + + /* + * increment priority stats + */ + RX_STATS_INC(portId,rxPriority[IX_ETHACC_NE_QOS(mbufPtr)]); + } + + /* test for QoS enabled in ethAcc */ + if (ixEthAccDataInfo.schDiscipline == FIFO_PRIORITY) + { + /* check if there is a higher priority queue + * which may require processing and then process it. + */ + if (ixEthAccDataInfo.higherPriorityQueue[qId] < IX_QMGR_MAX_NUM_QUEUES) + { + ixEthRxMultiBufferQMCallback(ixEthAccDataInfo.higherPriorityQueue[qId], + callbackId); + } + } + } + + /* check if any of the the arrays contains any entry */ + for (portId = 0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) + { + if (rxMbufPtr[portId] != rxMbufPortArray[portId]) + { + /* add a last NULL pointer at the end of the + * array of mbuf pointers + */ + *rxMbufPtr[portId] = NULL; + + /* + * increment callback count stats + */ + RX_STATS_INC(portId,rxFrameClientCallback); + + /* + * Call user level callback with an array of + * buffers (NULL terminated) + */ + ixEthAccPortData[portId].ixEthAccRxData. + rxMultiBufferCallbackFn( + ixEthAccPortData[portId].ixEthAccRxData. + rxMultiBufferCallbackTag, + rxMbufPortArray[portId]); + + /* reset the buffer pointer to the beginning of + * the array + */ + rxMbufPtr[portId] = rxMbufPortArray[portId]; + } + } + + } while (rxQReadStatus == IX_SUCCESS); +} + + +/** + * @brief rxFree low event handler + * + */ +void ixEthRxFreeQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId) +{ + IxEthAccPortId portId = (IxEthAccPortId) callbackId; + int lockVal; + UINT32 maxQWritesToPerform = IX_ETH_ACC_MAX_RX_FREE_BUFFERS_LOAD; + IX_STATUS qStatus = IX_SUCCESS; + + /* + * We have reached a low threshold on one of the Rx Free Qs + */ + + /*note that due to the fact that we are working off an Empty threshold, this callback + need only write a single entry to the Rx Free queue in order to re-arm the notification + */ + + RX_STATS_INC(portId,rxFreeLowCallback); + + /* + * Get buffers from approprite S/W Rx freeBufferList Q. + */ + +#ifndef NDEBUG + if (!IX_ETH_ACC_IS_PORT_VALID(portId)) + { + ixEthAccDataStats.unexpectedError++; + IX_ETH_ACC_FATAL_LOG( + "ixEthRxFreeQMCallback:Error: Invalid Port 0x%08X\n", + portId, 0, 0, 0, 0, 0); + return; + } +#endif + IX_ETH_ACC_DATA_PLANE_LOCK(lockVal); + if (IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(ixEthAccPortData[portId]. + ixEthAccRxData.freeBufferList)) + { + /* + * Turn off Q callback notification for Q in Question. + */ + qStatus = ixQMgrNotificationDisable( + IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(portId)); + + + IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); + + if (qStatus != IX_SUCCESS) + { + RX_INC(portId,rxUnexpectedError); + IX_ETH_ACC_FATAL_LOG( + "ixEthRxFreeQMCallback:Error: unexpected QM status 0x%08X\n", + qStatus, 0, 0, 0, 0, 0); + return; + } + } + else + { + IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); + /* + * Load the H/W Q with buffers from the s/w Q. + */ + + do + { + /* + * Consume Q entries. - Note Q contains Physical addresss, + * and have already been flushed to memory, + * And endianess converted if required. + */ + if (ixEthAccRxFreeFromSwQ(portId) != IX_SUCCESS) + { + /* + * No more entries in s/w Q. + * Turn off Q callback indication + */ + + IX_ETH_ACC_DATA_PLANE_LOCK(lockVal); + if (IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(ixEthAccPortData[portId]. + ixEthAccRxData.freeBufferList)) + { + qStatus = ixQMgrNotificationDisable( + IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(portId)); + } + IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); + break; + } + } + while (--maxQWritesToPerform); + } +} +/** + * @fn Tx queue low event handler + * + */ +void +ixEthTxFrameQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId) +{ + IxEthAccPortId portId = (IxEthAccPortId) callbackId; + int lockVal; + UINT32 maxQWritesToPerform = IX_ETH_ACC_MAX_TX_FRAME_TX_CONSUME_PER_CALLBACK; + IX_STATUS qStatus = IX_SUCCESS; + IxEthAccTxPriority highestPriority; + + + /* + * We have reached a low threshold on the Tx Q, and are being asked to + * supply a buffer for transmission from our S/W TX queues + */ + TX_STATS_INC(portId,txLowThreshCallback); + + /* + * Get buffers from approprite Q. + */ + +#ifndef NDEBUG + if (!IX_ETH_ACC_IS_PORT_VALID(portId)) + { + ixEthAccDataStats.unexpectedError++; + IX_ETH_ACC_FATAL_LOG( + "ixEthTxFrameQMCallback:Error: Invalid Port 0x%08X\n", + portId, 0, 0, 0, 0, 0); + return; + } +#endif + + do + { + /* + * Consume Q entries. - Note Q contains Physical addresss, + * and have already been flushed to memory, + * and endianess already sone if required. + */ + + IX_ETH_ACC_DATA_PLANE_LOCK(lockVal); + + if(ixEthAccTxSwQHighestPriorityGet(portId, &highestPriority) == + IX_ETH_ACC_FAIL) + { + /* + * No more entries in s/w Q. + * Turn off Q callback indication + */ + qStatus = ixQMgrNotificationDisable( + IX_ETH_ACC_PORT_TO_TX_Q_ID(portId)); + + IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); + + if (qStatus != IX_SUCCESS) + { + ixEthAccDataStats.unexpectedError++; + IX_ETH_ACC_FATAL_LOG( + "ixEthTxFrameQMCallback:Error: unexpected QM status 0x%08X\n", + qStatus, 0, 0, 0, 0, 0); + } + + return; + } + else + { + IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); + if (ixEthAccTxFromSwQ(portId,highestPriority)!=IX_SUCCESS) + { + /* nothing left in the sw queue or the hw queues are + * full. There is no point to continue to drain the + * sw queues + */ + return; + } + } + } + while (--maxQWritesToPerform); +} + +/** + * @brief TxDone event handler + * + * Design note : while processing the entry X, entry X+1 is preloaded + * into memory to reduce the number of stall cycles + * + */ + +void +ixEthTxFrameDoneQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId) +{ + IX_OSAL_MBUF *mbufPtr; + UINT32 qEntry; + UINT32 *qEntryPtr; + UINT32 txDoneQReadStatus; + UINT32 portId; + UINT32 npeId; + + /* + * Design note : entries are read in a static buffer, This buffer contains + * an extra entyry (which is zeroed by the compiler), so the loop will + * always terminate on a null entry, whatever the result of Burst read is. + */ + static UINT32 txDoneQEntry[IX_ETH_ACC_MAX_TX_FRAME_DONE_CONSUME_PER_CALLBACK + 1]; + + /* + * Indication that Tx frames have been transmitted from the NPE. + */ + + IX_ETH_ACC_STATS_INC(ixEthAccDataStats.txDoneCallbackCounter); + + do{ + qEntryPtr = txDoneQEntry; + txDoneQReadStatus = ixQMgrQBurstRead(IX_ETH_ACC_TX_FRAME_DONE_ETH_Q, + IX_ETH_ACC_MAX_TX_FRAME_DONE_CONSUME_PER_CALLBACK, + qEntryPtr); + +#ifndef NDEBUG + if (txDoneQReadStatus != IX_QMGR_Q_UNDERFLOW + && (txDoneQReadStatus != IX_SUCCESS)) + { + /*major error*/ + ixEthAccDataStats.unexpectedError++; + IX_ETH_ACC_FATAL_LOG( + "ixEthTxFrameDoneQMCallback:Error: %u\n", + (UINT32)txDoneQReadStatus, 0, 0, 0, 0, 0); + return; + } +#endif + + qEntry = *qEntryPtr; + + while(qEntry != 0) + { + mbufPtr = ixEthAccEntryFromQConvert(qEntry, + IX_ETHNPE_QM_Q_TXENET_ADDR_MASK); + +#ifndef NDEBUG + if (mbufPtr == NULL) + { + ixEthAccDataStats.unexpectedError++; + IX_ETH_ACC_FATAL_LOG( + "ixEthTxFrameDoneQMCallback:Error: Null Mbuf Ptr\n", + 0, 0, 0, 0, 0, 0); + return; + } +#endif + + /* endianness conversions and stats updates */ + ixEthAccMbufFromTxQ(mbufPtr); + + /* + * Get NPE id from message, then convert to portId. + */ + npeId = ((IX_ETHNPE_QM_Q_TXENETDONE_NPEID_MASK & + qEntry) >> + IX_ETHNPE_QM_Q_FIELD_NPEID_R); + portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId); + +#ifndef NDEBUG + /* Prudent to at least check the port is within range */ + if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS) + { + ixEthAccDataStats.unexpectedError++; + IX_ETH_ACC_FATAL_LOG( + "ixEthTxFrameDoneQMCallback: Illegal port: %u\n", + (UINT32)portId, 0, 0, 0, 0, 0); + return; + } +#endif + + TX_STATS_INC(portId,txDoneClientCallback); + + /* + * Call user level callback. + */ + ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn( + ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag, + mbufPtr); + + /* move to next queue entry */ + qEntry = *(++qEntryPtr); + + } + } while( txDoneQReadStatus == IX_SUCCESS ); +} + +IX_ETH_ACC_PUBLIC +void ixEthAccDataPlaneShow(void) +{ + UINT32 numTx0Entries; + UINT32 numTx1Entries; + UINT32 numTxDoneEntries; + UINT32 numRxEntries; + UINT32 numRxFree0Entries; + UINT32 numRxFree1Entries; + UINT32 portId; +#ifdef __ixp46X + UINT32 numTx2Entries; + UINT32 numRxFree2Entries; +#endif +#ifndef NDEBUG + UINT32 priority; + UINT32 numBuffersInRx=0; + UINT32 numBuffersInTx=0; + UINT32 numBuffersInSwQ=0; + UINT32 totalBuffers=0; + UINT32 rxFreeCallbackCounter = 0; + UINT32 txCallbackCounter = 0; +#endif + UINT32 key; + + /* snapshot of stats */ + IxEthAccTxDataStats tx[IX_ETH_ACC_NUMBER_OF_PORTS]; + IxEthAccRxDataStats rx[IX_ETH_ACC_NUMBER_OF_PORTS]; + IxEthAccDataPlaneStats stats; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return; + } + + /* get a reliable snapshot */ + key = ixOsalIrqLock(); + + numTx0Entries = 0; + ixQMgrQNumEntriesGet(IX_ETH_ACC_TX_FRAME_ENET0_Q, &numTx0Entries); + numTx1Entries = 0; + ixQMgrQNumEntriesGet(IX_ETH_ACC_TX_FRAME_ENET1_Q, &numTx1Entries); + numTxDoneEntries = 0; + ixQMgrQNumEntriesGet( IX_ETH_ACC_TX_FRAME_DONE_ETH_Q, &numTxDoneEntries); + numRxEntries = 0; + ixEthAccQMgrRxQEntryGet(&numRxEntries); + numRxFree0Entries = 0; + ixQMgrQNumEntriesGet(IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q, &numRxFree0Entries); + numRxFree1Entries = 0; + ixQMgrQNumEntriesGet(IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q, &numRxFree1Entries); + +#ifdef __ixp46X + numTx2Entries = 0; + ixQMgrQNumEntriesGet(IX_ETH_ACC_TX_FRAME_ENET2_Q, &numTx2Entries); + numRxFree2Entries = 0; + ixQMgrQNumEntriesGet(IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q, &numRxFree2Entries); +#endif + + for(portId=IX_ETH_PORT_1; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) + { + memcpy(&tx[portId], + &ixEthAccPortData[portId].ixEthAccTxData.stats, + sizeof(tx[portId])); + memcpy(&rx[portId], + &ixEthAccPortData[portId].ixEthAccRxData.stats, + sizeof(rx[portId])); + } + memcpy(&stats, &ixEthAccDataStats, sizeof(stats)); + + ixOsalIrqUnlock(key); + +#ifdef NDEBUG + printf("Detailed statistics collection not supported in this load\n"); +#endif + + /* print snapshot */ + for(portId=0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; 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 ((IX_ETH_PORT_1 == portId) && + (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) == + IX_FEATURE_CTRL_COMPONENT_DISABLED)) + { + continue ; + } + if ((IX_ETH_PORT_2 == portId) && + (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) == + IX_FEATURE_CTRL_COMPONENT_DISABLED)) + { + continue ; + } + if ((IX_ETH_PORT_3 == portId) && + (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA_ETH) == + IX_FEATURE_CTRL_COMPONENT_DISABLED)) + { + continue ; + } + } + + printf("PORT %u --------------------------------\n", + portId); +#ifndef NDEBUG + printf("Tx Done Frames : %u\n", + tx[portId].txDoneClientCallback + + tx[portId].txDoneSwQDuringDisable + + tx[portId].txDoneDuringDisable); + printf("Tx Frames : %u\n", + tx[portId].txQOK + tx[portId].txQDelayed); + printf("Tx H/W Q Added OK : %u\n", + tx[portId].txQOK); + printf("Tx H/W Q Delayed : %u\n", + tx[portId].txQDelayed); + printf("Tx From S/W Q Added OK : %u\n", + tx[portId].txFromSwQOK); + printf("Tx From S/W Q Delayed : %u\n", + tx[portId].txFromSwQDelayed); + printf("Tx Overflow : %u\n", + tx[portId].txOverflow); + printf("Tx Mutual Lock : %u\n", + tx[portId].txLock); + printf("Tx Late Ntf Enabled : %u\n", + tx[portId].txLateNotificationEnabled); + printf("Tx Low Thresh CB : %u\n", + tx[portId].txLowThreshCallback); + printf("Tx Done from H/W Q (Disable) : %u\n", + tx[portId].txDoneDuringDisable); + printf("Tx Done from S/W Q (Disable) : %u\n", + tx[portId].txDoneSwQDuringDisable); + for (priority = IX_ETH_ACC_TX_PRIORITY_0; + priority <= IX_ETH_ACC_TX_PRIORITY_7; + priority++) + { + if (tx[portId].txPriority[priority]) + { + printf("Tx Priority %u : %u\n", + priority, + tx[portId].txPriority[priority]); + } + } +#endif + printf("Tx unexpected errors : %u (should be 0)\n", + tx[portId].txUnexpectedError); + +#ifndef NDEBUG + printf("Rx Frames : %u\n", + rx[portId].rxFrameClientCallback + + rx[portId].rxSwQDuringDisable+ + rx[portId].rxDuringDisable); + printf("Rx Free Replenish : %u\n", + rx[portId].rxFreeRepOK + rx[portId].rxFreeRepDelayed); + printf("Rx Free H/W Q Added OK : %u\n", + rx[portId].rxFreeRepOK); + printf("Rx Free H/W Q Delayed : %u\n", + rx[portId].rxFreeRepDelayed); + printf("Rx Free From S/W Q Added OK : %u\n", + rx[portId].rxFreeRepFromSwQOK); + printf("Rx Free From S/W Q Delayed : %u\n", + rx[portId].rxFreeRepFromSwQDelayed); + printf("Rx Free Overflow : %u\n", + rx[portId].rxFreeOverflow); + printf("Rx Free Mutual Lock : %u\n", + rx[portId].rxFreeLock); + printf("Rx Free Late Ntf Enabled : %u\n", + rx[portId].rxFreeLateNotificationEnabled); + printf("Rx Free Low CB : %u\n", + rx[portId].rxFreeLowCallback); + printf("Rx From H/W Q (Disable) : %u\n", + rx[portId].rxDuringDisable); + printf("Rx From S/W Q (Disable) : %u\n", + rx[portId].rxSwQDuringDisable); + printf("Rx unlearned Mac Address : %u\n", + rx[portId].rxUnlearnedMacAddress); + printf("Rx Filtered (Rx => RxFree) : %u\n", + rx[portId].rxFiltered); + + for (priority = IX_ETH_ACC_TX_PRIORITY_0; + priority <= IX_ETH_ACC_TX_PRIORITY_7; + priority++) + { + if (rx[portId].rxPriority[priority]) + { + printf("Rx Priority %u : %u\n", + priority, + rx[portId].rxPriority[priority]); + } + } +#endif + printf("Rx unexpected errors : %u (should be 0)\n", + rx[portId].rxUnexpectedError); + +#ifndef NDEBUG + numBuffersInTx = tx[portId].txQOK + + tx[portId].txQDelayed - + tx[portId].txDoneClientCallback - + tx[portId].txDoneSwQDuringDisable - + tx[portId].txDoneDuringDisable; + + printf("# Tx Buffers currently for transmission : %u\n", + numBuffersInTx); + + numBuffersInRx = rx[portId].rxFreeRepOK + + rx[portId].rxFreeRepDelayed - + rx[portId].rxFrameClientCallback - + rx[portId].rxSwQDuringDisable - + rx[portId].rxDuringDisable; + + printf("# Rx Buffers currently for reception : %u\n", + numBuffersInRx); + + totalBuffers += numBuffersInRx + numBuffersInTx; +#endif + } + + printf("---------------------------------------\n"); + +#ifndef NDEBUG + printf("\n"); + printf("Mbufs :\n"); + printf("Tx Unchained mbufs : %u\n", + stats.unchainedTxMBufs); + printf("Tx Chained bufs : %u\n", + stats.chainedTxMBufs); + printf("TxDone Unchained mbufs : %u\n", + stats.unchainedTxDoneMBufs); + printf("TxDone Chained bufs : %u\n", + stats.chainedTxDoneMBufs); + printf("RxFree Unchained mbufs : %u\n", + stats.unchainedRxFreeMBufs); + printf("RxFree Chained bufs : %u\n", + stats.chainedRxFreeMBufs); + printf("Rx Unchained mbufs : %u\n", + stats.unchainedRxMBufs); + printf("Rx Chained bufs : %u\n", + stats.chainedRxMBufs); + + printf("\n"); + printf("Software queue usage :\n"); + printf("Buffers added to S/W Q : %u\n", + stats.addToSwQ); + printf("Buffers removed from S/W Q : %u\n", + stats.removeFromSwQ); + + printf("\n"); + printf("Hardware queues callbacks :\n"); + + for(portId=0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) + { + rxFreeCallbackCounter += rx[portId].rxFreeLowCallback; + txCallbackCounter += tx[portId].txLowThreshCallback; + } + printf("Tx Done QM Callback invoked : %u\n", + stats.txDoneCallbackCounter); + printf("Tx QM Callback invoked : %u\n", + txCallbackCounter); + printf("Rx QM Callback invoked : %u\n", + stats.rxCallbackCounter); + printf("Rx QM Callback burst read : %u\n", + stats.rxCallbackBurstRead); + printf("Rx Free QM Callback invoked : %u\n", + rxFreeCallbackCounter); +#endif + printf("Unexpected errors in CB : %u (should be 0)\n", + stats.unexpectedError); + printf("\n"); + + printf("Hardware queues levels :\n"); + printf("Transmit Port 1 Q : %u \n",numTx0Entries); + printf("Transmit Port 2 Q : %u \n",numTx1Entries); +#ifdef __ixp46X + printf("Transmit Port 3 Q : %u \n",numTx2Entries); +#endif + printf("Transmit Done Q : %u \n",numTxDoneEntries); + printf("Receive Q : %u \n",numRxEntries); + printf("Receive Free Port 1 Q : %u \n",numRxFree0Entries); + printf("Receive Free Port 2 Q : %u \n",numRxFree1Entries); +#ifdef __ixp46X + printf("Receive Free Port 3 Q : %u \n",numRxFree2Entries); +#endif + +#ifndef NDEBUG + printf("\n"); + printf("# Total Buffers accounted for : %u\n", + totalBuffers); + + numBuffersInSwQ = ixEthAccDataStats.addToSwQ - + ixEthAccDataStats.removeFromSwQ; + + printf(" Buffers in S/W Qs : %u\n", + numBuffersInSwQ); + printf(" Buffers in H/W Qs or NPEs : %u\n", + totalBuffers - numBuffersInSwQ); +#endif + + printf("Rx QoS Discipline : %s\n", + (ixEthAccDataInfo.schDiscipline == + FIFO_PRIORITY ) ? "Enabled" : "Disabled"); + + for(portId=0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) + { + printf("Tx QoS Discipline port %u : %s\n", + portId, + (ixEthAccPortData[portId].ixEthAccTxData.schDiscipline == + FIFO_PRIORITY ) ? "Enabled" : "Disabled"); + } + printf("\n"); +} + + + + + diff --git a/arch/arm/cpu/ixp/npe/IxEthAccMac.c b/arch/arm/cpu/ixp/npe/IxEthAccMac.c new file mode 100644 index 0000000000..369ee91d94 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxEthAccMac.c @@ -0,0 +1,2641 @@ +/** + * @file IxEthAccMac.c + * + * @author Intel Corporation + * @date + * + * @brief MAC control functions + * + * Design Notes: + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#include "IxOsal.h" +#include "IxNpeMh.h" +#ifdef CONFIG_IXP425_COMPONENT_ETHDB +#include "IxEthDB.h" +#endif +#include "IxEthDBPortDefs.h" +#include "IxEthNpe.h" +#include "IxEthAcc.h" +#include "IxEthAccDataPlane_p.h" +#include "IxEthAcc_p.h" +#include "IxEthAccMac_p.h" + +/* Maximum number of retries during ixEthAccPortDisable, which + * is approximately 10 seconds +*/ +#define IX_ETH_ACC_MAX_RETRY 500 + +/* Maximum number of retries during ixEthAccPortDisable when expecting + * timeout + */ +#define IX_ETH_ACC_MAX_RETRY_TIMEOUT 5 + +#define IX_ETH_ACC_VALIDATE_PORT_ID(portId) \ + do \ + { \ + if(!IX_ETH_ACC_IS_PORT_VALID(portId)) \ + { \ + return IX_ETH_ACC_INVALID_PORT; \ + } \ + } while(0) + +PUBLIC IxEthAccMacState ixEthAccMacState[IX_ETH_ACC_NUMBER_OF_PORTS]; + +PRIVATE UINT32 ixEthAccMacBase[IX_ETH_ACC_NUMBER_OF_PORTS]; + +/*Forward function declarations*/ +PRIVATE void +ixEthAccPortDisableRx (IxEthAccPortId portId, + IX_OSAL_MBUF * mBufPtr, + BOOL useMultiBufferCallback); + +PRIVATE void +ixEthAccPortDisableRxAndReplenish (IxEthAccPortId portId, + IX_OSAL_MBUF * mBufPtr, + BOOL useMultiBufferCallback); + +PRIVATE void +ixEthAccPortDisableTxDone (UINT32 cbTag, + IX_OSAL_MBUF *mbuf); + +PRIVATE void +ixEthAccPortDisableTxDoneAndSubmit (UINT32 cbTag, + IX_OSAL_MBUF *mbuf); + +PRIVATE void +ixEthAccPortDisableRxCallback (UINT32 cbTag, + IX_OSAL_MBUF * mBufPtr, + UINT32 learnedPortId); + +PRIVATE void +ixEthAccPortDisableMultiBufferRxCallback (UINT32 cbTag, + IX_OSAL_MBUF **mBufPtr); + +PRIVATE IxEthAccStatus +ixEthAccPortDisableTryTransmit(UINT32 portId); + +PRIVATE IxEthAccStatus +ixEthAccPortDisableTryReplenish(UINT32 portId); + +PRIVATE IxEthAccStatus +ixEthAccPortMulticastMacAddressGet (IxEthAccPortId portId, + IxEthAccMacAddr *macAddr); + +PRIVATE IxEthAccStatus +ixEthAccPortMulticastMacFilterGet (IxEthAccPortId portId, + IxEthAccMacAddr *macAddr); + +PRIVATE void +ixEthAccMacNpeStatsMessageCallback (IxNpeMhNpeId npeId, + IxNpeMhMessage msg); + +PRIVATE void +ixEthAccMacNpeStatsResetMessageCallback (IxNpeMhNpeId npeId, + IxNpeMhMessage msg); + +PRIVATE void +ixEthAccNpeLoopbackMessageCallback (IxNpeMhNpeId npeId, + IxNpeMhMessage msg); + +PRIVATE void +ixEthAccMulticastAddressSet(IxEthAccPortId portId); + +PRIVATE BOOL +ixEthAccMacEqual(IxEthAccMacAddr *macAddr1, + IxEthAccMacAddr *macAddr2); + +PRIVATE void +ixEthAccMacPrint(IxEthAccMacAddr *m); + +PRIVATE void +ixEthAccMacStateUpdate(IxEthAccPortId portId); + +IxEthAccStatus +ixEthAccMacMemInit(void) +{ + ixEthAccMacBase[IX_ETH_PORT_1] = + (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_0_BASE, + IX_OSAL_IXP400_ETHA_MAP_SIZE); + ixEthAccMacBase[IX_ETH_PORT_2] = + (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_1_BASE, + IX_OSAL_IXP400_ETHB_MAP_SIZE); +#ifdef __ixp46X + ixEthAccMacBase[IX_ETH_PORT_3] = + (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_2_BASE, + IX_OSAL_IXP400_ETH_NPEA_MAP_SIZE); + if (ixEthAccMacBase[IX_ETH_PORT_3] == 0) + { + ixOsalLog(IX_OSAL_LOG_LVL_FATAL, + IX_OSAL_LOG_DEV_STDOUT, + "EthAcc: Could not map MAC I/O memory\n", + 0, 0, 0, 0, 0 ,0); + + return IX_ETH_ACC_FAIL; + } +#endif + + if (ixEthAccMacBase[IX_ETH_PORT_1] == 0 + || ixEthAccMacBase[IX_ETH_PORT_2] == 0) + { + ixOsalLog(IX_OSAL_LOG_LVL_FATAL, + IX_OSAL_LOG_DEV_STDOUT, + "EthAcc: Could not map MAC I/O memory\n", + 0, 0, 0, 0, 0 ,0); + + return IX_ETH_ACC_FAIL; + } + + return IX_ETH_ACC_SUCCESS; +} + +void +ixEthAccMacUnload(void) +{ + IX_OSAL_MEM_UNMAP(ixEthAccMacBase[IX_ETH_PORT_1]); + IX_OSAL_MEM_UNMAP(ixEthAccMacBase[IX_ETH_PORT_2]); +#ifdef __ixp46X + IX_OSAL_MEM_UNMAP(ixEthAccMacBase[IX_ETH_PORT_3]); + ixEthAccMacBase[IX_ETH_PORT_3] = 0; +#endif + ixEthAccMacBase[IX_ETH_PORT_2] = 0; + ixEthAccMacBase[IX_ETH_PORT_1] = 0; +} + +IxEthAccStatus +ixEthAccPortEnablePriv(IxEthAccPortId portId) +{ + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable port.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + printf("EthAcc: (Mac) cannot enable port %d, port not initialized\n", portId); + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + if (ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn == NULL) + { + /* TxDone callback not registered */ + printf("EthAcc: (Mac) cannot enable port %d, TxDone callback not registered\n", portId); + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + if ((ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn == NULL) + && (ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn == NULL)) + { + /* Receive callback not registered */ + printf("EthAcc: (Mac) cannot enable port %d, Rx callback not registered\n", portId); + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + if(!ixEthAccMacState[portId].initDone) + { + printf("EthAcc: (Mac) cannot enable port %d, MAC address not set\n", portId); + return (IX_ETH_ACC_MAC_UNINITIALIZED); + } + + /* if the state is being set to what it is already at, do nothing*/ + if (ixEthAccMacState[portId].enabled) + { + return IX_ETH_ACC_SUCCESS; + } + +#ifdef CONFIG_IXP425_COMPONENT_ETHDB + /* enable ethernet database for this port */ + if (ixEthDBPortEnable(portId) != IX_ETH_DB_SUCCESS) + { + printf("EthAcc: (Mac) cannot enable port %d, EthDB failure\n", portId); + return IX_ETH_ACC_FAIL; + } +#endif + + /* set the MAC core registers */ + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_TX_CNTRL2, + IX_ETH_ACC_TX_CNTRL2_RETRIES_MASK); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RANDOM_SEED, + IX_ETH_ACC_RANDOM_SEED_DEFAULT); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_THRESH_P_EMPTY, + IX_ETH_ACC_MAC_THRESH_P_EMPTY_DEFAULT); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_THRESH_P_FULL, + IX_ETH_ACC_MAC_THRESH_P_FULL_DEFAULT); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_TX_DEFER, + IX_ETH_ACC_MAC_TX_DEFER_DEFAULT); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_TX_TWO_DEFER_1, + IX_ETH_ACC_MAC_TX_TWO_DEFER_1_DEFAULT); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_TX_TWO_DEFER_2, + IX_ETH_ACC_MAC_TX_TWO_DEFER_2_DEFAULT); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_SLOT_TIME, + IX_ETH_ACC_MAC_SLOT_TIME_DEFAULT); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_INT_CLK_THRESH, + IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_BUF_SIZE_TX, + IX_ETH_ACC_MAC_BUF_SIZE_TX_DEFAULT); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_TX_CNTRL1, + IX_ETH_ACC_TX_CNTRL1_DEFAULT); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + IX_ETH_ACC_RX_CNTRL1_DEFAULT); + + /* set the global state */ + ixEthAccMacState[portId].portDisableState = ACTIVE; + ixEthAccMacState[portId].enabled = TRUE; + + /* rewrite the setup (including mac filtering) depending + * on current options + */ + ixEthAccMacStateUpdate(portId); + + return IX_ETH_ACC_SUCCESS; +} + +/* + * PortDisable local variables. They contain the intermediate steps + * while the port is being disabled and the buffers being drained out + * of the NPE. + */ +typedef void (*IxEthAccPortDisableRx)(IxEthAccPortId portId, + IX_OSAL_MBUF * mBufPtr, + BOOL useMultiBufferCallback); +static IxEthAccPortRxCallback +ixEthAccPortDisableFn[IX_ETH_ACC_NUMBER_OF_PORTS]; +static IxEthAccPortMultiBufferRxCallback +ixEthAccPortDisableMultiBufferFn[IX_ETH_ACC_NUMBER_OF_PORTS]; +static IxEthAccPortDisableRx +ixEthAccPortDisableRxTable[IX_ETH_ACC_NUMBER_OF_PORTS]; +static UINT32 +ixEthAccPortDisableCbTag[IX_ETH_ACC_NUMBER_OF_PORTS]; +static UINT32 +ixEthAccPortDisableMultiBufferCbTag[IX_ETH_ACC_NUMBER_OF_PORTS]; + +static IxEthAccPortTxDoneCallback +ixEthAccPortDisableTxDoneFn[IX_ETH_ACC_NUMBER_OF_PORTS]; +static UINT32 +ixEthAccPortDisableTxDoneCbTag[IX_ETH_ACC_NUMBER_OF_PORTS]; + +static UINT32 +ixEthAccPortDisableUserBufferCount[IX_ETH_ACC_NUMBER_OF_PORTS]; + +/* + * PortDisable private callbacks functions. They handle the user + * traffic, and the special buffers (one for tx, one for rx) used + * in portDisable. + */ +PRIVATE void +ixEthAccPortDisableTxDone(UINT32 cbTag, + IX_OSAL_MBUF *mbuf) +{ + IxEthAccPortId portId = (IxEthAccPortId)cbTag; + volatile IxEthAccPortDisableState *txState = &ixEthAccMacState[portId].txState; + + /* check for the special mbuf used in portDisable */ + if (mbuf == ixEthAccMacState[portId].portDisableTxMbufPtr) + { + *txState = TRANSMIT_DONE; + } + else + { + /* increment the count of user traffic during portDisable */ + ixEthAccPortDisableUserBufferCount[portId]++; + + /* call client TxDone function */ + ixEthAccPortDisableTxDoneFn[portId](ixEthAccPortDisableTxDoneCbTag[portId], mbuf); + } +} + +PRIVATE IxEthAccStatus +ixEthAccPortDisableTryTransmit(UINT32 portId) +{ + int key; + IxEthAccStatus status = IX_ETH_ACC_SUCCESS; + volatile IxEthAccPortDisableState *txState = &ixEthAccMacState[portId].txState; + /* transmit the special buffer again if it is transmitted + * and update the txState + * This section is protected because the portDisable context + * run an identical code, so the system keeps transmitting at the + * maximum rate. + */ + key = ixOsalIrqLock(); + if (*txState == TRANSMIT_DONE) + { + IX_OSAL_MBUF *mbufTxPtr = ixEthAccMacState[portId].portDisableTxMbufPtr; + *txState = TRANSMIT; + status = ixEthAccPortTxFrameSubmit(portId, + mbufTxPtr, + IX_ETH_ACC_TX_DEFAULT_PRIORITY); + } + ixOsalIrqUnlock(key); + + return status; +} + +PRIVATE void +ixEthAccPortDisableTxDoneAndSubmit(UINT32 cbTag, + IX_OSAL_MBUF *mbuf) +{ + IxEthAccPortId portId = (IxEthAccPortId)cbTag; + + /* call the callback which forwards the traffic to the client */ + ixEthAccPortDisableTxDone(cbTag, mbuf); + + /* try to transmit the buffer used in portDisable + * if seen in TxDone + */ + ixEthAccPortDisableTryTransmit(portId); +} + +PRIVATE void +ixEthAccPortDisableRx (IxEthAccPortId portId, + IX_OSAL_MBUF * mBufPtr, + BOOL useMultiBufferCallback) +{ + volatile IxEthAccPortDisableState *rxState = &ixEthAccMacState[portId].rxState; + IX_OSAL_MBUF *mNextPtr; + + while (mBufPtr) + { + mNextPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mBufPtr); + IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mBufPtr) = NULL; + + /* check for the special mbuf used in portDisable */ + if (mBufPtr == ixEthAccMacState[portId].portDisableRxMbufPtr) + { + *rxState = RECEIVE; + } + else + { + /* increment the count of user traffic during portDisable */ + ixEthAccPortDisableUserBufferCount[portId]++; + + /* reset the received payload length during portDisable */ + IX_OSAL_MBUF_MLEN(mBufPtr) = 0; + IX_OSAL_MBUF_PKT_LEN(mBufPtr) = 0; + + if (useMultiBufferCallback) + { + /* call the user callback with one unchained + * buffer, without payload. A small array is built + * to be used as a parameter (the user callback expects + * to receive an array ended by a NULL pointer. + */ + IX_OSAL_MBUF *mBufPtrArray[2]; + + mBufPtrArray[0] = mBufPtr; + mBufPtrArray[1] = NULL; + ixEthAccPortDisableMultiBufferFn[portId]( + ixEthAccPortDisableMultiBufferCbTag[portId], + mBufPtrArray); + } + else + { + /* call the user callback with a unchained + * buffer, without payload and the destination port is + * unknown. + */ + ixEthAccPortDisableFn[portId]( + ixEthAccPortDisableCbTag[portId], + mBufPtr, + IX_ETH_DB_UNKNOWN_PORT /* port not found */); + } + } + + mBufPtr = mNextPtr; + } +} + +PRIVATE IxEthAccStatus +ixEthAccPortDisableTryReplenish(UINT32 portId) +{ + int key; + IxEthAccStatus status = IX_ETH_ACC_SUCCESS; + volatile IxEthAccPortDisableState *rxState = &ixEthAccMacState[portId].rxState; + /* replenish with the special buffer again if it is received + * and update the rxState + * This section is protected because the portDisable context + * run an identical code, so the system keeps replenishing at the + * maximum rate. + */ + key = ixOsalIrqLock(); + if (*rxState == RECEIVE) + { + IX_OSAL_MBUF *mbufRxPtr = ixEthAccMacState[portId].portDisableRxMbufPtr; + *rxState = REPLENISH; + IX_OSAL_MBUF_MLEN(mbufRxPtr) = IX_ETHACC_RX_MBUF_MIN_SIZE; + status = ixEthAccPortRxFreeReplenish(portId, mbufRxPtr); + } + ixOsalIrqUnlock(key); + + return status; +} + +PRIVATE void +ixEthAccPortDisableRxAndReplenish (IxEthAccPortId portId, + IX_OSAL_MBUF * mBufPtr, + BOOL useMultiBufferCallback) +{ + /* call the callback which forwards the traffic to the client */ + ixEthAccPortDisableRx(portId, mBufPtr, useMultiBufferCallback); + + /* try to replenish with the buffer used in portDisable + * if seen in Rx + */ + ixEthAccPortDisableTryReplenish(portId); +} + +PRIVATE void +ixEthAccPortDisableRxCallback (UINT32 cbTag, + IX_OSAL_MBUF * mBufPtr, + UINT32 learnedPortId) +{ + IxEthAccPortId portId = (IxEthAccPortId)cbTag; + + /* call the portDisable receive callback */ + (ixEthAccPortDisableRxTable[portId])(portId, mBufPtr, FALSE); +} + +PRIVATE void +ixEthAccPortDisableMultiBufferRxCallback (UINT32 cbTag, + IX_OSAL_MBUF **mBufPtr) +{ + IxEthAccPortId portId = (IxEthAccPortId)cbTag; + + while (*mBufPtr) + { + /* call the portDisable receive callback with one buffer at a time */ + (ixEthAccPortDisableRxTable[portId])(portId, *mBufPtr++, TRUE); + } +} + +IxEthAccStatus +ixEthAccPortDisablePriv(IxEthAccPortId portId) +{ + IxEthAccStatus status = IX_ETH_ACC_SUCCESS; + int key; + int retry, retryTimeout; + volatile IxEthAccPortDisableState *state = &ixEthAccMacState[portId].portDisableState; + volatile IxEthAccPortDisableState *rxState = &ixEthAccMacState[portId].rxState; + volatile IxEthAccPortDisableState *txState = &ixEthAccMacState[portId].txState; + + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot disable port.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + /* if the state is being set to what it is already at, do nothing */ + if (!ixEthAccMacState[portId].enabled) + { + return IX_ETH_ACC_SUCCESS; + } + + *state = DISABLED; + + /* disable MAC receive first */ + ixEthAccPortRxDisablePriv(portId); + +#ifdef CONFIG_IXP425_COMPONENT_ETHDB + /* disable ethernet database for this port - It is done now to avoid + * issuing ELT maintenance after requesting 'port disable' in an NPE + */ + if (ixEthDBPortDisable(portId) != IX_ETH_DB_SUCCESS) + { + status = IX_ETH_ACC_FAIL; + IX_ETH_ACC_FATAL_LOG("ixEthAccPortDisable: failed to disable EthDB for this port\n", 0, 0, 0, 0, 0, 0); + } +#endif + + /* enter the critical section */ + key = ixOsalIrqLock(); + + /* swap the Rx and TxDone callbacks */ + ixEthAccPortDisableFn[portId] = ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn; + ixEthAccPortDisableMultiBufferFn[portId] = ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn; + ixEthAccPortDisableCbTag[portId] = ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag; + ixEthAccPortDisableMultiBufferCbTag[portId] = ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag; + ixEthAccPortDisableTxDoneFn[portId] = ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn; + ixEthAccPortDisableTxDoneCbTag[portId] = ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag; + ixEthAccPortDisableRxTable[portId] = ixEthAccPortDisableRx; + + /* register temporary callbacks */ + ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn = ixEthAccPortDisableRxCallback; + ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag = portId; + + ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn = ixEthAccPortDisableMultiBufferRxCallback; + ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag = portId; + + ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn = ixEthAccPortDisableTxDone; + ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag = portId; + + /* initialise the Rx state and Tx states */ + *txState = TRANSMIT_DONE; + *rxState = RECEIVE; + + /* exit the critical section */ + ixOsalIrqUnlock(key); + + /* enable a NPE loopback */ + if (ixEthAccNpeLoopbackEnablePriv(portId) != IX_ETH_ACC_SUCCESS) + { + status = IX_ETH_ACC_FAIL; + } + + if (status == IX_ETH_ACC_SUCCESS) + { + retry = 0; + + /* Step 1 : Drain Tx traffic and TxDone queues : + * + * Transmit and replenish at least once with the + * special buffers until both of them are seen + * in the callback hook + * + * (the receive callback keeps replenishing, so once we see + * the special Tx buffer, we can be sure that Tx drain is complete) + */ + ixEthAccPortDisableRxTable[portId] + = ixEthAccPortDisableRxAndReplenish; + ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn + = ixEthAccPortDisableTxDone; + + do + { + /* keep replenishing */ + status = ixEthAccPortDisableTryReplenish(portId); + if (status == IX_ETH_ACC_SUCCESS) + { + /* keep transmitting */ + status = ixEthAccPortDisableTryTransmit(portId); + } + if (status == IX_ETH_ACC_SUCCESS) + { + /* wait for some traffic being processed */ + ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS); + } + } + while ((status == IX_ETH_ACC_SUCCESS) + && (retry++ < IX_ETH_ACC_MAX_RETRY) + && (*txState == TRANSMIT)); + + /* Step 2 : Drain Rx traffic, RxFree and Rx queues : + * + * Transmit and replenish at least once with the + * special buffers until both of them are seen + * in the callback hook + * (the transmit callback keeps transmitting, and when we see + * the special Rx buffer, we can be sure that rxFree drain + * is complete) + * + * The nested loop helps to retry if the user was keeping + * replenishing or transmitting during portDisable. + * + * The 2 nested loops ensure more retries if user traffic is + * seen during portDisable : the user should not replenish + * or transmit while portDisable is running. However, because of + * the queueing possibilities in ethAcc dataplane, it is possible + * that a lot of traffic is left in the queues (e.g. when + * transmitting over a low speed link) and therefore, more + * retries are allowed to help flushing the buffers out. + */ + ixEthAccPortDisableRxTable[portId] + = ixEthAccPortDisableRx; + ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn + = ixEthAccPortDisableTxDoneAndSubmit; + + do + { + do + { + ixEthAccPortDisableUserBufferCount[portId] = 0; + + /* keep replenishing */ + status = ixEthAccPortDisableTryReplenish(portId); + if (status == IX_ETH_ACC_SUCCESS) + { + /* keep transmitting */ + status = ixEthAccPortDisableTryTransmit(portId); + } + if (status == IX_ETH_ACC_SUCCESS) + { + /* wait for some traffic being processed */ + ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS); + } + } + while ((status == IX_ETH_ACC_SUCCESS) + && (retry++ < IX_ETH_ACC_MAX_RETRY) + && ((ixEthAccPortDisableUserBufferCount[portId] != 0) + || (*rxState == REPLENISH))); + + /* After the first iteration, change the receive callbacks, + * to process only 1 buffer at a time + */ + ixEthAccPortDisableRxTable[portId] + = ixEthAccPortDisableRx; + ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn + = ixEthAccPortDisableTxDone; + + /* repeat the whole process while user traffic is seen in TxDone + * + * The conditions to stop the loop are + * - Xscale has both Rx and Tx special buffers + * (txState = transmit, rxState = receive) + * - any error in txSubmit or rxReplenish + * - no user traffic seen + * - an excessive amount of retries + */ + } + while ((status == IX_ETH_ACC_SUCCESS) + && (retry < IX_ETH_ACC_MAX_RETRY) + && (*txState == TRANSMIT)); + + /* check the loop exit conditions. The NPE should not hold + * the special buffers. + */ + if ((*rxState == REPLENISH) || (*txState == TRANSMIT)) + { + status = IX_ETH_ACC_FAIL; + } + + if (status == IX_ETH_ACC_SUCCESS) + { + /* Step 3 : Replenish without transmitting until a timeout + * occurs, in order to drain the internal NPE fifos + * + * we can expect a few frames srill held + * in the NPE. + * + * The 2 nested loops take care about the NPE dropping traffic + * (including loopback traffic) when the Rx queue is full. + * + * The timeout value is very conservative + * since the loopback used keeps replenishhing. + * + */ + do + { + ixEthAccPortDisableRxTable[portId] = ixEthAccPortDisableRxAndReplenish; + ixEthAccPortDisableUserBufferCount[portId] = 0; + retryTimeout = 0; + do + { + /* keep replenishing */ + status = ixEthAccPortDisableTryReplenish(portId); + if (status == IX_ETH_ACC_SUCCESS) + { + /* wait for some traffic being processed */ + ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS); + } + } + while ((status == IX_ETH_ACC_SUCCESS) + && (retryTimeout++ < IX_ETH_ACC_MAX_RETRY_TIMEOUT)); + + /* Step 4 : Transmit once. Stop replenish + * + * After the Rx timeout, we are sure that the NPE does not + * hold any frame in its internal NPE fifos. + * + * At this point, the NPE still holds the last rxFree buffer. + * By transmitting a single frame, this should unblock the + * last rxFree buffer. This code just transmit once and + * wait for both frames seen in TxDone and in rxFree. + * + */ + ixEthAccPortDisableRxTable[portId] = ixEthAccPortDisableRx; + status = ixEthAccPortDisableTryTransmit(portId); + + /* the NPE should immediatelyt release + * the last Rx buffer and the last transmitted buffer + * unless the last Tx frame was dropped (rx queue full) + */ + if (status == IX_ETH_ACC_SUCCESS) + { + retryTimeout = 0; + do + { + ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS); + } + while ((*rxState == REPLENISH) + && (retryTimeout++ < IX_ETH_ACC_MAX_RETRY_TIMEOUT)); + } + + /* the NPE may have dropped the traffic because of Rx + * queue being full. This code ensures that the last + * Tx and Rx frames are both received. + */ + } + while ((status == IX_ETH_ACC_SUCCESS) + && (retry++ < IX_ETH_ACC_MAX_RETRY) + && ((*txState == TRANSMIT) + || (*rxState == REPLENISH) + || (ixEthAccPortDisableUserBufferCount[portId] != 0))); + + /* Step 5 : check the final states : the NPE has + * no buffer left, nor in Tx , nor in Rx directions. + */ + if ((*rxState == REPLENISH) || (*txState == TRANSMIT)) + { + status = IX_ETH_ACC_FAIL; + } + } + + /* now all the buffers are drained, disable NPE loopback + * This is done regardless of the logic to drain the queues and + * the internal buffers held by the NPE. + */ + if (ixEthAccNpeLoopbackDisablePriv(portId) != IX_ETH_ACC_SUCCESS) + { + status = IX_ETH_ACC_FAIL; + } + } + + /* disable MAC Tx and Rx services */ + ixEthAccMacState[portId].enabled = FALSE; + ixEthAccMacStateUpdate(portId); + + /* restore the Rx and TxDone callbacks (within a critical section) */ + key = ixOsalIrqLock(); + + ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn = ixEthAccPortDisableFn[portId]; + ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag = ixEthAccPortDisableCbTag[portId]; + ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn = ixEthAccPortDisableMultiBufferFn[portId]; + ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag = ixEthAccPortDisableMultiBufferCbTag[portId]; + ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn = ixEthAccPortDisableTxDoneFn[portId]; + ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag = ixEthAccPortDisableTxDoneCbTag[portId]; + + ixOsalIrqUnlock(key); + + /* the MAC core rx/tx disable may left the MAC hardware in an + * unpredictable state. A hw reset is executed before resetting + * all the MAC parameters to a known value. + */ + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_CORE_CNTRL, + IX_ETH_ACC_CORE_RESET); + + ixOsalSleep(IX_ETH_ACC_MAC_RESET_DELAY); + + /* rewrite all parameters to their current value */ + ixEthAccMacStateUpdate(portId); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_INT_CLK_THRESH, + IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_CORE_CNTRL, + IX_ETH_ACC_CORE_MDC_EN); + + return status; +} + +IxEthAccStatus +ixEthAccPortEnabledQueryPriv(IxEthAccPortId portId, BOOL *enabled) +{ + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable port.\n",(INT32)portId,0,0,0,0,0); + + /* Since Eth NPE is not available, port must be disabled */ + *enabled = FALSE ; + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + /* Since Eth NPE is not available, port must be disabled */ + *enabled = FALSE ; + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + *enabled = ixEthAccMacState[portId].enabled; + + return IX_ETH_ACC_SUCCESS; +} + +IxEthAccStatus +ixEthAccPortMacResetPriv(IxEthAccPortId portId) +{ + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot reset Ethernet coprocessor.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_CORE_CNTRL, + IX_ETH_ACC_CORE_RESET); + + ixOsalSleep(IX_ETH_ACC_MAC_RESET_DELAY); + + /* rewrite all parameters to their current value */ + ixEthAccMacStateUpdate(portId); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_INT_CLK_THRESH, + IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_CORE_CNTRL, + IX_ETH_ACC_CORE_MDC_EN); + + return IX_ETH_ACC_SUCCESS; +} + +IxEthAccStatus +ixEthAccPortLoopbackEnable(IxEthAccPortId portId) +{ + UINT32 regval; + + /* Turn off promiscuous mode */ + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable loopback.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + /* read register */ + REG_READ(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + regval); + + /* update register */ + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + regval | IX_ETH_ACC_RX_CNTRL1_LOOP_EN); + + return IX_ETH_ACC_SUCCESS; +} + +PRIVATE void +ixEthAccNpeLoopbackMessageCallback (IxNpeMhNpeId npeId, + IxNpeMhMessage msg) +{ + IxEthAccPortId portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId); + +#ifndef NDEBUG + /* Prudent to at least check the port is within range */ + if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS) + { + IX_ETH_ACC_FATAL_LOG("IXETHACC:ixEthAccPortDisableMessageCallback: Illegal port: %u\n", + (UINT32) portId, 0, 0, 0, 0, 0); + + return; + } +#endif + + /* unlock message reception mutex */ + ixOsalMutexUnlock(&ixEthAccMacState[portId].npeLoopbackMessageLock); +} + +IxEthAccStatus +ixEthAccNpeLoopbackEnablePriv(IxEthAccPortId portId) +{ + IX_STATUS npeMhStatus; + IxNpeMhMessage message; + IxEthAccStatus status = IX_ETH_ACC_SUCCESS; + + /* Turn off promiscuous mode */ + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable NPE loopback.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + /* enable NPE loopback (lsb of the message contains the value 1) */ + message.data[0] = (IX_ETHNPE_SETLOOPBACK_MODE << IX_ETH_ACC_MAC_MSGID_SHL) + | 0x01; + message.data[1] = 0; + + npeMhStatus = ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId), + message, + IX_ETHNPE_SETLOOPBACK_MODE_ACK, + ixEthAccNpeLoopbackMessageCallback, + IX_NPEMH_SEND_RETRIES_DEFAULT); + + if (npeMhStatus != IX_SUCCESS) + { + status = IX_ETH_ACC_FAIL; + } + else + { + /* wait for NPE loopbackEnable response */ + if (ixOsalMutexLock(&ixEthAccMacState[portId]. npeLoopbackMessageLock, + IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS) + != IX_SUCCESS) + { + status = IX_ETH_ACC_FAIL; + } + } + + return status; +} + +IxEthAccStatus +ixEthAccPortTxEnablePriv(IxEthAccPortId portId) +{ + UINT32 regval; + + /* Turn off promiscuous mode */ + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable TX.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + /* read register */ + REG_READ(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_TX_CNTRL1, + regval); + + /* update register */ + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_TX_CNTRL1, + regval | IX_ETH_ACC_TX_CNTRL1_TX_EN); + + return IX_ETH_ACC_SUCCESS; +} + +IxEthAccStatus +ixEthAccPortRxEnablePriv(IxEthAccPortId portId) +{ + UINT32 regval; + + /* Turn off promiscuous mode */ + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable RX.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + /* read register */ + REG_READ(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + regval); + + /* update register */ + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + regval | IX_ETH_ACC_RX_CNTRL1_RX_EN); + + return IX_ETH_ACC_SUCCESS; +} + +IxEthAccStatus +ixEthAccPortLoopbackDisable(IxEthAccPortId portId) +{ + UINT32 regval; + + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot disable loopback.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + /*disable MAC loopabck */ + REG_READ(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + regval); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + (regval & ~IX_ETH_ACC_RX_CNTRL1_LOOP_EN)); + + return IX_ETH_ACC_SUCCESS; +} + +IxEthAccStatus +ixEthAccNpeLoopbackDisablePriv(IxEthAccPortId portId) +{ + IX_STATUS npeMhStatus; + IxNpeMhMessage message; + IxEthAccStatus status = IX_ETH_ACC_SUCCESS; + + /* Turn off promiscuous mode */ + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable NPE loopback.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + /* disable NPE loopback (lsb of the message contains the value 0) */ + message.data[0] = (IX_ETHNPE_SETLOOPBACK_MODE << IX_ETH_ACC_MAC_MSGID_SHL); + message.data[1] = 0; + + npeMhStatus = ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId), + message, + IX_ETHNPE_SETLOOPBACK_MODE_ACK, + ixEthAccNpeLoopbackMessageCallback, + IX_NPEMH_SEND_RETRIES_DEFAULT); + + if (npeMhStatus != IX_SUCCESS) + { + status = IX_ETH_ACC_FAIL; + } + else + { + /* wait for NPE loopbackEnable response */ + if (ixOsalMutexLock(&ixEthAccMacState[portId].npeLoopbackMessageLock, + IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS) + != IX_SUCCESS) + { + status = IX_ETH_ACC_FAIL; + } + } + + return status; +} + +IxEthAccStatus +ixEthAccPortTxDisablePriv(IxEthAccPortId portId) +{ + UINT32 regval; + + /* Turn off promiscuous mode */ + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot disable TX.\n", (INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + /* read register */ + REG_READ(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_TX_CNTRL1, + regval); + + /* update register */ + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_TX_CNTRL1, + (regval & ~IX_ETH_ACC_TX_CNTRL1_TX_EN)); + + return IX_ETH_ACC_SUCCESS; +} + +IxEthAccStatus +ixEthAccPortRxDisablePriv(IxEthAccPortId portId) +{ + UINT32 regval; + + /* Turn off promiscuous mode */ + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot disable RX.\n", (INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + /* read register */ + REG_READ(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + regval); + + /* update register */ + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + (regval & ~IX_ETH_ACC_RX_CNTRL1_RX_EN)); + + return IX_ETH_ACC_SUCCESS; +} + +IxEthAccStatus +ixEthAccPortPromiscuousModeClearPriv(IxEthAccPortId portId) +{ + UINT32 regval; + + /* Turn off promiscuous mode */ + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot clear promiscuous mode.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + /*set bit 5 of Rx control 1 - enable address filtering*/ + REG_READ(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + regval); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + regval | IX_ETH_ACC_RX_CNTRL1_ADDR_FLTR_EN); + + ixEthAccMacState[portId].promiscuous = FALSE; + + ixEthAccMulticastAddressSet(portId); + + return IX_ETH_ACC_SUCCESS; +} + +IxEthAccStatus +ixEthAccPortPromiscuousModeSetPriv(IxEthAccPortId portId) +{ + UINT32 regval; + + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot set promiscuous mode.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + /* + * Set bit 5 of Rx control 1 - We enable address filtering even in + * promiscuous mode because we want the MAC to set the appropriate + * bits in m_flags which doesn't happen if we turn off filtering. + */ + REG_READ(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + regval); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + regval | IX_ETH_ACC_RX_CNTRL1_ADDR_FLTR_EN); + + ixEthAccMacState[portId].promiscuous = TRUE; + + ixEthAccMulticastAddressSet(portId); + + return IX_ETH_ACC_SUCCESS; +} + +IxEthAccStatus +ixEthAccPortUnicastMacAddressSetPriv (IxEthAccPortId portId, + IxEthAccMacAddr *macAddr) +{ + UINT32 i; + + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot set Unicast Mac Address.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + + if (macAddr == NULL) + { + return IX_ETH_ACC_FAIL; + } + + if ( macAddr->macAddress[0] & IX_ETH_ACC_ETH_MAC_BCAST_MCAST_BIT ) + { + /* This is a multicast/broadcast address cant set it ! */ + return IX_ETH_ACC_FAIL; + } + + if ( macAddr->macAddress[0] == 0 && + macAddr->macAddress[1] == 0 && + macAddr->macAddress[2] == 0 && + macAddr->macAddress[3] == 0 && + macAddr->macAddress[4] == 0 && + macAddr->macAddress[5] == 0 ) + { + /* This is an invalid mac address cant set it ! */ + return IX_ETH_ACC_FAIL; + } + +#ifdef CONFIG_IXP425_COMPONENT_ETHDB + /* update the MAC address in the ethernet database */ + if (ixEthDBPortAddressSet(portId, (IxEthDBMacAddr *) macAddr) != IX_ETH_DB_SUCCESS) + { + return IX_ETH_ACC_FAIL; + } +#endif + + /*Set the Unicast MAC to the specified value*/ + for(i=0;imacAddress[i]); + } + ixEthAccMacState[portId].initDone = TRUE; + + return IX_ETH_ACC_SUCCESS; +} + +IxEthAccStatus +ixEthAccPortUnicastMacAddressGetPriv (IxEthAccPortId portId, + IxEthAccMacAddr *macAddr) +{ + /*Return the current value of the Unicast MAC from h/w + for the specified port*/ + UINT32 i; + + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot get Unicast Mac Address.\n",(INT32)portId,0,0,0,0,0); + /* Since Eth Npe is unavailable, return invalid MAC Address = 00:00:00:00:00:00 */ + for(i=0;imacAddress[i] = 0; + } + return IX_ETH_ACC_SUCCESS ; + } + + if(!ixEthAccMacState[portId].initDone) + { + return (IX_ETH_ACC_MAC_UNINITIALIZED); + } + + if (macAddr == NULL) + { + return IX_ETH_ACC_FAIL; + } + + + for(i=0;imacAddress[i]); + } + return IX_ETH_ACC_SUCCESS; +} + +PRIVATE IxEthAccStatus +ixEthAccPortMulticastMacAddressGet (IxEthAccPortId portId, + IxEthAccMacAddr *macAddr) +{ + /*Return the current value of the Multicast MAC from h/w + for the specified port*/ + UINT32 i; + + for(i=0;imacAddress[i]); + } + + return IX_ETH_ACC_SUCCESS; +} + +PRIVATE IxEthAccStatus +ixEthAccPortMulticastMacFilterGet (IxEthAccPortId portId, + IxEthAccMacAddr *macAddr) +{ + /*Return the current value of the Multicast MAC from h/w + for the specified port*/ + UINT32 i; + + for(i=0;imacAddress[i]); + } + return IX_ETH_ACC_SUCCESS; +} + +IxEthAccStatus +ixEthAccPortMulticastAddressJoinPriv (IxEthAccPortId portId, + IxEthAccMacAddr *macAddr) +{ + UINT32 i; + IxEthAccMacAddr broadcastAddr = {{0xff,0xff,0xff,0xff,0xff,0xff}}; + + /*Check that the port parameter is valid*/ + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot join Multicast Mac Address.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + /*Check that the mac address is valid*/ + if(macAddr == NULL) + { + return IX_ETH_ACC_FAIL; + } + + /* Check that this is a multicast address */ + if (!(macAddr->macAddress[0] & IX_ETH_ACC_ETH_MAC_BCAST_MCAST_BIT)) + { + return IX_ETH_ACC_FAIL; + } + + /* We don't add the Broadcast address */ + if(ixEthAccMacEqual(&broadcastAddr, macAddr)) + { + return IX_ETH_ACC_FAIL; + } + + for (i = 0; + i= IX_ETH_ACC_MAX_MULTICAST_ADDRESSES) + { + return IX_ETH_ACC_FAIL; + } + + /*First add the address to the multicast table for the + specified port*/ + i=ixEthAccMacState[portId].mcastAddrIndex; + + memcpy(&ixEthAccMacState[portId].mcastAddrsTable[i], + &macAddr->macAddress, + IX_IEEE803_MAC_ADDRESS_SIZE); + + /*Increment the index into the table, this must be done here + as MulticastAddressSet below needs to know about the latest + entry. + */ + ixEthAccMacState[portId].mcastAddrIndex++; + + /*Then calculate the new value to be written to the address and + address mask registers*/ + ixEthAccMulticastAddressSet(portId); + + return IX_ETH_ACC_SUCCESS; +} + + +IxEthAccStatus +ixEthAccPortMulticastAddressJoinAllPriv (IxEthAccPortId portId) +{ + IxEthAccMacAddr mcastMacAddr = {{0x1,0x0,0x0,0x0,0x0,0x0}}; + + /*Check that the port parameter is valid*/ + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot join all Multicast Address.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + /* remove all entries from the database and + * insert a multicast entry + */ + memcpy(&ixEthAccMacState[portId].mcastAddrsTable[0], + &mcastMacAddr.macAddress, + IX_IEEE803_MAC_ADDRESS_SIZE); + + ixEthAccMacState[portId].mcastAddrIndex = 1; + ixEthAccMacState[portId].joinAll = TRUE; + + ixEthAccMulticastAddressSet(portId); + + return IX_ETH_ACC_SUCCESS; +} + +IxEthAccStatus +ixEthAccPortMulticastAddressLeavePriv (IxEthAccPortId portId, + IxEthAccMacAddr *macAddr) +{ + UINT32 i; + IxEthAccMacAddr mcastMacAddr = {{0x1,0x0,0x0,0x0,0x0,0x0}}; + + /*Check that the port parameter is valid*/ + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot leave Multicast Address.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + /*Check that the mac address is valid*/ + if(macAddr == NULL) + { + return IX_ETH_ACC_FAIL; + } + /* Remove this mac address from the mask for the specified port + * we copy down all entries above the blanked entry, and + * decrement the index + */ + i=0; + + while(i= IX_ETH_ACC_NUMBER_OF_PORTS) + { + IX_ETH_ACC_FATAL_LOG( + "IXETHACC:ixEthAccMacNpeStatsMessageCallback: Illegal port: %u\n", + (UINT32)portId, 0, 0, 0, 0, 0); + return; + } +#endif + + /*Unblock Stats Get call*/ + ixOsalMutexUnlock(&ixEthAccMacState[portId].ackMIBStatsLock); + +} + +PRIVATE void +ixEthAccMibIIStatsEndianConvert (IxEthEthObjStats *retStats) +{ + /* endianness conversion */ + + /* Rx stats */ + retStats->dot3StatsAlignmentErrors = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsAlignmentErrors); + retStats->dot3StatsFCSErrors = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsFCSErrors); + retStats->dot3StatsInternalMacReceiveErrors = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsInternalMacReceiveErrors); + retStats->RxOverrunDiscards = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxOverrunDiscards); + retStats->RxLearnedEntryDiscards = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxLearnedEntryDiscards); + retStats->RxLargeFramesDiscards = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxLargeFramesDiscards); + retStats->RxSTPBlockedDiscards = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxSTPBlockedDiscards); + retStats->RxVLANTypeFilterDiscards = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxVLANTypeFilterDiscards); + retStats->RxVLANIdFilterDiscards = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxVLANIdFilterDiscards); + retStats->RxInvalidSourceDiscards = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxInvalidSourceDiscards); + retStats->RxBlackListDiscards = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxBlackListDiscards); + retStats->RxWhiteListDiscards = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxWhiteListDiscards); + retStats->RxUnderflowEntryDiscards = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxUnderflowEntryDiscards); + + /* Tx stats */ + retStats->dot3StatsSingleCollisionFrames = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsSingleCollisionFrames); + retStats->dot3StatsMultipleCollisionFrames = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsMultipleCollisionFrames); + retStats->dot3StatsDeferredTransmissions = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsDeferredTransmissions); + retStats->dot3StatsLateCollisions = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsLateCollisions); + retStats->dot3StatsExcessiveCollsions = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsExcessiveCollsions); + retStats->dot3StatsInternalMacTransmitErrors = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsInternalMacTransmitErrors); + retStats->dot3StatsCarrierSenseErrors = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsCarrierSenseErrors); + retStats->TxLargeFrameDiscards = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->TxLargeFrameDiscards); + retStats->TxVLANIdFilterDiscards = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->TxVLANIdFilterDiscards); +} + +IxEthAccStatus +ixEthAccMibIIStatsGet (IxEthAccPortId portId, + IxEthEthObjStats *retStats ) +{ + IxNpeMhMessage message; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + printf("EthAcc: ixEthAccMibIIStatsGet (Mac) EthAcc service is not initialized\n"); + return (IX_ETH_ACC_FAIL); + } + + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (retStats == NULL) + { + printf("EthAcc: ixEthAccMibIIStatsGet (Mac) NULL argument\n"); + return (IX_ETH_ACC_FAIL); + } + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + printf("EthAcc: ixEthAccMibIIStatsGet (Mac) NPE for port %d is not available\n", portId); + + IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot get MIB II Stats.\n",(INT32)portId,0,0,0,0,0); + + /* Return all zero stats */ + IX_ETH_ACC_MEMSET(retStats, 0, sizeof(IxEthEthObjStats)); + + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + printf("EthAcc: ixEthAccMibIIStatsGet (Mac) port %d is not initialized\n", portId); + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + IX_OSAL_CACHE_INVALIDATE(retStats, sizeof(IxEthEthObjStats)); + + message.data[0] = IX_ETHNPE_GETSTATS << IX_ETH_ACC_MAC_MSGID_SHL; + message.data[1] = (UINT32) IX_OSAL_MMU_VIRT_TO_PHYS(retStats); + + /* Permit only one task to request MIB statistics Get operation + at a time */ + ixOsalMutexLock(&ixEthAccMacState[portId].MIBStatsGetAccessLock, IX_OSAL_WAIT_FOREVER); + + if(ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId), + message, + IX_ETHNPE_GETSTATS, + ixEthAccMacNpeStatsMessageCallback, + IX_NPEMH_SEND_RETRIES_DEFAULT) + != IX_SUCCESS) + { + ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetAccessLock); + + printf("EthAcc: (Mac) StatsGet failed to send NPE message\n"); + + return IX_ETH_ACC_FAIL; + } + + /* Wait for callback invocation indicating response to + this request - we need this mutex in order to ensure + that the return from this function is synchronous */ + ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsLock, IX_ETH_ACC_MIB_STATS_DELAY_MSECS); + + /* Permit other tasks to perform MIB statistics Get operation */ + ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetAccessLock); + + ixEthAccMibIIStatsEndianConvert (retStats); + + return IX_ETH_ACC_SUCCESS; +} + + +PRIVATE void +ixEthAccMacNpeStatsResetMessageCallback (IxNpeMhNpeId npeId, + IxNpeMhMessage msg) +{ + IxEthAccPortId portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId); + +#ifndef NDEBUG + /* Prudent to at least check the port is within range */ + if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS) + { + IX_ETH_ACC_FATAL_LOG( + "IXETHACC:ixEthAccMacNpeStatsResetMessageCallback: Illegal port: %u\n", + (UINT32)portId, 0, 0, 0, 0, 0); + return; + } +#endif + + /*Unblock Stats Get & reset call*/ + ixOsalMutexUnlock(&ixEthAccMacState[portId].ackMIBStatsResetLock); + +} + + + +IxEthAccStatus +ixEthAccMibIIStatsGetClear (IxEthAccPortId portId, + IxEthEthObjStats *retStats) +{ + IxNpeMhMessage message; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) EthAcc service is not initialized\n"); + return (IX_ETH_ACC_FAIL); + } + + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (retStats == NULL) + { + printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) NULL argument\n"); + return (IX_ETH_ACC_FAIL); + } + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) NPE for port %d is not available\n", portId); + + IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot get and clear MIB II Stats.\n", (INT32)portId, 0, 0, 0, 0, 0); + + /* Return all zero stats */ + IX_ETH_ACC_MEMSET(retStats, 0, sizeof(IxEthEthObjStats)); + + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) port %d is not initialized\n", portId); + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + IX_OSAL_CACHE_INVALIDATE(retStats, sizeof(IxEthEthObjStats)); + + message.data[0] = IX_ETHNPE_RESETSTATS << IX_ETH_ACC_MAC_MSGID_SHL; + message.data[1] = (UINT32) IX_OSAL_MMU_VIRT_TO_PHYS(retStats); + + /* Permit only one task to request MIB statistics Get-Reset operation at a time */ + ixOsalMutexLock(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock, IX_OSAL_WAIT_FOREVER); + + if(ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId), + message, + IX_ETHNPE_RESETSTATS, + ixEthAccMacNpeStatsResetMessageCallback, + IX_NPEMH_SEND_RETRIES_DEFAULT) + != IX_SUCCESS) + { + ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock); + + printf("EthAcc: (Mac) ixEthAccMibIIStatsGetClear failed to send NPE message\n"); + + return IX_ETH_ACC_FAIL; + } + + /* Wait for callback invocation indicating response to this request */ + ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsResetLock, IX_ETH_ACC_MIB_STATS_DELAY_MSECS); + + /* permit other tasks to get and reset MIB stats*/ + ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock); + + ixEthAccMibIIStatsEndianConvert(retStats); + + return IX_ETH_ACC_SUCCESS; +} + +IxEthAccStatus +ixEthAccMibIIStatsClear (IxEthAccPortId portId) +{ + static IxEthEthObjStats retStats; + IxEthAccStatus status; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot clear MIB II Stats.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + /* there is no reset operation without a corresponding Get */ + status = ixEthAccMibIIStatsGetClear(portId, &retStats); + + return status; +} + +/* Initialize the ethernet MAC settings */ +IxEthAccStatus +ixEthAccMacInit(IxEthAccPortId portId) +{ + IX_OSAL_MBUF_POOL* portDisablePool; + UINT8 *data; + + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot initialize Mac.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if(ixEthAccMacState[portId].macInitialised == FALSE) + { + ixEthAccMacState[portId].fullDuplex = TRUE; + ixEthAccMacState[portId].rxFCSAppend = TRUE; + ixEthAccMacState[portId].txFCSAppend = TRUE; + ixEthAccMacState[portId].txPADAppend = TRUE; + ixEthAccMacState[portId].enabled = FALSE; + ixEthAccMacState[portId].promiscuous = TRUE; + ixEthAccMacState[portId].joinAll = FALSE; + ixEthAccMacState[portId].initDone = FALSE; + ixEthAccMacState[portId].macInitialised = TRUE; + + /* initialize MIB stats mutexes */ + ixOsalMutexInit(&ixEthAccMacState[portId].ackMIBStatsLock); + ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsLock, IX_OSAL_WAIT_FOREVER); + + ixOsalMutexInit(&ixEthAccMacState[portId].ackMIBStatsResetLock); + ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsResetLock, IX_OSAL_WAIT_FOREVER); + + ixOsalMutexInit(&ixEthAccMacState[portId].MIBStatsGetAccessLock); + + ixOsalMutexInit(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock); + + ixOsalMutexInit(&ixEthAccMacState[portId].npeLoopbackMessageLock); + + ixEthAccMacState[portId].portDisableRxMbufPtr = NULL; + ixEthAccMacState[portId].portDisableTxMbufPtr = NULL; + + portDisablePool = IX_OSAL_MBUF_POOL_INIT(2, + IX_ETHACC_RX_MBUF_MIN_SIZE, + "portDisable Pool"); + + IX_OSAL_ENSURE(portDisablePool != NULL, "Failed to initialize PortDisable pool"); + + ixEthAccMacState[portId].portDisableRxMbufPtr = IX_OSAL_MBUF_POOL_GET(portDisablePool); + ixEthAccMacState[portId].portDisableTxMbufPtr = IX_OSAL_MBUF_POOL_GET(portDisablePool); + + IX_OSAL_ENSURE(ixEthAccMacState[portId].portDisableRxMbufPtr != NULL, + "Pool allocation failed"); + IX_OSAL_ENSURE(ixEthAccMacState[portId].portDisableTxMbufPtr != NULL, + "Pool allocation failed"); + /* fill the payload of the Rx mbuf used in portDisable */ + IX_OSAL_MBUF_MLEN(ixEthAccMacState[portId].portDisableRxMbufPtr) = IX_ETHACC_RX_MBUF_MIN_SIZE; + + memset(IX_OSAL_MBUF_MDATA(ixEthAccMacState[portId].portDisableRxMbufPtr), + 0xAA, + IX_ETHACC_RX_MBUF_MIN_SIZE); + + /* fill the payload of the Tx mbuf used in portDisable (64 bytes) */ + IX_OSAL_MBUF_MLEN(ixEthAccMacState[portId].portDisableTxMbufPtr) = 64; + IX_OSAL_MBUF_PKT_LEN(ixEthAccMacState[portId].portDisableTxMbufPtr) = 64; + + data = (UINT8 *) IX_OSAL_MBUF_MDATA(ixEthAccMacState[portId].portDisableTxMbufPtr); + memset(data, 0xBB, 64); + data[0] = 0x00; /* unicast destination MAC address */ + data[6] = 0x00; /* unicast source MAC address */ + data[12] = 0x08; /* typelength : IP frame */ + data[13] = 0x00; /* typelength : IP frame */ + + IX_OSAL_CACHE_FLUSH(data, 64); + } + + IX_OSAL_ASSERT (ixEthAccMacBase[portId] != 0); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_CORE_CNTRL, + IX_ETH_ACC_CORE_RESET); + + ixOsalSleep(IX_ETH_ACC_MAC_RESET_DELAY); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_CORE_CNTRL, + IX_ETH_ACC_CORE_MDC_EN); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_INT_CLK_THRESH, + IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT); + + ixEthAccMacStateUpdate(portId); + + return IX_ETH_ACC_SUCCESS; +} + +/* PRIVATE Functions*/ + +PRIVATE void +ixEthAccMacStateUpdate(IxEthAccPortId portId) +{ + UINT32 regval; + + if ( ixEthAccMacState[portId].enabled == FALSE ) + { + /* Just disable both the transmitter and reciver in the MAC. */ + REG_READ(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + regval); + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + regval & ~IX_ETH_ACC_RX_CNTRL1_RX_EN); + + REG_READ(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_TX_CNTRL1, + regval); + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_TX_CNTRL1, + regval & ~IX_ETH_ACC_TX_CNTRL1_TX_EN); + } + + if(ixEthAccMacState[portId].fullDuplex) + { + ixEthAccPortDuplexModeSetPriv (portId, IX_ETH_ACC_FULL_DUPLEX); + } + else + { + ixEthAccPortDuplexModeSetPriv (portId, IX_ETH_ACC_HALF_DUPLEX); + } + + if(ixEthAccMacState[portId].rxFCSAppend) + { + ixEthAccPortRxFrameAppendFCSEnablePriv (portId); + } + else + { + ixEthAccPortRxFrameAppendFCSDisablePriv (portId); + } + + if(ixEthAccMacState[portId].txFCSAppend) + { + ixEthAccPortTxFrameAppendFCSEnablePriv (portId); + } + else + { + ixEthAccPortTxFrameAppendFCSDisablePriv (portId); + } + + if(ixEthAccMacState[portId].txPADAppend) + { + ixEthAccPortTxFrameAppendPaddingEnablePriv (portId); + } + else + { + ixEthAccPortTxFrameAppendPaddingDisablePriv (portId); + } + + if(ixEthAccMacState[portId].promiscuous) + { + ixEthAccPortPromiscuousModeSetPriv(portId); + } + else + { + ixEthAccPortPromiscuousModeClearPriv(portId); + } + + if ( ixEthAccMacState[portId].enabled == TRUE ) + { + /* Enable both the transmitter and reciver in the MAC. */ + REG_READ(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + regval); + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + regval | IX_ETH_ACC_RX_CNTRL1_RX_EN); + + REG_READ(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_TX_CNTRL1, + regval); + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_TX_CNTRL1, + regval | IX_ETH_ACC_TX_CNTRL1_TX_EN); + } +} + + +PRIVATE BOOL +ixEthAccMacEqual(IxEthAccMacAddr *macAddr1, + IxEthAccMacAddr *macAddr2) +{ + UINT32 i; + for(i=0;imacAddress[i] != macAddr2->macAddress[i]) + { + return FALSE; + } + } + return TRUE; +} + +PRIVATE void +ixEthAccMacPrint(IxEthAccMacAddr *m) +{ + printf("%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x", + m->macAddress[0], m->macAddress[1], + m->macAddress[2], m->macAddress[3], + m->macAddress[4], m->macAddress[5]); +} + +/* Set the multicast address and address mask registers + * + * A bit in the address mask register must be set if + * all multicast addresses always have that bit set, or if + * all multicast addresses always have that bit cleared. + * + * A bit in the address register must be set if all multicast + * addresses have that bit set, otherwise, it should be cleared + */ + +PRIVATE void +ixEthAccMulticastAddressSet(IxEthAccPortId portId) +{ + UINT32 i; + UINT32 j; + IxEthAccMacAddr addressMask; + IxEthAccMacAddr address; + IxEthAccMacAddr alwaysClearBits; + IxEthAccMacAddr alwaysSetBits; + + /* calculate alwaysClearBits and alwaysSetBits: + * alwaysClearBits is calculated by ORing all + * multicast addresses, those bits that are always + * clear are clear in the result + * + * alwaysSetBits is calculated by ANDing all + * multicast addresses, those bits that are always set + * are set in the result + */ + + if (ixEthAccMacState[portId].promiscuous == TRUE) + { + /* Promiscuous Mode is set, and filtering + * allow all packets, and enable the mcast and + * bcast detection. + */ + memset(&addressMask.macAddress, + 0, + IX_IEEE803_MAC_ADDRESS_SIZE); + memset(&address.macAddress, + 0, + IX_IEEE803_MAC_ADDRESS_SIZE); + } + else + { + if(ixEthAccMacState[portId].joinAll == TRUE) + { + /* Join all is set. The mask and address are + * the multicast settings. + */ + IxEthAccMacAddr macAddr = {{0x1,0x0,0x0,0x0,0x0,0x0}}; + + memcpy(addressMask.macAddress, + macAddr.macAddress, + IX_IEEE803_MAC_ADDRESS_SIZE); + memcpy(address.macAddress, + macAddr.macAddress, + IX_IEEE803_MAC_ADDRESS_SIZE); + } + else if(ixEthAccMacState[portId].mcastAddrIndex == 0) + { + /* No entry in the filtering database, + * Promiscuous Mode is cleared, Broadcast filtering + * is configured. + */ + memset(addressMask.macAddress, + IX_ETH_ACC_MAC_ALL_BITS_SET, + IX_IEEE803_MAC_ADDRESS_SIZE); + memset(address.macAddress, + IX_ETH_ACC_MAC_ALL_BITS_SET, + IX_IEEE803_MAC_ADDRESS_SIZE); + } + else + { + /* build a mask and an address which mix all entreis + * from the list of multicast addresses + */ + memset(alwaysClearBits.macAddress, + 0, + IX_IEEE803_MAC_ADDRESS_SIZE); + memset(alwaysSetBits.macAddress, + IX_ETH_ACC_MAC_ALL_BITS_SET, + IX_IEEE803_MAC_ADDRESS_SIZE); + + for(i=0;i> 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; +} + diff --git a/arch/arm/cpu/ixp/npe/IxEthDBAPI.c b/arch/arm/cpu/ixp/npe/IxEthDBAPI.c new file mode 100644 index 0000000000..b2bfb72606 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxEthDBAPI.c @@ -0,0 +1,448 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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; +} diff --git a/arch/arm/cpu/ixp/npe/IxEthDBAPISupport.c b/arch/arm/cpu/ixp/npe/IxEthDBAPISupport.c new file mode 100644 index 0000000000..25633a3d56 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxEthDBAPISupport.c @@ -0,0 +1,678 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#include +#include +#include + +#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; + IxOsalMutex *ackPortAddressLock; + 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; + } + + ackPortAddressLock = &ixEthDBPortInfo[portID].npeAckLock; + + /* 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; +} diff --git a/arch/arm/cpu/ixp/npe/IxEthDBCore.c b/arch/arm/cpu/ixp/npe/IxEthDBCore.c new file mode 100644 index 0000000000..25b7cbb8b8 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxEthDBCore.c @@ -0,0 +1,463 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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; +} diff --git a/arch/arm/cpu/ixp/npe/IxEthDBEvents.c b/arch/arm/cpu/ixp/npe/IxEthDBEvents.c new file mode 100644 index 0000000000..4d44e03337 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxEthDBEvents.c @@ -0,0 +1,520 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#include +#include + +#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); +} + diff --git a/arch/arm/cpu/ixp/npe/IxEthDBFeatures.c b/arch/arm/cpu/ixp/npe/IxEthDBFeatures.c new file mode 100644 index 0000000000..7a58d268ca --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxEthDBFeatures.c @@ -0,0 +1,662 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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 < sizeof (ixEthDBTrafficClassDefinitions) / sizeof (ixEthDBTrafficClassDefinitions[0]); + 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 == sizeof (ixEthDBTrafficClassDefinitions) / sizeof (ixEthDBTrafficClassDefinitions[0])) + { + 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; +} diff --git a/arch/arm/cpu/ixp/npe/IxEthDBFirewall.c b/arch/arm/cpu/ixp/npe/IxEthDBFirewall.c new file mode 100644 index 0000000000..eb46174b6c --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxEthDBFirewall.c @@ -0,0 +1,266 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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; +} diff --git a/arch/arm/cpu/ixp/npe/IxEthDBHashtable.c b/arch/arm/cpu/ixp/npe/IxEthDBHashtable.c new file mode 100644 index 0000000000..f1b18e6b48 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxEthDBHashtable.c @@ -0,0 +1,642 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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 entry 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 reference and places the + * pointer to the resulting node in searchResult. + * 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 IX_ETH_DB_SUCCESS 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 reference. + * 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; +} + +/** + * @} + */ diff --git a/arch/arm/cpu/ixp/npe/IxEthDBLearning.c b/arch/arm/cpu/ixp/npe/IxEthDBLearning.c new file mode 100644 index 0000000000..2287dbe96c --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxEthDBLearning.c @@ -0,0 +1,149 @@ +/** + * @file IxEthDBLearning.c + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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; +} + diff --git a/arch/arm/cpu/ixp/npe/IxEthDBMem.c b/arch/arm/cpu/ixp/npe/IxEthDBMem.c new file mode 100644 index 0000000000..133cbef8d6 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxEthDBMem.c @@ -0,0 +1,649 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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, its associated descriptor + * and recursively of all its child nodes. + * + * @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 + */ diff --git a/arch/arm/cpu/ixp/npe/IxEthDBNPEAdaptor.c b/arch/arm/cpu/ixp/npe/IxEthDBNPEAdaptor.c new file mode 100644 index 0000000000..112a46c998 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxEthDBNPEAdaptor.c @@ -0,0 +1,719 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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 diff --git a/arch/arm/cpu/ixp/npe/IxEthDBPortUpdate.c b/arch/arm/cpu/ixp/npe/IxEthDBPortUpdate.c new file mode 100644 index 0000000000..cdf114bfc4 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxEthDBPortUpdate.c @@ -0,0 +1,740 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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 route balanced + * not perfectly balanced. 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; +} + diff --git a/arch/arm/cpu/ixp/npe/IxEthDBReports.c b/arch/arm/cpu/ixp/npe/IxEthDBReports.c new file mode 100644 index 0000000000..9c7ae1cc6a --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxEthDBReports.c @@ -0,0 +1,652 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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; +} + diff --git a/arch/arm/cpu/ixp/npe/IxEthDBSearch.c b/arch/arm/cpu/ixp/npe/IxEthDBSearch.c new file mode 100644 index 0000000000..4a10878b68 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxEthDBSearch.c @@ -0,0 +1,327 @@ +/** + * @file IxEthDBSearch.c + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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; +} diff --git a/arch/arm/cpu/ixp/npe/IxEthDBSpanningTree.c b/arch/arm/cpu/ixp/npe/IxEthDBSpanningTree.c new file mode 100644 index 0000000000..6d9fd6ec18 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxEthDBSpanningTree.c @@ -0,0 +1,107 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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; +} diff --git a/arch/arm/cpu/ixp/npe/IxEthDBUtil.c b/arch/arm/cpu/ixp/npe/IxEthDBUtil.c new file mode 100644 index 0000000000..e708bf1bce --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxEthDBUtil.c @@ -0,0 +1,120 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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; +} diff --git a/arch/arm/cpu/ixp/npe/IxEthDBVlan.c b/arch/arm/cpu/ixp/npe/IxEthDBVlan.c new file mode 100644 index 0000000000..e2efb9b339 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxEthDBVlan.c @@ -0,0 +1,1179 @@ +/** + * @file IxEthDBVlan.c + * + * @brief Implementation of the VLAN API + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#include "IxEthDB.h" +#include "IxEthDB_p.h" + +/* forward prototypes */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBUpdateTrafficClass(IxEthDBPortId portID, UINT32 classIndex); +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBVlanTableGet(IxEthDBPortId portID, IxEthDBVlanSet portVlanTable, IxEthDBVlanSet vlanSet); + +/* contants used by various functions as "action" parameter */ +#define ADD_VLAN (0x1) +#define REMOVE_VLAN (0x2) + +/** + * @brief adds or removes a VLAN from a VLAN set + * + * @param vlanID VLAN ID to add or remove + * @param table VLAN set to add into or remove from + * @param action ADD_VLAN or REMOVE_VLAN + * + * @internal + */ +IX_ETH_DB_PRIVATE +void ixEthDBLocalVlanMembershipChange(UINT32 vlanID, IxEthDBVlanSet table, UINT32 action) +{ + UINT32 setOffset; + + /* add/remove VID to membership table */ + setOffset = VLAN_SET_OFFSET(vlanID); /* we need 9 bits to index the 512 byte membership array */ + + if (action == ADD_VLAN) + { + table[setOffset] |= 1 << VLAN_SET_MASK(vlanID); + } + else if (action == REMOVE_VLAN) + { + table[setOffset] &= ~(1 << VLAN_SET_MASK(vlanID)); + } +} + +/** + * @brief updates a set of 8 VLANs in an NPE + * + * @param portID ID of the port + * @param setOffset offset of the 8 VLANs + * + * This function updates the VLAN membership table + * and Transmit Tagging Info table for 8 consecutive + * VLAN IDs indexed by setOffset. + * + * For example, a setOffset of 0 indexes VLAN IDs 0 + * through 7, 1 indexes VLAN IDs 8 through 9 etc. + * + * @return IX_ETH_DB_SUCCESS if the operation completed + * successfully or an appropriate error message otherwise + * + * @internal + */ +IX_ETH_DB_PRIVATE +IxEthDBStatus ixEthDBVlanTableEntryUpdate(IxEthDBPortId portID, UINT32 setOffset) +{ + PortInfo *portInfo = &ixEthDBPortInfo[portID]; + IxNpeMhMessage message; + IX_STATUS result; + + FILL_SETPORTVLANTABLEENTRY_MSG(message, IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), + 2 * setOffset, + portInfo->vlanMembership[setOffset], + portInfo->transmitTaggingInfo[setOffset]); + + IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); + + return result; +} + +/** + * @brief updates a VLAN range in an NPE + * + * @param portID ID of the port + * + * This function is similar to @ref ixEthDBVlanTableEntryUpdate + * except that it can update more than one VLAN set (up to + * the entire VLAN membership and TTI tables if the offset is 0 + * and length is sizeof (IxEthDBVlanSet) (512 bytes). + * + * Updating the NPE via this method is slower as it requires + * a memory copy from SDRAM, hence it is recommended that the + * ixEthDBVlanTableEntryUpdate function is used where possible. + * + * @return IX_ETH_DB_SUCCESS if the operation completed + * successfully or an appropriate error message otherwise + * + * @internal + */ +IX_ETH_DB_PRIVATE +IxEthDBStatus ixEthDBVlanTableRangeUpdate(IxEthDBPortId portID) +{ + PortInfo *portInfo = &ixEthDBPortInfo[portID]; + UINT8 *vlanUpdateZone = (UINT8 *) portInfo->updateMethod.vlanUpdateZone; + IxNpeMhMessage message; + UINT32 setIndex; + IX_STATUS result; + + /* copy membership info and transmit tagging into into exchange area */ + for (setIndex = 0 ; setIndex < sizeof (portInfo->vlanMembership) ; setIndex++) + { + /* membership and TTI data are interleaved */ + vlanUpdateZone[setIndex * 2] = portInfo->vlanMembership[setIndex]; + vlanUpdateZone[setIndex * 2 + 1] = portInfo->transmitTaggingInfo[setIndex]; + } + + IX_OSAL_CACHE_FLUSH(vlanUpdateZone, FULL_VLAN_BYTE_SIZE); + + /* build NPE message */ + FILL_SETPORTVLANTABLERANGE_MSG(message, IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), 0, 0, + IX_OSAL_MMU_VIRT_TO_PHYS(vlanUpdateZone)); + + /* send message */ + IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); + + return result; +} + +/** + * @brief adds or removes a VLAN from a port's VLAN membership table + * or Transmit Tagging Information table + * + * @param portID ID of the port + * @param vlanID VLAN ID to add or remove + * @param table to add or remove from + * @param action ADD_VLAN or REMOVE_VLAN + * + * @return IX_ETH_DB_SUCCESS if the operation completed + * successfully or an appropriate error message otherwise + * + * @internal + */ +IX_ETH_DB_PRIVATE +IxEthDBStatus ixEthDBPortVlanMembershipChange(IxEthDBPortId portID, IxEthDBVlanId vlanID, IxEthDBVlanSet table, UINT32 action) +{ + /* change VLAN in local membership table */ + ixEthDBLocalVlanMembershipChange(vlanID, table, action); + + /* send updated entry to NPE */ + return ixEthDBVlanTableEntryUpdate(portID, VLAN_SET_OFFSET(vlanID)); +} + +/** + * @brief sets the default port VLAN tag (the lower 3 bytes are the PVID) + * + * @param portID ID of the port + * @param vlanTag port VLAN tag (802.1Q tag) + * + * 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 ixEthDBPortVlanTagSet(IxEthDBPortId portID, IxEthDBVlanTag vlanTag) +{ + IxNpeMhMessage message; + IX_STATUS result; + + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_VLAN_TAG(vlanTag); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + /* add VLAN ID to local membership table */ + ixEthDBPortVlanMembershipChange(portID, + vlanTag & IX_ETH_DB_802_1Q_VLAN_MASK, + ixEthDBPortInfo[portID].vlanMembership, + ADD_VLAN); + + /* set tag in portInfo */ + ixEthDBPortInfo[portID].vlanTag = vlanTag; + + /* build VLAN_SetDefaultRxVID message */ + FILL_SETDEFAULTRXVID_MSG(message, + IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), + IX_IEEE802_1Q_VLAN_TPID, + vlanTag); + + IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); + + return result; +} + +/** + * @brief retrieves the default port VLAN tag (the lower 3 bytes are the PVID) + * + * @param portID ID of the port + * @param vlanTag address to write the port VLAN tag (802.1Q tag) 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 ixEthDBPortVlanTagGet(IxEthDBPortId portID, IxEthDBVlanTag *vlanTag) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + IX_ETH_DB_CHECK_REFERENCE(vlanTag); + + *vlanTag = ixEthDBPortInfo[portID].vlanTag; + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief sets the VLAN tag (the lower 3 bytes are the PVID) of a + * database filtering record + * + * @param portID ID of the port + * @param vlanTag VLAN tag (802.1Q tag) + * + * Important: filtering records are automatically converted to + * IX_ETH_DB_FILTERING_VLAN record when added a VLAN tag. + * + * 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 ixEthDBVlanTagSet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag vlanTag) +{ + HashNode *searchResult; + MacDescriptor *descriptor; + + IX_ETH_DB_CHECK_REFERENCE(macAddr); + + IX_ETH_DB_CHECK_VLAN_TAG(vlanTag); + + searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS); + + if (searchResult == NULL) + { + return IX_ETH_DB_NO_SUCH_ADDR; + } + + descriptor = (MacDescriptor *) searchResult->data; + + /* set record type to VLAN if not already set */ + descriptor->type = IX_ETH_DB_FILTERING_VLAN_RECORD; + + /* add vlan tag */ + descriptor->recordData.filteringVlanData.ieee802_1qTag = vlanTag; + + /* transaction completed */ + ixEthDBReleaseHashNode(searchResult); + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief retrieves the VLAN tag (the lower 3 bytes are the PVID) from a + * database VLAN filtering record + * + * @param portID ID of the port + * @param vlanTag address to write the VLAN tag (802.1Q tag) 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 ixEthDBVlanTagGet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag *vlanTag) +{ + HashNode *searchResult; + MacDescriptor *descriptor; + + IX_ETH_DB_CHECK_REFERENCE(macAddr); + + IX_ETH_DB_CHECK_REFERENCE(vlanTag); + + searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_FILTERING_VLAN_RECORD); + + if (searchResult == NULL) + { + return IX_ETH_DB_NO_SUCH_ADDR; + } + + descriptor = (MacDescriptor *) searchResult->data; + + /* get vlan tag */ + *vlanTag = descriptor->recordData.filteringVlanData.ieee802_1qTag; + + /* transaction completed */ + ixEthDBReleaseHashNode(searchResult); + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief adds a VLAN to a port's VLAN membership table + * + * @param portID ID of the port + * @param vlanID VLAN ID to add + * + * 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 ixEthDBPortVlanMembershipAdd(IxEthDBPortId portID, IxEthDBVlanId vlanID) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_VLAN_ID(vlanID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + return ixEthDBPortVlanMembershipChange(portID, vlanID, ixEthDBPortInfo[portID].vlanMembership, ADD_VLAN); +} + +/** + * @brief removes a VLAN from a port's VLAN membership table + * + * @param portID ID of the port + * @param vlanID VLAN ID 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 ixEthDBPortVlanMembershipRemove(IxEthDBPortId portID, IxEthDBVlanId vlanID) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + IX_ETH_DB_CHECK_VLAN_ID(vlanID); + + /* for safety isolate only the VLAN ID in the tag (the lower 12 bits) */ + vlanID = vlanID & IX_ETH_DB_802_1Q_VLAN_MASK; + + /* check we're not asked to remove the default port VID */ + if (vlanID == IX_ETH_DB_GET_VLAN_ID(ixEthDBPortInfo[portID].vlanTag)) + { + return IX_ETH_DB_NO_PERMISSION; + } + + return ixEthDBPortVlanMembershipChange(portID, vlanID, ixEthDBPortInfo[portID].vlanMembership, REMOVE_VLAN); +} + +/** + * @brief adds or removes a VLAN range from a port's + * VLAN membership table or TTI table + * + * @param portID ID of the port + * @param vlanIDMin start of the VLAN range + * @param vlanIDMax end of the VLAN range + * @param table VLAN set to add or remove from + * @param action ADD_VLAN or REMOVE_VLAN + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + * + * @internal + */ +IX_ETH_DB_PRIVATE +IxEthDBStatus ixEthDBPortVlanMembershipRangeChange(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax, IxEthDBVlanSet table, UINT32 action) +{ + UINT32 setOffsetMin, setOffsetMax; + + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + IX_ETH_DB_CHECK_VLAN_ID(vlanIDMin); + + IX_ETH_DB_CHECK_VLAN_ID(vlanIDMax); + + /* for safety isolate only the VLAN ID in the tags (the lower 12 bits) */ + vlanIDMin = vlanIDMin & IX_ETH_DB_802_1Q_VLAN_MASK; + vlanIDMax = vlanIDMax & IX_ETH_DB_802_1Q_VLAN_MASK; + + /* is this a range? */ + if (vlanIDMax < vlanIDMin) + { + return IX_ETH_DB_INVALID_VLAN; + } + + /* check that we're not specifically asked to remove the default port VID */ + if (action == REMOVE_VLAN && vlanIDMax == vlanIDMin && IX_ETH_DB_GET_VLAN_ID(ixEthDBPortInfo[portID].vlanTag) == vlanIDMin) + { + return IX_ETH_DB_NO_PERMISSION; + } + + /* compute set offsets */ + setOffsetMin = VLAN_SET_OFFSET(vlanIDMin); + setOffsetMax = VLAN_SET_OFFSET(vlanIDMax); + + /* change VLAN range */ + for (; vlanIDMin <= vlanIDMax ; vlanIDMin++) + { + /* change vlan in local membership table */ + ixEthDBLocalVlanMembershipChange(vlanIDMin, table, action); + } + + /* if the range is within one set (max 8 VLANs in one table byte) we can just update that entry in the NPE */ + if (setOffsetMin == setOffsetMax) + { + /* send updated entry to NPE */ + return ixEthDBVlanTableEntryUpdate(portID, setOffsetMin); + } + else + { + /* update a zone of the membership/transmit tag info table */ + return ixEthDBVlanTableRangeUpdate(portID); + } +} + +/** + * @brief adds a VLAN range to a port's VLAN membership table + * + * @param portID ID of the port + * @param vlanIDMin start of the VLAN range + * @param vlanIDMax end of the VLAN range + * + * 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 ixEthDBPortVlanMembershipRangeAdd(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + return ixEthDBPortVlanMembershipRangeChange(portID, vlanIDMin, vlanIDMax, ixEthDBPortInfo[portID].vlanMembership, ADD_VLAN); +} + +/** + * @brief removes a VLAN range from a port's VLAN membership table + * + * @param portID ID of the port + * @param vlanIDMin start of the VLAN range + * @param vlanIDMax end of the VLAN range + * + * 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 ixEthDBPortVlanMembershipRangeRemove(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + return ixEthDBPortVlanMembershipRangeChange(portID, vlanIDMin, vlanIDMax, ixEthDBPortInfo[portID].vlanMembership, REMOVE_VLAN); +} + +/** + * @brief sets a port's VLAN membership table or TTI table and + * updates the NPE VLAN configuration + * + * @param portID ID of the port + * @param portVlanTable port VLAN table to set + * @param vlanSet new set contents + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + * + * @internal + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortVlanTableSet(IxEthDBPortId portID, IxEthDBVlanSet portVlanTable, IxEthDBVlanSet vlanSet) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + IX_ETH_DB_CHECK_REFERENCE(vlanSet); + + memcpy(portVlanTable, vlanSet, sizeof (IxEthDBVlanSet)); + + return ixEthDBVlanTableRangeUpdate(portID); +} + +/** + * @brief retireves a port's VLAN membership table or TTI table + * + * @param portID ID of the port + * @param portVlanTable port VLAN table to retrieve + * @param vlanSet address to + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + * + * @internal + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBVlanTableGet(IxEthDBPortId portID, IxEthDBVlanSet portVlanTable, IxEthDBVlanSet vlanSet) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + IX_ETH_DB_CHECK_REFERENCE(vlanSet); + + memcpy(vlanSet, portVlanTable, sizeof (IxEthDBVlanSet)); + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief sets a port's VLAN membership table + * + * @param portID ID of the port + * @param vlanSet new VLAN membership table + * + * 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 ixEthDBPortVlanMembershipSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet) +{ + IxEthDBVlanId vlanID; + + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_REFERENCE(vlanSet); + + /* set the bit corresponding to the PVID just in case */ + vlanID = IX_ETH_DB_GET_VLAN_ID(ixEthDBPortInfo[portID].vlanTag); + vlanSet[VLAN_SET_OFFSET(vlanID)] |= 1 << VLAN_SET_MASK(vlanID); + + return ixEthDBPortVlanTableSet(portID, ixEthDBPortInfo[portID].vlanMembership, vlanSet); +} + +/** + * @brief retrieves a port's VLAN membership table + * + * @param portID ID of the port + * @param vlanSet location to store the port's VLAN membership table + * + * 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 ixEthDBPortVlanMembershipGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + return ixEthDBVlanTableGet(portID, ixEthDBPortInfo[portID].vlanMembership, vlanSet); +} + +/** + * @brief enables or disables Egress tagging for one VLAN ID + * + * @param portID ID of the port + * @param vlanID VLAN ID to enable or disable Egress tagging on + * @param enabled TRUE to enable and FALSE to disable tagging + * + * 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 ixEthDBEgressVlanEntryTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL enabled) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_VLAN_ID(vlanID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + return ixEthDBPortVlanMembershipChange(portID, vlanID, ixEthDBPortInfo[portID].transmitTaggingInfo, enabled? ADD_VLAN : REMOVE_VLAN); +} + +/** + * @brief retrieves the Egress tagging status for one VLAN ID + * + * @param portID ID of the port + * @param vlanID VLAN ID to retrieve the tagging status for + * @param enabled location to store the tagging status + * (TRUE - tagging enabled, FALSE - tagging disabled) + * + * 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 ixEthDBEgressVlanEntryTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL *enabled) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + IX_ETH_DB_CHECK_REFERENCE(enabled); + + IX_ETH_DB_CHECK_VLAN_ID(vlanID); + + *enabled = ((ixEthDBPortInfo[portID].transmitTaggingInfo[VLAN_SET_OFFSET(vlanID)] & (1 << VLAN_SET_MASK(vlanID))) != 0); + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief enables or disables Egress VLAN tagging for a VLAN range + * + * @param portID ID of the port + * @param vlanIDMin start of VLAN range + * @param vlanIDMax end of VLAN range + * @param enabled TRUE to enable or FALSE to disable VLAN tagging + * + * 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 ixEthDBEgressVlanRangeTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax, BOOL enabled) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + return ixEthDBPortVlanMembershipRangeChange(portID, vlanIDMin, vlanIDMax, ixEthDBPortInfo[portID].transmitTaggingInfo, enabled? ADD_VLAN : REMOVE_VLAN); +} + +/** + * @brief sets the Egress VLAN tagging table (the Transmit Tagging + * Information table) + * + * @param portID ID of the port + * @param vlanSet new TTI table + * + * 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 ixEthDBEgressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet) +{ + IxEthDBVlanId vlanID; + + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_REFERENCE(vlanSet); + + /* set the PVID bit just in case */ + vlanID = IX_ETH_DB_GET_VLAN_ID(ixEthDBPortInfo[portID].vlanTag); + vlanSet[VLAN_SET_OFFSET(vlanID)] |= 1 << VLAN_SET_MASK(vlanID); + + return ixEthDBPortVlanTableSet(portID, ixEthDBPortInfo[portID].transmitTaggingInfo, vlanSet); +} + +/** + * @brief retrieves the Egress VLAN tagging table (the Transmit + * Tagging Information table) + * + * @param portID ID of the port + * @param vlanSet location to store the port's TTI table + * + * 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 ixEthDBEgressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + return ixEthDBVlanTableGet(portID, ixEthDBPortInfo[portID].transmitTaggingInfo, vlanSet); +} + +/** + * @brief sends the NPE the updated frame filter and default + * Ingress tagging + * + * @param portID ID of the port + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + * + * @internal + */ +IX_ETH_DB_PRIVATE +IxEthDBStatus ixEthDBIngressVlanModeUpdate(IxEthDBPortId portID) +{ + PortInfo *portInfo = &ixEthDBPortInfo[portID]; + IxNpeMhMessage message; + IX_STATUS result; + + FILL_SETRXTAGMODE_MSG(message, portID, portInfo->npeFrameFilter, portInfo->npeTaggingAction); + IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); + + return result; +} + +/** + * @brief sets the default Ingress tagging behavior + * + * @param portID ID of the port + * @param taggingAction default tagging behavior + * + * 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 ixEthDBIngressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBTaggingAction taggingAction) +{ + PortInfo *portInfo; + + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + portInfo = &ixEthDBPortInfo[portID]; + + if (taggingAction == IX_ETH_DB_PASS_THROUGH) + { + portInfo->npeTaggingAction = 0x00; + } + else if (taggingAction == IX_ETH_DB_ADD_TAG) + { + portInfo->npeTaggingAction = 0x02; + } + else if (taggingAction == IX_ETH_DB_REMOVE_TAG) + { + portInfo->npeTaggingAction = 0x01; + } + else + { + return IX_ETH_DB_INVALID_ARG; + } + + portInfo->taggingAction = taggingAction; + + return ixEthDBIngressVlanModeUpdate(portID); +} + +/** + * @brief retrieves the default Ingress tagging behavior of a port + * + * @param portID ID of the port + * @param taggingAction location to save the default tagging behavior + * + * 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 ixEthDBIngressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBTaggingAction *taggingAction) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + IX_ETH_DB_CHECK_REFERENCE(taggingAction); + + *taggingAction = ixEthDBPortInfo[portID].taggingAction; + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief sets the Ingress acceptable frame type filter + * + * @param portID ID of the port + * @param frameFilter acceptable frame type filter + * + * 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 ixEthDBAcceptableFrameTypeSet(IxEthDBPortId portID, IxEthDBFrameFilter frameFilter) +{ + PortInfo *portInfo; + IxEthDBStatus result = IX_ETH_DB_SUCCESS; + + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + /* check parameter range + the ORed value of the valid values is 0x7 + a value having extra bits is invalid */ + if ((frameFilter | 0x7) != 0x7 || frameFilter == 0) + { + return IX_ETH_DB_INVALID_ARG; + } + + portInfo = &ixEthDBPortInfo[portID]; + + portInfo->frameFilter = frameFilter; + portInfo->npeFrameFilter = 0; /* allow all by default */ + + /* if accepting priority tagged but not all VLAN tagged + set the membership table to contain only VLAN ID 0 + hence remove vlans 1-4094 and add VLAN ID 0 */ + if (((frameFilter & IX_ETH_DB_PRIORITY_TAGGED_FRAMES) != 0) + && ((frameFilter & IX_ETH_DB_VLAN_TAGGED_FRAMES) == 0)) + { + result = ixEthDBPortVlanMembershipRangeChange(portID, + 1, IX_ETH_DB_802_1Q_MAX_VLAN_ID, portInfo->vlanMembership, REMOVE_VLAN); + + if (result == IX_ETH_DB_SUCCESS) + { + ixEthDBLocalVlanMembershipChange(0, portInfo->vlanMembership, ADD_VLAN); + result = ixEthDBVlanTableRangeUpdate(portID); + } + } + + /* untagged only? */ + if (frameFilter == IX_ETH_DB_UNTAGGED_FRAMES) + { + portInfo->npeFrameFilter = 0x01; + } + + /* tagged only? */ + if ((frameFilter & IX_ETH_DB_UNTAGGED_FRAMES) == 0) + { + portInfo->npeFrameFilter = 0x02; + } + + if (result == IX_ETH_DB_SUCCESS) + { + result = ixEthDBIngressVlanModeUpdate(portID); + } + + return result; +} + +/** + * @brief retrieves the acceptable frame type filter for a port + * + * @param portID ID of the port + * @param frameFilter location to store the frame filter + * + * 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 ixEthDBAcceptableFrameTypeGet(IxEthDBPortId portID, IxEthDBFrameFilter *frameFilter) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + IX_ETH_DB_CHECK_REFERENCE(frameFilter); + + *frameFilter = ixEthDBPortInfo[portID].frameFilter; + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief sends an NPE the updated configuration related + * to one QoS priority (associated traffic class and AQM mapping) + * + * @param portID ID of the port + * @param classIndex QoS priority (traffic class index) + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + * + * @internal + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBUpdateTrafficClass(IxEthDBPortId portID, UINT32 classIndex) +{ + IxNpeMhMessage message; + IX_STATUS result; + + UINT32 trafficClass = ixEthDBPortInfo[portID].priorityTable[classIndex]; + UINT32 aqmQueue = ixEthDBPortInfo[portID].ixEthDBTrafficClassAQMAssignments[trafficClass]; + + FILL_SETRXQOSENTRY(message, IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), classIndex, trafficClass, aqmQueue); + + IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); + + return result; +} + +/** + * @brief sets the priority mapping table + * + * @param portID ID of the port + * @param priorityTable new priority mapping table + * + * 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 ixEthDBPriorityMappingTableSet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable) +{ + UINT32 classIndex; + + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + IX_ETH_DB_CHECK_REFERENCE(priorityTable); + + for (classIndex = 0 ; classIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; classIndex++) + { + /* check range */ + if (priorityTable[classIndex] >= ixEthDBPortInfo[portID].ixEthDBTrafficClassCount) + { + return IX_ETH_DB_INVALID_PRIORITY; + } + } + + /* set new traffic classes */ + for (classIndex = 0 ; classIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; classIndex++) + { + ixEthDBPortInfo[portID].priorityTable[classIndex] = priorityTable[classIndex]; + + if (ixEthDBUpdateTrafficClass(portID, classIndex) != IX_ETH_DB_SUCCESS) + { + return IX_ETH_DB_FAIL; + } + } + + return IX_ETH_DB_SUCCESS; + } + +/** + * @brief retrieves a port's priority mapping table + * + * @param portID ID of the port + * @param priorityTable location to store the priority table + * + * 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 ixEthDBPriorityMappingTableGet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + IX_ETH_DB_CHECK_REFERENCE(priorityTable); + + memcpy(priorityTable, ixEthDBPortInfo[portID].priorityTable, sizeof (IxEthDBPriorityTable)); + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief sets one QoS priority => traffic class mapping + * + * @param portID ID of the port + * @param userPriority QoS (user) priority + * @param trafficClass associated traffic class + * + * 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 ixEthDBPriorityMappingClassSet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority trafficClass) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + /* check ranges for userPriority and trafficClass */ + if (userPriority >= IX_IEEE802_1Q_QOS_PRIORITY_COUNT || trafficClass >= ixEthDBPortInfo[portID].ixEthDBTrafficClassCount) + { + return IX_ETH_DB_INVALID_PRIORITY; + } + + ixEthDBPortInfo[portID].priorityTable[userPriority] = trafficClass; + + return ixEthDBUpdateTrafficClass(portID, userPriority); +} + +/** + * @brief retrieves one QoS priority => traffic class mapping + * + * @param portID ID of the port + * @param userPriority QoS (user) priority + * @param trafficClass location to store the associated traffic class + * + * 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 ixEthDBPriorityMappingClassGet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority *trafficClass) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + IX_ETH_DB_CHECK_REFERENCE(trafficClass); + + /* check userPriority range */ + if (userPriority >= IX_IEEE802_1Q_QOS_PRIORITY_COUNT) + { + return IX_ETH_DB_INVALID_PRIORITY; + } + + *trafficClass = ixEthDBPortInfo[portID].priorityTable[userPriority]; + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief enables or disables the source port extraction + * from the VLAN TPID field + * + * @param portID ID of the port + * @param enable TRUE to enable or FALSE to disable + * + * 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 ixEthDBVlanPortExtractionEnable(IxEthDBPortId portID, BOOL enable) +{ + 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_VLAN_QOS); + + FILL_SETPORTIDEXTRACTIONMODE(message, portID, enable); + + IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); + + return result; +} diff --git a/arch/arm/cpu/ixp/npe/IxEthDBWiFi.c b/arch/arm/cpu/ixp/npe/IxEthDBWiFi.c new file mode 100644 index 0000000000..0a6043f364 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxEthDBWiFi.c @@ -0,0 +1,480 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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; +} diff --git a/arch/arm/cpu/ixp/npe/IxEthMii.c b/arch/arm/cpu/ixp/npe/IxEthMii.c new file mode 100644 index 0000000000..4d92f17eef --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxEthMii.c @@ -0,0 +1,497 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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 0 && i= 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; +} + diff --git a/arch/arm/cpu/ixp/npe/IxFeatureCtrl.c b/arch/arm/cpu/ixp/npe/IxFeatureCtrl.c new file mode 100644 index 0000000000..2e196a19aa --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxFeatureCtrl.c @@ -0,0 +1,422 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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_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 +} diff --git a/arch/arm/cpu/ixp/npe/IxNpeDl.c b/arch/arm/cpu/ixp/npe/IxNpeDl.c new file mode 100644 index 0000000000..3738337538 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxNpeDl.c @@ -0,0 +1,940 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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; + } +} diff --git a/arch/arm/cpu/ixp/npe/IxNpeDlImageMgr.c b/arch/arm/cpu/ixp/npe/IxNpeDlImageMgr.c new file mode 100644 index 0000000000..9bcdc9c0d8 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxNpeDlImageMgr.c @@ -0,0 +1,687 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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; +} + diff --git a/arch/arm/cpu/ixp/npe/IxNpeDlNpeMgr.c b/arch/arm/cpu/ixp/npe/IxNpeDlNpeMgr.c new file mode 100644 index 0000000000..f5a4c5f508 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxNpeDlNpeMgr.c @@ -0,0 +1,936 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- +*/ + + +/* + * Put the user defined include files required. + */ + + +/* + * 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 (); +} diff --git a/arch/arm/cpu/ixp/npe/IxNpeDlNpeMgrUtils.c b/arch/arm/cpu/ixp/npe/IxNpeDlNpeMgrUtils.c new file mode 100644 index 0000000000..18cac50208 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxNpeDlNpeMgrUtils.c @@ -0,0 +1,806 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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; +} diff --git a/arch/arm/cpu/ixp/npe/IxNpeMh.c b/arch/arm/cpu/ixp/npe/IxNpeMh.c new file mode 100644 index 0000000000..8703def8bc --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxNpeMh.c @@ -0,0 +1,582 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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; +} diff --git a/arch/arm/cpu/ixp/npe/IxNpeMhConfig.c b/arch/arm/cpu/ixp/npe/IxNpeMhConfig.c new file mode 100644 index 0000000000..50c8f21138 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxNpeMhConfig.c @@ -0,0 +1,608 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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; +} + + diff --git a/arch/arm/cpu/ixp/npe/IxNpeMhReceive.c b/arch/arm/cpu/ixp/npe/IxNpeMhReceive.c new file mode 100644 index 0000000000..57c8be30e5 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxNpeMhReceive.c @@ -0,0 +1,320 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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; +} diff --git a/arch/arm/cpu/ixp/npe/IxNpeMhSend.c b/arch/arm/cpu/ixp/npe/IxNpeMhSend.c new file mode 100644 index 0000000000..318913ac84 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxNpeMhSend.c @@ -0,0 +1,307 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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; +} diff --git a/arch/arm/cpu/ixp/npe/IxNpeMhSolicitedCbMgr.c b/arch/arm/cpu/ixp/npe/IxNpeMhSolicitedCbMgr.c new file mode 100644 index 0000000000..8e083a63bf --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxNpeMhSolicitedCbMgr.c @@ -0,0 +1,358 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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; +} diff --git a/arch/arm/cpu/ixp/npe/IxNpeMhUnsolicitedCbMgr.c b/arch/arm/cpu/ixp/npe/IxNpeMhUnsolicitedCbMgr.c new file mode 100644 index 0000000000..d37f9f9306 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxNpeMhUnsolicitedCbMgr.c @@ -0,0 +1,246 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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; +} diff --git a/arch/arm/cpu/ixp/npe/IxOsalBufferMgt.c b/arch/arm/cpu/ixp/npe/IxOsalBufferMgt.c new file mode 100644 index 0000000000..fa8db477af --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxOsalBufferMgt.c @@ -0,0 +1,800 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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 */ diff --git a/arch/arm/cpu/ixp/npe/IxOsalIoMem.c b/arch/arm/cpu/ixp/npe/IxOsalIoMem.c new file mode 100644 index 0000000000..34df92bf79 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxOsalIoMem.c @@ -0,0 +1,332 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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 = + sizeof (ixOsalGlobalMemoryMap) / sizeof (IxOsalMemoryMap); + + 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); + } +} diff --git a/arch/arm/cpu/ixp/npe/IxOsalOsCacheMMU.c b/arch/arm/cpu/ixp/npe/IxOsalOsCacheMMU.c new file mode 100644 index 0000000000..3db1a70da9 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxOsalOsCacheMMU.c @@ -0,0 +1,67 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#include "IxOsal.h" + +#include + +/* + * 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); +} diff --git a/arch/arm/cpu/ixp/npe/IxOsalOsMsgQ.c b/arch/arm/cpu/ixp/npe/IxOsalOsMsgQ.c new file mode 100644 index 0000000000..45a5c68b16 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxOsalOsMsgQ.c @@ -0,0 +1,79 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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; +} + diff --git a/arch/arm/cpu/ixp/npe/IxOsalOsSemaphore.c b/arch/arm/cpu/ixp/npe/IxOsalOsSemaphore.c new file mode 100644 index 0000000000..443aefd4fc --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxOsalOsSemaphore.c @@ -0,0 +1,233 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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); +} diff --git a/arch/arm/cpu/ixp/npe/IxOsalOsServices.c b/arch/arm/cpu/ixp/npe/IxOsalOsServices.c new file mode 100644 index 0000000000..e18c6c4c1e --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxOsalOsServices.c @@ -0,0 +1,251 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#include +#include +#include "IxOsal.h" +#include +#include +#include +#include +#include + +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)); +} diff --git a/arch/arm/cpu/ixp/npe/IxOsalOsThread.c b/arch/arm/cpu/ixp/npe/IxOsalOsThread.c new file mode 100644 index 0000000000..e6a4967fcd --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxOsalOsThread.c @@ -0,0 +1,98 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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; +} diff --git a/arch/arm/cpu/ixp/npe/IxQMgrAqmIf.c b/arch/arm/cpu/ixp/npe/IxQMgrAqmIf.c new file mode 100644 index 0000000000..738651322c --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxQMgrAqmIf.c @@ -0,0 +1,963 @@ +/* + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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_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++; + } +} + diff --git a/arch/arm/cpu/ixp/npe/IxQMgrDispatcher.c b/arch/arm/cpu/ixp/npe/IxQMgrDispatcher.c new file mode 100644 index 0000000000..09f69ce322 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxQMgrDispatcher.c @@ -0,0 +1,1347 @@ +/** + * @file IxQMgrDispatcher.c + * + * @author Intel Corporation + * @date 20-Dec-2001 + * + * @brief This file contains the implementation of the Dispatcher sub component + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- +*/ + +/* + * User defined include files. + */ +#include "IxQMgr.h" +#include "IxQMgrAqmIf_p.h" +#include "IxQMgrQCfg_p.h" +#include "IxQMgrDispatcher_p.h" +#include "IxQMgrLog_p.h" +#include "IxQMgrDefines_p.h" +#include "IxFeatureCtrl.h" +#include "IxOsal.h" + + + +/* + * #defines and macros used in this file. + */ + + +/* + * This constant is used to indicate the number of priority levels supported + */ +#define IX_QMGR_NUM_PRIORITY_LEVELS 3 + +/* + * This constant is used to set the size of the array of status words + */ +#define MAX_Q_STATUS_WORDS 4 + +/* + * This macro is used to check if a given priority is valid + */ +#define IX_QMGR_DISPATCHER_PRIORITY_CHECK(priority) \ +(((priority) >= IX_QMGR_Q_PRIORITY_0) && ((priority) <= IX_QMGR_Q_PRIORITY_2)) + +/* + * This macto is used to check that a given interrupt source is valid + */ +#define IX_QMGR_DISPATCHER_SOURCE_ID_CHECK(srcSel) \ +(((srcSel) >= IX_QMGR_Q_SOURCE_ID_E) && ((srcSel) <= IX_QMGR_Q_SOURCE_ID_NOT_F)) + +/* + * Number of times a dummy callback is called before logging a trace + * message + */ +#define LOG_THROTTLE_COUNT 1000000 + +/* Priority tables limits */ +#define IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX (0) +#define IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX (16) +#define IX_QMGR_MAX_LOW_QUE_PRIORITY_TABLE_INDEX (31) +#define IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX (32) +#define IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX (48) +#define IX_QMGR_MAX_UPP_QUE_PRIORITY_TABLE_INDEX (63) + +/* + * This macro is used to check if a given callback type is valid + */ +#define IX_QMGR_DISPATCHER_CALLBACK_TYPE_CHECK(type) \ + (((type) >= IX_QMGR_TYPE_REALTIME_OTHER) && \ + ((type) <= IX_QMGR_TYPE_REALTIME_SPORADIC)) + +/* + * define max index in lower queue to use in loops + */ +#define IX_QMGR_MAX_LOW_QUE_TABLE_INDEX (31) + +/* + * Typedefs whose scope is limited to this file. + */ + +/* + * Information on a queue needed by the Dispatcher + */ +typedef struct +{ + IxQMgrCallback callback; /* Notification callback */ + IxQMgrCallbackId callbackId; /* Notification callback identifier */ + unsigned dummyCallbackCount; /* Number of times runs of dummy callback */ + IxQMgrPriority priority; /* Dispatch priority */ + unsigned int statusWordOffset; /* Offset to the status word to check */ + UINT32 statusMask; /* Status mask */ + UINT32 statusCheckValue; /* Status check value */ + UINT32 intRegCheckMask; /* Interrupt register check mask */ +} IxQMgrQInfo; + +/* + * Variable declarations global to this file. Externs are followed by + * statics. + */ + +/* + * Flag to keep record of what dispatcher set in featureCtrl when ixQMgrInit() + * is called. This is needed because it is possible that a client might + * change whether the live lock prevention dispatcher is used between + * calls to ixQMgrInit() and ixQMgrDispatcherLoopGet(). + */ +PRIVATE IX_STATUS ixQMgrOrigB0Dispatcher = IX_FEATURE_CTRL_COMPONENT_ENABLED; + +/* + * keep record of Q types - not in IxQMgrQInfo for performance as + * it is only used with ixQMgrDispatcherLoopRunB0LLP() + */ +PRIVATE IxQMgrType ixQMgrQTypes[IX_QMGR_MAX_NUM_QUEUES]; + +/* + * This array contains a list of queue identifiers ordered by priority. The table + * is split logically between queue identifiers 0-31 and 32-63. + */ +static IxQMgrQId priorityTable[IX_QMGR_MAX_NUM_QUEUES]; + +/* + * This flag indicates to the dispatcher that the priority table needs to be rebuilt. + */ +static BOOL rebuildTable = FALSE; + +/* Dispatcher statistics */ +static IxQMgrDispatcherStats dispatcherStats; + +/* Table of queue information */ +static IxQMgrQInfo dispatchQInfo[IX_QMGR_MAX_NUM_QUEUES]; + +/* Masks use to identify the first queues in the priority tables +* when comparing with the interrupt register +*/ +static unsigned int lowPriorityTableFirstHalfMask; +static unsigned int uppPriorityTableFirstHalfMask; + +/* + * Static function prototypes + */ + +/* + * This function is the default callback for all queues + */ +PRIVATE void +dummyCallback (IxQMgrQId qId, + IxQMgrCallbackId cbId); + +PRIVATE void +ixQMgrDispatcherReBuildPriorityTable (void); + +/* + * Function definitions. + */ +void +ixQMgrDispatcherInit (void) +{ + int i; + IxFeatureCtrlProductId productId = 0; + IxFeatureCtrlDeviceId deviceId = 0; + BOOL stickyIntSilicon = TRUE; + + /* Set default priorities */ + for (i=0; i< IX_QMGR_MAX_NUM_QUEUES; i++) + { + dispatchQInfo[i].callback = dummyCallback; + dispatchQInfo[i].callbackId = 0; + dispatchQInfo[i].dummyCallbackCount = 0; + dispatchQInfo[i].priority = IX_QMGR_Q_PRIORITY_2; + dispatchQInfo[i].statusWordOffset = 0; + dispatchQInfo[i].statusCheckValue = 0; + dispatchQInfo[i].statusMask = 0; + /* + * There are two interrupt registers, 32 bits each. One for the lower + * queues(0-31) and one for the upper queues(32-63). Therefore need to + * mod by 32 i.e the min upper queue identifier. + */ + dispatchQInfo[i].intRegCheckMask = (1<<(i%(IX_QMGR_MIN_QUEUPP_QID))); + + /* + * Set the Q types - will only be used with livelock + */ + ixQMgrQTypes[i] = IX_QMGR_TYPE_REALTIME_OTHER; + + /* Reset queue statistics */ + dispatcherStats.queueStats[i].callbackCnt = 0; + dispatcherStats.queueStats[i].priorityChangeCnt = 0; + dispatcherStats.queueStats[i].intNoCallbackCnt = 0; + dispatcherStats.queueStats[i].intLostCallbackCnt = 0; + dispatcherStats.queueStats[i].notificationEnabled = FALSE; + dispatcherStats.queueStats[i].srcSel = 0; + + } + + /* Priority table. Order the table from queue 0 to 63 */ + ixQMgrDispatcherReBuildPriorityTable(); + + /* Reset statistics */ + dispatcherStats.loopRunCnt = 0; + + /* Get the device ID for the underlying silicon */ + deviceId = ixFeatureCtrlDeviceRead(); + + /* Get the product ID for the underlying silicon */ + productId = ixFeatureCtrlProductIdRead(); + + /* + * Check featureCtrl to see if Livelock prevention is required + */ + ixQMgrOrigB0Dispatcher = ixFeatureCtrlSwConfigurationCheck( + IX_FEATURECTRL_ORIGB0_DISPATCHER); + + /* + * Check if the silicon supports the sticky interrupt feature. + * IF (IXP42X AND A0) -> No sticky interrupt feature supported + */ + if ((IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X == + (IX_FEATURE_CTRL_DEVICE_TYPE_MASK & deviceId)) && + (IX_FEATURE_CTRL_SILICON_TYPE_A0 == + (IX_FEATURE_CTRL_SILICON_STEPPING_MASK & productId))) + { + stickyIntSilicon = FALSE; + } + + /* + * IF user wants livelock prev option AND silicon supports sticky interrupt + * feature -> enable the sticky interrupt bit + */ + if ((IX_FEATURE_CTRL_SWCONFIG_DISABLED == ixQMgrOrigB0Dispatcher) && + stickyIntSilicon) + { + ixQMgrStickyInterruptRegEnable(); + } +} + +IX_STATUS +ixQMgrDispatcherPrioritySet (IxQMgrQId qId, + IxQMgrPriority priority) +{ + int ixQMgrLockKey; + + if (!ixQMgrQIsConfigured(qId)) + { + return IX_QMGR_Q_NOT_CONFIGURED; + } + + if (!IX_QMGR_DISPATCHER_PRIORITY_CHECK(priority)) + { + return IX_QMGR_Q_INVALID_PRIORITY; + } + + ixQMgrLockKey = ixOsalIrqLock(); + + /* Change priority */ + dispatchQInfo[qId].priority = priority; + /* Set flag */ + rebuildTable = TRUE; + + ixOsalIrqUnlock(ixQMgrLockKey); + +#ifndef NDEBUG + /* Update statistics */ + dispatcherStats.queueStats[qId].priorityChangeCnt++; +#endif + + return IX_SUCCESS; +} + +IX_STATUS +ixQMgrNotificationCallbackSet (IxQMgrQId qId, + IxQMgrCallback callback, + IxQMgrCallbackId callbackId) +{ + if (!ixQMgrQIsConfigured(qId)) + { + return IX_QMGR_Q_NOT_CONFIGURED; + } + + if (NULL == callback) + { + /* Reset to dummy callback */ + dispatchQInfo[qId].callback = dummyCallback; + dispatchQInfo[qId].dummyCallbackCount = 0; + dispatchQInfo[qId].callbackId = 0; + } + else + { + dispatchQInfo[qId].callback = callback; + dispatchQInfo[qId].callbackId = callbackId; + } + + return IX_SUCCESS; +} + +IX_STATUS +ixQMgrNotificationEnable (IxQMgrQId qId, + IxQMgrSourceId srcSel) +{ + IxQMgrQStatus qStatusOnEntry;/* The queue status on entry/exit */ + IxQMgrQStatus qStatusOnExit; /* to this function */ + int ixQMgrLockKey; + +#ifndef NDEBUG + if (!ixQMgrQIsConfigured (qId)) + { + return IX_QMGR_Q_NOT_CONFIGURED; + } + + if ((qId < IX_QMGR_MIN_QUEUPP_QID) && + !IX_QMGR_DISPATCHER_SOURCE_ID_CHECK(srcSel)) + { + /* QId 0-31 source id invalid */ + return IX_QMGR_INVALID_INT_SOURCE_ID; + } + + if ((IX_QMGR_Q_SOURCE_ID_NE != srcSel) && + (qId >= IX_QMGR_MIN_QUEUPP_QID)) + { + /* + * For queues 32-63 the interrupt source is fixed to the Nearly + * Empty status flag and therefore should have a srcSel of NE. + */ + return IX_QMGR_INVALID_INT_SOURCE_ID; + } +#endif + +#ifndef NDEBUG + dispatcherStats.queueStats[qId].notificationEnabled = TRUE; + dispatcherStats.queueStats[qId].srcSel = srcSel; +#endif + + /* Get the current queue status */ + ixQMgrAqmIfQueStatRead (qId, &qStatusOnEntry); + + /* + * Enabling interrupts results in Read-Modify-Write + * so need critical section + */ + + ixQMgrLockKey = ixOsalIrqLock(); + + /* Calculate the checkMask and checkValue for this q */ + ixQMgrAqmIfQStatusCheckValsCalc (qId, + srcSel, + &dispatchQInfo[qId].statusWordOffset, + &dispatchQInfo[qId].statusCheckValue, + &dispatchQInfo[qId].statusMask); + + + /* Set the interupt source is this queue is in the range 0-31 */ + if (qId < IX_QMGR_MIN_QUEUPP_QID) + { + ixQMgrAqmIfIntSrcSelWrite (qId, srcSel); + } + + /* Enable the interrupt */ + ixQMgrAqmIfQInterruptEnable (qId); + + ixOsalIrqUnlock(ixQMgrLockKey); + + /* 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 +ixQMgrNotificationDisable (IxQMgrQId qId) +{ + int ixQMgrLockKey; + +#ifndef NDEBUG + /* Validate parameters */ + if (!ixQMgrQIsConfigured (qId)) + { + return IX_QMGR_Q_NOT_CONFIGURED; + } +#endif + + /* + * Enabling interrupts results in Read-Modify-Write + * so need critical section + */ +#ifndef NDEBUG + dispatcherStats.queueStats[qId].notificationEnabled = FALSE; +#endif + + ixQMgrLockKey = ixOsalIrqLock(); + + ixQMgrAqmIfQInterruptDisable (qId); + + ixOsalIrqUnlock(ixQMgrLockKey); + + return IX_SUCCESS; +} + +void +ixQMgrStickyInterruptRegEnable(void) +{ + /* Use Aqm If function to set Interrupt Register0 Bit-3 */ + ixQMgrAqmIfIntSrcSelReg0Bit3Set (); +} + +#if !defined __XSCALE__ || defined __linux + +/* Count the number of leading zero bits in a word, + * and return the same value than the CLZ instruction. + * + * word (in) return value (out) + * 0x80000000 0 + * 0x40000000 1 + * ,,, ,,, + * 0x00000002 30 + * 0x00000001 31 + * 0x00000000 32 + * + * The C version of this function is used as a replacement + * for system not providing the equivalent of the CLZ + * assembly language instruction. + * + * Note that this version is big-endian + */ +unsigned int +ixQMgrCountLeadingZeros(UINT32 word) +{ + unsigned int leadingZerosCount = 0; + + if (word == 0) + { + return 32; + } + /* search the first bit set by testing the MSB and shifting the input word */ + while ((word & 0x80000000) == 0) + { + word <<= 1; + leadingZerosCount++; + } + return leadingZerosCount; +} +#endif /* not __XSCALE__ or __linux */ + +void +ixQMgrDispatcherLoopGet (IxQMgrDispatcherFuncPtr *qDispatcherFuncPtr) +{ + IxFeatureCtrlProductId productId = 0; + IxFeatureCtrlDeviceId deviceId = 0; + + /* Get the device ID for the underlying silicon */ + deviceId = ixFeatureCtrlDeviceRead(); + + /* Get the product ID for the underlying silicon */ + productId = ixFeatureCtrlProductIdRead (); + + /* IF (IXP42X AND A0 silicon) -> use ixQMgrDispatcherLoopRunA0 */ + if ((IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X == + (IX_FEATURE_CTRL_DEVICE_TYPE_MASK & deviceId)) && + (IX_FEATURE_CTRL_SILICON_TYPE_A0 == + (IX_FEATURE_CTRL_SILICON_STEPPING_MASK & productId))) + { + /*For IXP42X A0 silicon */ + *qDispatcherFuncPtr = &ixQMgrDispatcherLoopRunA0 ; + } + else /*For IXP42X B0 or IXP46X silicon*/ + { + if (IX_FEATURE_CTRL_SWCONFIG_ENABLED == ixQMgrOrigB0Dispatcher) + { + /* Default for IXP42X B0 and IXP46X silicon */ + *qDispatcherFuncPtr = &ixQMgrDispatcherLoopRunB0; + } + else + { + /* FeatureCtrl indicated that livelock dispatcher be used */ + *qDispatcherFuncPtr = &ixQMgrDispatcherLoopRunB0LLP; + } + } +} + +void +ixQMgrDispatcherLoopRunA0 (IxQMgrDispatchGroup group) +{ + UINT32 intRegVal; /* Interrupt reg val */ + UINT32 intRegValAfterWrite; /* Interrupt reg val after writing back */ + UINT32 intRegCheckMask; /* Mask for checking interrupt bits */ + UINT32 qStatusWordsB4Write[MAX_Q_STATUS_WORDS]; /* Status b4 interrupt write */ + UINT32 qStatusWordsAfterWrite[MAX_Q_STATUS_WORDS]; /* Status after interrupt write */ + IxQMgrQInfo *currDispatchQInfo; + BOOL statusChangeFlag; + + int priorityTableIndex;/* Priority table index */ + int qIndex; /* Current queue being processed */ + int endIndex; /* Index of last queue to process */ + +#ifndef NDEBUG + IX_OSAL_ASSERT((group == IX_QMGR_QUEUPP_GROUP) || + (group == IX_QMGR_QUELOW_GROUP)); +#endif + + /* Read Q status registers before interrupt status read/write */ + ixQMgrAqmIfQStatusRegsRead (group, qStatusWordsB4Write); + + /* Read the interrupt register */ + ixQMgrAqmIfQInterruptRegRead (group, &intRegVal); + + /* No bit set : nothing to process (the reaminder of the algorithm is + * based on the fact that the interrupt register value contains at + * least one bit set + */ + if (intRegVal == 0) + { +#ifndef NDEBUG + /* Update statistics */ + dispatcherStats.loopRunCnt++; +#endif + + /* Rebuild the priority table if needed */ + if (rebuildTable) + { + ixQMgrDispatcherReBuildPriorityTable (); + } + + return; + } + + /* Write it back to clear the interrupt */ + ixQMgrAqmIfQInterruptRegWrite (group, intRegVal); + + /* Read Q status registers after interrupt status read/write */ + ixQMgrAqmIfQStatusRegsRead (group, qStatusWordsAfterWrite); + + /* get the first queue Id from the interrupt register value */ + qIndex = (BITS_PER_WORD - 1) - ixQMgrCountLeadingZeros(intRegVal); + + /* check if any change occured during hw register modifications */ + if (IX_QMGR_QUELOW_GROUP == group) + { + statusChangeFlag = + (qStatusWordsB4Write[0] != qStatusWordsAfterWrite[0]) || + (qStatusWordsB4Write[1] != qStatusWordsAfterWrite[1]) || + (qStatusWordsB4Write[2] != qStatusWordsAfterWrite[2]) || + (qStatusWordsB4Write[3] != qStatusWordsAfterWrite[3]); + } + else + { + statusChangeFlag = + (qStatusWordsB4Write[0] != qStatusWordsAfterWrite[0]); + /* Set the queue range based on the queue group to proccess */ + qIndex += IX_QMGR_MIN_QUEUPP_QID; + } + + if (statusChangeFlag == FALSE) + { + /* check if the interrupt register contains + * only 1 bit set (happy day scenario) + */ + currDispatchQInfo = &dispatchQInfo[qIndex]; + if (intRegVal == currDispatchQInfo->intRegCheckMask) + { + /* only 1 queue event triggered a notification * + * Call the callback function for this queue + */ + currDispatchQInfo->callback (qIndex, + currDispatchQInfo->callbackId); +#ifndef NDEBUG + /* Update statistics */ + dispatcherStats.queueStats[qIndex].callbackCnt++; +#endif + } + else + { + /* the event is triggered by more than 1 queue, + * the queue search will be starting from the beginning + * or the middle of the priority table + * + * the serach will end when all the bits of the interrupt + * register are cleared. There is no need to maintain + * a seperate value and test it at each iteration. + */ + if (IX_QMGR_QUELOW_GROUP == group) + { + /* check if any bit related to queues in the first + * half of the priority table is set + */ + if (intRegVal & lowPriorityTableFirstHalfMask) + { + priorityTableIndex = IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX; + } + else + { + priorityTableIndex = IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX; + } + } + else + { + /* check if any bit related to queues in the first + * half of the priority table is set + */ + if (intRegVal & uppPriorityTableFirstHalfMask) + { + priorityTableIndex = IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX; + } + else + { + priorityTableIndex = IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX; + } + } + + /* iterate following the priority table until all the bits + * of the interrupt register are cleared. + */ + do + { + qIndex = priorityTable[priorityTableIndex++]; + currDispatchQInfo = &dispatchQInfo[qIndex]; + intRegCheckMask = currDispatchQInfo->intRegCheckMask; + + /* If this queue caused this interrupt to be raised */ + if (intRegVal & intRegCheckMask) + { + /* Call the callback function for this queue */ + currDispatchQInfo->callback (qIndex, + currDispatchQInfo->callbackId); +#ifndef NDEBUG + /* Update statistics */ + dispatcherStats.queueStats[qIndex].callbackCnt++; +#endif + + /* Clear the interrupt register bit */ + intRegVal &= ~intRegCheckMask; + } + } + while(intRegVal); + } + } + else + { + /* A change in queue status occured during the hw interrupt + * register update. To maintain the interrupt consistency, it + * is necessary to iterate through all queues of the queue group. + */ + + /* Read interrupt status again */ + ixQMgrAqmIfQInterruptRegRead (group, &intRegValAfterWrite); + + if (IX_QMGR_QUELOW_GROUP == group) + { + priorityTableIndex = IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX; + endIndex = IX_QMGR_MAX_LOW_QUE_PRIORITY_TABLE_INDEX; + } + else + { + priorityTableIndex = IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX; + endIndex = IX_QMGR_MAX_UPP_QUE_PRIORITY_TABLE_INDEX; + } + + for ( ; priorityTableIndex<=endIndex; priorityTableIndex++) + { + qIndex = priorityTable[priorityTableIndex]; + currDispatchQInfo = &dispatchQInfo[qIndex]; + intRegCheckMask = currDispatchQInfo->intRegCheckMask; + + /* If this queue caused this interrupt to be raised */ + if (intRegVal & intRegCheckMask) + { + /* Call the callback function for this queue */ + currDispatchQInfo->callback (qIndex, + currDispatchQInfo->callbackId); +#ifndef NDEBUG + /* Update statistics */ + dispatcherStats.queueStats[qIndex].callbackCnt++; +#endif + + } /* if (intRegVal .. */ + + /* + * If interrupt bit is set in intRegValAfterWrite don't + * proceed as this will be caught in next interrupt + */ + else if ((intRegValAfterWrite & intRegCheckMask) == 0) + { + /* Check if an interrupt was lost for this Q */ + if (ixQMgrAqmIfQStatusCheck(qStatusWordsB4Write, + qStatusWordsAfterWrite, + currDispatchQInfo->statusWordOffset, + currDispatchQInfo->statusCheckValue, + currDispatchQInfo->statusMask)) + { + /* Call the callback function for this queue */ + currDispatchQInfo->callback (qIndex, + dispatchQInfo[qIndex].callbackId); +#ifndef NDEBUG + /* Update statistics */ + dispatcherStats.queueStats[qIndex].callbackCnt++; + dispatcherStats.queueStats[qIndex].intLostCallbackCnt++; +#endif + } /* if ixQMgrAqmIfQStatusCheck(.. */ + } /* else if ((intRegValAfterWrite ... */ + } /* for (priorityTableIndex=0 ... */ + } + + /* Rebuild the priority table if needed */ + if (rebuildTable) + { + ixQMgrDispatcherReBuildPriorityTable (); + } + +#ifndef NDEBUG + /* Update statistics */ + dispatcherStats.loopRunCnt++; +#endif +} + + + +void +ixQMgrDispatcherLoopRunB0 (IxQMgrDispatchGroup group) +{ + UINT32 intRegVal; /* Interrupt reg val */ + UINT32 intRegCheckMask; /* Mask for checking interrupt bits */ + IxQMgrQInfo *currDispatchQInfo; + + + int priorityTableIndex; /* Priority table index */ + int qIndex; /* Current queue being processed */ + +#ifndef NDEBUG + IX_OSAL_ASSERT((group == IX_QMGR_QUEUPP_GROUP) || + (group == IX_QMGR_QUELOW_GROUP)); + IX_OSAL_ASSERT((group == IX_QMGR_QUEUPP_GROUP) || + (group == IX_QMGR_QUELOW_GROUP)); +#endif + + /* Read the interrupt register */ + ixQMgrAqmIfQInterruptRegRead (group, &intRegVal); + + + /* No queue has interrupt register set */ + if (intRegVal != 0) + { + + /* Write it back to clear the interrupt */ + ixQMgrAqmIfQInterruptRegWrite (group, intRegVal); + + /* get the first queue Id from the interrupt register value */ + qIndex = (BITS_PER_WORD - 1) - ixQMgrCountLeadingZeros(intRegVal); + + if (IX_QMGR_QUEUPP_GROUP == group) + { + /* Set the queue range based on the queue group to proccess */ + qIndex += IX_QMGR_MIN_QUEUPP_QID; + } + + /* check if the interrupt register contains + * only 1 bit set + * For example: + * intRegVal = 0x0010 + * currDispatchQInfo->intRegCheckMask = 0x0010 + * intRegVal == currDispatchQInfo->intRegCheckMask is TRUE. + */ + currDispatchQInfo = &dispatchQInfo[qIndex]; + if (intRegVal == currDispatchQInfo->intRegCheckMask) + { + /* only 1 queue event triggered a notification * + * Call the callback function for this queue + */ + currDispatchQInfo->callback (qIndex, + currDispatchQInfo->callbackId); +#ifndef NDEBUG + /* Update statistics */ + dispatcherStats.queueStats[qIndex].callbackCnt++; +#endif + } + else + { + /* the event is triggered by more than 1 queue, + * the queue search will be starting from the beginning + * or the middle of the priority table + * + * the serach will end when all the bits of the interrupt + * register are cleared. There is no need to maintain + * a seperate value and test it at each iteration. + */ + if (IX_QMGR_QUELOW_GROUP == group) + { + /* check if any bit related to queues in the first + * half of the priority table is set + */ + if (intRegVal & lowPriorityTableFirstHalfMask) + { + priorityTableIndex = IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX; + } + else + { + priorityTableIndex = IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX; + } + } + else + { + /* check if any bit related to queues in the first + * half of the priority table is set + */ + if (intRegVal & uppPriorityTableFirstHalfMask) + { + priorityTableIndex = IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX; + } + else + { + priorityTableIndex = IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX; + } + } + + /* iterate following the priority table until all the bits + * of the interrupt register are cleared. + */ + do + { + qIndex = priorityTable[priorityTableIndex++]; + currDispatchQInfo = &dispatchQInfo[qIndex]; + intRegCheckMask = currDispatchQInfo->intRegCheckMask; + + /* If this queue caused this interrupt to be raised */ + if (intRegVal & intRegCheckMask) + { + /* Call the callback function for this queue */ + currDispatchQInfo->callback (qIndex, + currDispatchQInfo->callbackId); +#ifndef NDEBUG + /* Update statistics */ + dispatcherStats.queueStats[qIndex].callbackCnt++; +#endif + + /* Clear the interrupt register bit */ + intRegVal &= ~intRegCheckMask; + } + } + while(intRegVal); + } /*End of intRegVal == currDispatchQInfo->intRegCheckMask */ + } /* End of intRegVal != 0 */ + +#ifndef NDEBUG + /* Update statistics */ + dispatcherStats.loopRunCnt++; +#endif + + /* Rebuild the priority table if needed */ + if (rebuildTable) + { + ixQMgrDispatcherReBuildPriorityTable (); + } +} + +void +ixQMgrDispatcherLoopRunB0LLP (IxQMgrDispatchGroup group) +{ + UINT32 intRegVal =0; /* Interrupt reg val */ + UINT32 intRegCheckMask; /* Mask for checking interrupt bits */ + IxQMgrQInfo *currDispatchQInfo; + + int priorityTableIndex; /* Priority table index */ + int qIndex; /* Current queue being processed */ + + UINT32 intRegValCopy = 0; + UINT32 intEnableRegVal = 0; + UINT8 i = 0; + +#ifndef NDEBUG + IX_OSAL_ASSERT((group == IX_QMGR_QUEUPP_GROUP) || + (group == IX_QMGR_QUELOW_GROUP)); +#endif + + /* Read the interrupt register */ + ixQMgrAqmIfQInterruptRegRead (group, &intRegVal); + + /* + * mask any interrupts that are not enabled + */ + ixQMgrAqmIfQInterruptEnableRegRead (group, &intEnableRegVal); + intRegVal &= intEnableRegVal; + + /* No queue has interrupt register set */ + if (intRegVal != 0) + { + if (IX_QMGR_QUELOW_GROUP == group) + { + /* + * As the sticky bit is set, the interrupt register will + * not clear if write back at this point because the condition + * has not been cleared. Take a copy and write back later after + * the condition has been cleared + */ + intRegValCopy = intRegVal; + } + else + { + /* no sticky for upper Q's, so write back now */ + ixQMgrAqmIfQInterruptRegWrite (group, intRegVal); + } + + /* get the first queue Id from the interrupt register value */ + qIndex = (BITS_PER_WORD - 1) - ixQMgrCountLeadingZeros(intRegVal); + + if (IX_QMGR_QUEUPP_GROUP == group) + { + /* Set the queue range based on the queue group to proccess */ + qIndex += IX_QMGR_MIN_QUEUPP_QID; + } + + /* check if the interrupt register contains + * only 1 bit set + * For example: + * intRegVal = 0x0010 + * currDispatchQInfo->intRegCheckMask = 0x0010 + * intRegVal == currDispatchQInfo->intRegCheckMask is TRUE. + */ + currDispatchQInfo = &dispatchQInfo[qIndex]; + if (intRegVal == currDispatchQInfo->intRegCheckMask) + { + + /* + * check if Q type periodic - only lower queues can + * have there type set to periodic + */ + if (IX_QMGR_TYPE_REALTIME_PERIODIC == ixQMgrQTypes[qIndex]) + { + /* + * Disable the notifications on any sporadics + */ + for (i=0; i <= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++) + { + if (IX_QMGR_TYPE_REALTIME_SPORADIC == ixQMgrQTypes[i]) + { + ixQMgrNotificationDisable(i); +#ifndef NDEBUG + /* Update statistics */ + dispatcherStats.queueStats[i].disableCount++; +#endif + } + } + } + + currDispatchQInfo->callback (qIndex, + currDispatchQInfo->callbackId); +#ifndef NDEBUG + /* Update statistics */ + dispatcherStats.queueStats[qIndex].callbackCnt++; +#endif + } + else + { + /* the event is triggered by more than 1 queue, + * the queue search will be starting from the beginning + * or the middle of the priority table + * + * the serach will end when all the bits of the interrupt + * register are cleared. There is no need to maintain + * a seperate value and test it at each iteration. + */ + if (IX_QMGR_QUELOW_GROUP == group) + { + /* check if any bit related to queues in the first + * half of the priority table is set + */ + if (intRegVal & lowPriorityTableFirstHalfMask) + { + priorityTableIndex = + IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX; + } + else + { + priorityTableIndex = + IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX; + } + } + else + { + /* check if any bit related to queues in the first + * half of the priority table is set + */ + if (intRegVal & uppPriorityTableFirstHalfMask) + { + priorityTableIndex = + IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX; + } + else + { + priorityTableIndex = + IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX; + } + } + + /* iterate following the priority table until all the bits + * of the interrupt register are cleared. + */ + do + { + qIndex = priorityTable[priorityTableIndex++]; + currDispatchQInfo = &dispatchQInfo[qIndex]; + intRegCheckMask = currDispatchQInfo->intRegCheckMask; + + /* If this queue caused this interrupt to be raised */ + if (intRegVal & intRegCheckMask) + { + /* + * check if Q type periodic - only lower queues can + * have there type set to periodic. There can only be one + * periodic queue, so the sporadics are only disabled once. + */ + if (IX_QMGR_TYPE_REALTIME_PERIODIC == ixQMgrQTypes[qIndex]) + { + /* + * Disable the notifications on any sporadics + */ + for (i=0; i <= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++) + { + if (IX_QMGR_TYPE_REALTIME_SPORADIC == + ixQMgrQTypes[i]) + { + ixQMgrNotificationDisable(i); + /* + * remove from intRegVal as we don't want + * to service any sporadics now + */ + intRegVal &= ~dispatchQInfo[i].intRegCheckMask; +#ifndef NDEBUG + /* Update statistics */ + dispatcherStats.queueStats[i].disableCount++; +#endif + } + } + } + + currDispatchQInfo->callback (qIndex, + currDispatchQInfo->callbackId); +#ifndef NDEBUG + /* Update statistics */ + dispatcherStats.queueStats[qIndex].callbackCnt++; +#endif + /* Clear the interrupt register bit */ + intRegVal &= ~intRegCheckMask; + } + } + while(intRegVal); + } /*End of intRegVal == currDispatchQInfo->intRegCheckMask */ + } /* End of intRegVal != 0 */ + +#ifndef NDEBUG + /* Update statistics */ + dispatcherStats.loopRunCnt++; +#endif + + if ((intRegValCopy != 0) && (IX_QMGR_QUELOW_GROUP == group)) + { + /* + * lower groups (therefore sticky) AND at least one enabled interrupt + * Write back to clear the interrupt + */ + ixQMgrAqmIfQInterruptRegWrite (IX_QMGR_QUELOW_GROUP, intRegValCopy); + } + + /* Rebuild the priority table if needed */ + if (rebuildTable) + { + ixQMgrDispatcherReBuildPriorityTable (); + } +} + +PRIVATE void +ixQMgrDispatcherReBuildPriorityTable (void) +{ + UINT32 qIndex; + UINT32 priority; + int lowQuePriorityTableIndex = IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX; + int uppQuePriorityTableIndex = IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX; + + /* Reset the rebuild flag */ + rebuildTable = FALSE; + + /* initialize the mak used to identify the queues in the first half + * of the priority table + */ + lowPriorityTableFirstHalfMask = 0; + uppPriorityTableFirstHalfMask = 0; + + /* For each priority level */ + for(priority=0; priority dummyCallback: qId (%d), callbackId (%d)\n",qId,cbId); + } + dispatchQInfo[qId].dummyCallbackCount++; + +#ifndef NDEBUG + /* Update statistcs */ + dispatcherStats.queueStats[qId].intNoCallbackCnt++; +#endif +} +void +ixQMgrLLPShow (int resetStats) +{ +#ifndef NDEBUG + UINT8 i = 0; + IxQMgrQInfo *q; + UINT32 intEnableRegVal = 0; + + printf ("Livelock statistics are printed on the fly.\n"); + printf ("qId Type EnableCnt DisableCnt IntEnableState Callbacks\n"); + printf ("=== ======== ========= ========== ============== =========\n"); + + for (i=0; i<= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++) + { + q = &dispatchQInfo[i]; + + if (ixQMgrQTypes[i] != IX_QMGR_TYPE_REALTIME_OTHER) + { + printf (" %2d ", i); + + if (ixQMgrQTypes[i] == IX_QMGR_TYPE_REALTIME_SPORADIC) + { + printf ("Sporadic"); + } + else + { + printf ("Periodic"); + } + + + ixQMgrAqmIfQInterruptEnableRegRead (IX_QMGR_QUELOW_GROUP, + &intEnableRegVal); + + + intEnableRegVal &= dispatchQInfo[i].intRegCheckMask; + intEnableRegVal = intEnableRegVal >> i; + + printf (" %10d %10d %10d %10d\n", + dispatcherStats.queueStats[i].enableCount, + dispatcherStats.queueStats[i].disableCount, + intEnableRegVal, + dispatcherStats.queueStats[i].callbackCnt); + + if (resetStats) + { + dispatcherStats.queueStats[i].enableCount = + dispatcherStats.queueStats[i].disableCount = + dispatcherStats.queueStats[i].callbackCnt = 0; + } + } + } +#else + IX_QMGR_LOG0("Livelock Prevention statistics are only collected in debug mode\n"); +#endif +} + +void +ixQMgrPeriodicDone (void) +{ + UINT32 i = 0; + UINT32 ixQMgrLockKey = 0; + + /* + * for the lower queues + */ + for (i=0; i <= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++) + { + /* + * check for sporadics + */ + if (IX_QMGR_TYPE_REALTIME_SPORADIC == ixQMgrQTypes[i]) + { + /* + * enable any sporadics + */ + ixQMgrLockKey = ixOsalIrqLock(); + ixQMgrAqmIfQInterruptEnable(i); + ixOsalIrqUnlock(ixQMgrLockKey); +#ifndef NDEBUG + /* + * Update statistics + */ + dispatcherStats.queueStats[i].enableCount++; + dispatcherStats.queueStats[i].notificationEnabled = TRUE; +#endif + } + } +} +IX_STATUS +ixQMgrCallbackTypeSet (IxQMgrQId qId, + IxQMgrType type) +{ + UINT32 ixQMgrLockKey = 0; + IxQMgrType ixQMgrOldType =0; + +#ifndef NDEBUG + if (!ixQMgrQIsConfigured(qId)) + { + return IX_QMGR_Q_NOT_CONFIGURED; + } + if (qId >= IX_QMGR_MIN_QUEUPP_QID) + { + return IX_QMGR_PARAMETER_ERROR; + } + if(!IX_QMGR_DISPATCHER_CALLBACK_TYPE_CHECK(type)) + { + return IX_QMGR_PARAMETER_ERROR; + } +#endif + + ixQMgrOldType = ixQMgrQTypes[qId]; + ixQMgrQTypes[qId] = type; + + /* + * check if Q has been changed from type SPORADIC + */ + if (IX_QMGR_TYPE_REALTIME_SPORADIC == ixQMgrOldType) + { + /* + * previously Q was a SPORADIC, this means that LLP + * might have had it disabled. enable it now. + */ + ixQMgrLockKey = ixOsalIrqLock(); + ixQMgrAqmIfQInterruptEnable(qId); + ixOsalIrqUnlock(ixQMgrLockKey); + +#ifndef NDEBUG + /* + * Update statistics + */ + dispatcherStats.queueStats[qId].enableCount++; +#endif + } + + return IX_SUCCESS; +} + +IX_STATUS +ixQMgrCallbackTypeGet (IxQMgrQId qId, + IxQMgrType *type) +{ +#ifndef NDEBUG + if (!ixQMgrQIsConfigured(qId)) + { + return IX_QMGR_Q_NOT_CONFIGURED; + } + if (qId >= IX_QMGR_MIN_QUEUPP_QID) + { + return IX_QMGR_PARAMETER_ERROR; + } + if(type == NULL) + { + return IX_QMGR_PARAMETER_ERROR; + } +#endif + + *type = ixQMgrQTypes[qId]; + return IX_SUCCESS; +} diff --git a/arch/arm/cpu/ixp/npe/IxQMgrInit.c b/arch/arm/cpu/ixp/npe/IxQMgrInit.c new file mode 100644 index 0000000000..b00c22d08e --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxQMgrInit.c @@ -0,0 +1,233 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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; iqStats[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; +} + + + + diff --git a/arch/arm/cpu/ixp/npe/IxQMgrQAccess.c b/arch/arm/cpu/ixp/npe/IxQMgrQAccess.c new file mode 100644 index 0000000000..8885736246 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxQMgrQAccess.c @@ -0,0 +1,796 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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 */ diff --git a/arch/arm/cpu/ixp/npe/IxQMgrQCfg.c b/arch/arm/cpu/ixp/npe/IxQMgrQCfg.c new file mode 100644 index 0000000000..ec7d837c38 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/IxQMgrQCfg.c @@ -0,0 +1,543 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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; +} diff --git a/arch/arm/cpu/ixp/npe/Makefile b/arch/arm/cpu/ixp/npe/Makefile new file mode 100644 index 0000000000..e1f970062d --- /dev/null +++ b/arch/arm/cpu/ixp/npe/Makefile @@ -0,0 +1,98 @@ +# +# (C) Copyright 2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB := $(obj)libnpe.a + +LOCAL_CFLAGS += -I$(TOPDIR)/arch/arm/cpu/ixp/npe/include -DCONFIG_IXP425_COMPONENT_ETHDB -D__linux +CFLAGS += $(LOCAL_CFLAGS) +HOSTCFLAGS += $(LOCAL_CFLAGS) + +COBJS-$(CONFIG_IXP4XX_NPE) := 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 + +SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +all: $(LIB) + +$(LIB): $(obj).depend $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/ixp/npe/include/IxAssert.h b/arch/arm/cpu/ixp/npe/include/IxAssert.h new file mode 100644 index 0000000000..eae8b3f273 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/IxAssert.h @@ -0,0 +1,71 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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 + */ + + + diff --git a/arch/arm/cpu/ixp/npe/include/IxAtmSch.h b/arch/arm/cpu/ixp/npe/include/IxAtmSch.h new file mode 100644 index 0000000000..73c3be29ab --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/IxAtmSch.h @@ -0,0 +1,504 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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 + * - IX_SUCCESS : indicates that + * -# The ATM scheduler component has been successfully initialized. + * -# The scheduler is ready to accept Port modelling requests. + * - IX_FAIL : 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 + * - IX_SUCCESS : 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. + * - IX_FAIL : 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 + * - IX_SUCCESS : The port rate has been successfully modified.
+ * - IX_FAIL : 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 + * - IX_SUCCESS : The VC has been successfully established on + * this port. The client may begin to submit demand on this VC. + * - IX_ATMSCH_RET_NOT_ADMITTED : The VC cannot be established + * on this port because there is insufficient upstream capacity + * available to support the requested traffic contract descriptor + * - IX_FAIL :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 + * - IX_SUCCESS : The id has successfully been set. + * - IX_FAIL :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 + * - IX_SUCCESS : The VC has been successfully removed from + * this port. It is no longer modelled on this port. + * - IX_FAIL :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 + * - IX_SUCCESS : The VC queue has been successfully updated. + * - IX_ATMSCH_RET_QUEUE_FULL : 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. + * - IX_FAIL : 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 + * - IX_SUCCESS : The VC queue has been successfully cleared. + * - IX_FAIL : 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 + * - IX_SUCCESS : The schedule table has been published. + * Currently there is at least one VC queue that is nonempty. + * - IX_ATMSCH_RET_QUEUE_EMPTY : 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. + * - IX_FAIL : 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 */ + +/** @} */ diff --git a/arch/arm/cpu/ixp/npe/include/IxAtmTypes.h b/arch/arm/cpu/ixp/npe/include/IxAtmTypes.h new file mode 100644 index 0000000000..8624c3328e --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/IxAtmTypes.h @@ -0,0 +1,409 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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 + */ + + diff --git a/arch/arm/cpu/ixp/npe/include/IxAtmdAcc.h b/arch/arm/cpu/ixp/npe/include/IxAtmdAcc.h new file mode 100644 index 0000000000..ae7b2434c3 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/IxAtmdAcc.h @@ -0,0 +1,1194 @@ + +/** + * @file IxAtmdAcc.h + * + * @date 07-Nov-2001 + * + * @brief IxAtmdAcc Public API + * + * This file contains the public API of IxAtmdAcc, related to the + * data functions of the component + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +/* ------------------------------------------------------ + Doxygen group definitions + ------------------------------------------------------ */ + +/** + * + * @defgroup IxAtmdAccAPI IXP400 ATM Driver Access (IxAtmdAcc) API + * + * @brief The public API for the IXP400 Atm Driver Data component + * + * IxAtmdAcc is the low level interface by which AAL0/AAL5 and + * OAM data gets transmitted to,and received from the Utopia bus. + * + * For AAL0/AAL5 services transmit and receive connections may + * be established independantly for unique combinations of + * port,VPI,and VCI. + * + * Two AAL0 services supporting 48 or 52 byte cell data are provided. + * Submitted AAL0 PDUs must be a multiple of the cell data size (48/52). + * AAL0_52 is a raw cell service the client must format + * the PDU with an ATM cell header (excluding HEC) at the start of + * each cell, note that AtmdAcc does not validate the cell headers in + * a submitted PDU. + * + * OAM cells cannot be received over the AAL0 service but instead + * are received over a dedicated OAM service. + * + * For the OAM service an "OAM Tx channel" may be enabled for a port + * by establishing a single dedicated OAM Tx connection on that port. + * A single "OAM Rx channel" for all ports may be enabled by + * establishing a dedicated OAM Rx connection. + * + * The OAM service allows buffers containing 52 byte OAM F4/F5 cells + * to be transmitted and received over the dedicated OAM channels. + * HEC is appended/removed, and CRC-10 performed by the NPE. The OAM + * service offered by AtmdAcc is a raw cell transport service. + * It is assumed that ITU I.610 procedures that make use of this + * service are implemented above AtmdAcc. + * + * Note that the dedicated OAM connections are established on + * reserved VPI,VCI, and (in the case of Rx) port values defined below. + * These values are used purely to descriminate the dedicated OAM channels + * and do not identify a particular OAM F4/F5 flow. F4/F5 flows may be + * realised for particluar VPI/VCIs by manipulating the VPI,VCI + * fields of the ATM cell headers of cells in the buffers passed + * to AtmdAcc. Note that AtmdAcc does not validate the cell headers + * in a submitted OAM PDU. + * + * + * + * This part is related to the User datapath processing + * + * @{ + */ + +#ifndef IXATMDACC_H +#define IXATMDACC_H + +#include "IxAtmTypes.h" + +/* ------------------------------------------------------ + AtmdAcc Data Types definition + ------------------------------------------------------ */ + +/** + * + * @ingroup IxAtmdAccAPI + * + * @def IX_ATMDACC_WARNING + * + * @brief Warning return code + * + * This constant is used to tell IxAtmDAcc user about a special case. + * + */ +#define IX_ATMDACC_WARNING 2 + +/** + * + * @ingroup IxAtmdAccAPI + * + * @def IX_ATMDACC_BUSY + * + * @brief Busy return code + * + * This constant is used to tell IxAtmDAcc user that the request + * is correct, but cannot be processed because the IxAtmAcc resources + * are already used. The user has to retry its request later + * + */ +#define IX_ATMDACC_BUSY 3 + +/** + * + * @ingroup IxAtmdAccAPI + * + * @def IX_ATMDACC_RESOURCES_STILL_ALLOCATED + * + * @brief Disconnect return code + * + * This constant is used to tell IxAtmDAcc user that the disconnect + * functions are not complete because the resources used by the driver + * are not yet released. The user has to retry the disconnect call + * later. + * + */ +#define IX_ATMDACC_RESOURCES_STILL_ALLOCATED 4 + +/** + * + * @ingroup IxAtmdAccAPI + * + * @def IX_ATMDACC_DEFAULT_REPLENISH_COUNT + * + * @brief Default resources usage for RxVcFree replenish mechanism + * + * This constant is used to tell IxAtmDAcc to allocate and use + * the minimum of resources for rx free replenish. + * + * @sa ixAtmdAccRxVcConnect + */ +#define IX_ATMDACC_DEFAULT_REPLENISH_COUNT 0 + + +/** + * @ingroup IxAtmdAccAPI + * + * @def IX_ATMDACC_OAM_TX_VPI + * + * @brief The reserved value used for the dedicated OAM + * Tx connection. This "well known" value is used by atmdAcc and + * its clients to dsicriminate the OAM channel, and should be chosen so + * that it does not coencide with the VPI value used in an AAL0/AAL5 connection. + * Any attempt to connect a service type other than OAM on this VPI will fail. + * + * + */ +#define IX_ATMDACC_OAM_TX_VPI 0 + +/** + * @ingroup IxAtmdAccAPI + * + * @def IX_ATMDACC_OAM_TX_VCI + * + * @brief The reserved value used for the dedicated OAM + * Tx connection. This "well known" value is used by atmdAcc and + * its clients to dsicriminate the OAM channel, and should be chosen so + * that it does not coencide with the VCI value used in an AAL0/AAL5 connection. + * Any attempt to connect a service type other than OAM on this VCI will fail. + */ +#define IX_ATMDACC_OAM_TX_VCI 0 + + + /** + * @ingroup IxAtmdAccAPI + * + * @def IX_ATMDACC_OAM_RX_PORT + * + * @brief The reserved dummy PORT used for all dedicated OAM + * Rx connections. Note that this is not a real port but must + * have a value that lies within the valid range of port values. + */ +#define IX_ATMDACC_OAM_RX_PORT IX_UTOPIA_PORT_0 + + /** + * @ingroup IxAtmdAccAPI + * + * @def IX_ATMDACC_OAM_RX_VPI + * + * @brief The reserved value value used for the dedicated OAM + * Rx connection. This value should be chosen so that it does not + * coencide with the VPI value used in an AAL0/AAL5 connection. + * Any attempt to connect a service type other than OAM on this VPI will fail. + */ +#define IX_ATMDACC_OAM_RX_VPI 0 + +/** + * @ingroup IxAtmdAccAPI + * + * @def IX_ATMDACC_OAM_RX_VCI + * + * @brief The reserved value value used for the dedicated OAM + * Rx connection. This value should be chosen so that it does not + * coencide with the VCI value used in an AAL0/AAL5 connection. + * Any attempt to connect a service type other than OAM on this VCI will fail. + */ +#define IX_ATMDACC_OAM_RX_VCI 0 + + +/** + * @enum IxAtmdAccPduStatus + * + * @ingroup IxAtmdAccAPI + * + * @brief IxAtmdAcc Pdu status : + * + * IxAtmdAccPduStatus is used during a RX operation to indicate + * the status of the received PDU + * + */ + +typedef enum +{ + IX_ATMDACC_AAL0_VALID = 0, /**< aal0 pdu */ + IX_ATMDACC_OAM_VALID, /**< OAM pdu */ + IX_ATMDACC_AAL2_VALID, /**< aal2 pdu @b reserved for future use */ + IX_ATMDACC_AAL5_VALID, /**< aal5 pdu complete and trailer is valid */ + IX_ATMDACC_AAL5_PARTIAL, /**< aal5 pdu not complete, trailer is missing */ + IX_ATMDACC_AAL5_CRC_ERROR, /**< aal5 pdu not complete, crc error/length error */ + IX_ATMDACC_MBUF_RETURN /**< empty buffer returned to the user */ +} IxAtmdAccPduStatus; + + +/** + * + * @enum IxAtmdAccAalType + * + * @ingroup IxAtmdAccAPI + * + * @brief IxAtmdAcc AAL Service Type : + * + * IxAtmdAccAalType defines the type of traffic to run on this VC + * + */ +typedef enum +{ + IX_ATMDACC_AAL5, /**< ITU-T AAL5 */ + IX_ATMDACC_AAL2, /**< ITU-T AAL2 @b reserved for future use */ + IX_ATMDACC_AAL0_48, /**< AAL0 48 byte payloads (cell header is added by NPE)*/ + IX_ATMDACC_AAL0_52, /**< AAL0 52 byte cell data (HEC is added by NPE) */ + IX_ATMDACC_OAM, /**< OAM cell transport service (HEC is added by NPE)*/ + IX_ATMDACC_MAX_SERVICE_TYPE /**< not a service, used for parameter validation */ +} IxAtmdAccAalType; + +/** + * + * @enum IxAtmdAccClpStatus + * + * @ingroup IxAtmdAccAPI + * + * @brief IxAtmdAcc CLP indication + * + * IxAtmdAccClpStatus defines the CLP status of the current PDU + * + */ +typedef enum +{ + IX_ATMDACC_CLP_NOT_SET = 0, /**< CLP indication is not set */ + IX_ATMDACC_CLP_SET = 1 /**< CLP indication is set */ +} IxAtmdAccClpStatus; + +/** + * @typedef IxAtmdAccUserId + * + * @ingroup IxAtmdAccAPI + * + * @brief User-supplied Id + * + * IxAtmdAccUserId is passed through callbacks and allows the + * IxAtmdAcc user to identify the source of a call back. The range of + * this user-owned Id is [0...2^32-1)]. + * + * The user provides this own Ids on a per-channel basis as a parameter + * in a call to @a ixAtmdAccRxVcConnect() or @a ixAtmdAccRxVcConnect() + * + * @sa ixAtmdAccRxVcConnect + * @sa ixAtmdAccTxVcConnect + * + */ +typedef unsigned int IxAtmdAccUserId; + +/* ------------------------------------------------------ + Part of the IxAtmdAcc interface related to RX traffic + ------------------------------------------------------ */ + +/** + * + * @ingroup IxAtmdAccAPI + * + * @brief Rx callback prototype + * + * IxAtmdAccRxVcRxCallback is the prototype of the Rx callback user + * function called once per PDU to pass a receive Pdu to a user on a + * partilcular connection. The callback is likely to push the mbufs + * to a protocol layer, and recycle the mbufs for a further use. + * + * @note -This function is called ONLY in the context of + * the @a ixAtmdAccRxDispatch() function + * + * @sa ixAtmdAccRxDispatch + * @sa ixAtmdAccRxVcConnect + * + * @param port @ref IxAtmLogicalPort [in] - the port on which this PDU was received + * a logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] + * @param userId @ref IxAtmdAccUserId [in] - user Id provided in the call + * to @a ixAtmdAccRxVcConnect() + * @param status @ref IxAtmdAccPduStatus [in] - an indication about the PDU validity. + * In the case of AAL0 the only possibile value is + * AAL0_VALID, in this case the client may optionally determine + * that an rx timeout occured by checking if the mbuf is + * compleletly or only partially filled, the later case + * indicating a timeout. + * In the case of OAM the only possible value is OAM valid. + * The status is set to @a IX_ATMDACC_MBUF_RETURN when + * the mbuf is released during a disconnect process. + * @param clp @ref IxAtmdAccClpStatus [in] - clp indication for this PDU. + * For AAL5/AAL0_48 this information + * is set if the clp bit of any rx cell is set + * For AAL0-52/OAM the client may inspect the CLP in individual + * cell headers in the PDU, and this parameter is set to 0. + * @param *mbufPtr @ref IX_OSAL_MBUF [in] - depending on the servive type a pointer to + * an mbuf (AAL5/AAL0/OAM) or mbuf chain (AAL5 only), + * that comprises the complete PDU data. + * + * This parameter is guaranteed not to be a null pointer. + * + */ +typedef void (*IxAtmdAccRxVcRxCallback) (IxAtmLogicalPort port, + IxAtmdAccUserId userId, + IxAtmdAccPduStatus status, + IxAtmdAccClpStatus clp, + IX_OSAL_MBUF * mbufPtr); + +/** + * + * @ingroup IxAtmdAccAPI + * + * @brief Callback prototype for free buffer level is low. + * + * IxAtmdAccRxVcFreeLowCallback is the prototype of the user function + * which get called on a per-VC basis, when more mbufs are needed to + * continue the ATM data reception. This function is likely to supply + * more available mbufs by one or many calls to the replenish function + * @a ixAtmdAccRxVcFreeReplenish() + * + * This function is called when the number of available buffers for + * reception is going under the threshold level as defined + * in @a ixAtmdAccRxVcFreeLowCallbackRegister() + * + * This function is called inside an Qmgr dispatch context. No system + * resource or interrupt-unsafe feature should be used inside this + * callback. + * + * @sa ixAtmdAccRxVcFreeLowCallbackRegister + * @sa IxAtmdAccRxVcFreeLowCallback + * @sa ixAtmdAccRxVcFreeReplenish + * @sa ixAtmdAccRxVcFreeEntriesQuery + * @sa ixAtmdAccRxVcConnect + * + * @param userId @ref IxAtmdAccUserId [in] - user Id provided in the call + * to @a ixAtmdAccRxVcConnect() + * + * @return None + * + */ +typedef void (*IxAtmdAccRxVcFreeLowCallback) (IxAtmdAccUserId userId); + +/* ------------------------------------------------------ + Part of the IxAtmdAcc interface related to TX traffic + ------------------------------------------------------ */ + +/** + * + * @ingroup IxAtmdAccAPI + * + * @brief Buffer callback prototype. + * + * This function is called to relinguish ownership of a transmitted + * buffer chain to the user. + * + * @note -In the case of a chained mbuf the AmtdAcc component can + * chain many user buffers together and pass ownership to the user in + * one function call. + * + * @param userId @ref IxAtmdAccUserId [in] - user If provided at registration of this + * callback. + * @param mbufPtr @ref IX_OSAL_MBUF [in] - a pointer to mbufs or chain of mbufs and is + * guaranteed not to be a null pointer. + * + */ +typedef void (*IxAtmdAccTxVcBufferReturnCallback) (IxAtmdAccUserId userId, + IX_OSAL_MBUF * mbufPtr); + +/* ------------------------------------------------------ + Part of the IxAtmdAcc interface related to Initialisation + ------------------------------------------------------ */ + +/** + * + * @ingroup IxAtmdAccAPI + * + * @fn ixAtmdAccInit (void) + * + * @brief Initialise the IxAtmdAcc Component + * + * This function initialise the IxAtmdAcc component. This function shall + * be called before any other function of the API. Its role is to + * initialise all internal resources of the IxAtmdAcc component. + * + * The ixQmgr component needs to be initialized prior the use of + * @a ixAtmdAccInit() + * + * @param none + * + * Failing to initilialize the IxAtmdAcc API before any use of it will + * result in a failed status. + * If the specified component is not present, a success status will still be + * returned, however, a warning indicating the NPE to download to is not + * present will be issued. + * + * @return @li IX_SUCCESS initialisation is complete (in case of component not + * being present, a warning is clearly indicated) + * @return @li IX_FAIL unable to process this request either + * because this IxAtmdAcc is already initialised + * or some unspecified error has occrred. + */ +PUBLIC IX_STATUS ixAtmdAccInit (void); + +/** + * + * @ingroup IxAtmdAccAPI + * + * @fn ixAtmdAccShow (void) + * + * @brief Show IxAtmdAcc configuration on a per port basis + * + * @param none + * + * @return none + * + * @note - Display use printf() and are redirected to stdout + */ +PUBLIC void +ixAtmdAccShow (void); + +/** + * + * @ingroup IxAtmdAccAPI + * + * @fn ixAtmdAccStatsShow (void) + * + * @brief Show all IxAtmdAcc stats + * + * @param none + * + * @return none + * + * @note - Stats display use printf() and are redirected to stdout + */ +PUBLIC void +ixAtmdAccStatsShow (void); + +/** + * + * @ingroup IxAtmdAccAPI + * + * @fn ixAtmdAccStatsReset (void) + * + * @brief Reset all IxAtmdAcc stats + * + * @param none + * + * @return none + * + */ +PUBLIC void +ixAtmdAccStatsReset (void); + +/* ------------------------------------------------------ + Part of the IxAtmdAcc interface related to RX traffic + ------------------------------------------------------ */ + +/** + * + * @ingroup IxAtmdAccAPI + * + * @fn ixAtmdAccRxVcConnect (IxAtmLogicalPort port, + unsigned int vpi, + unsigned int vci, + IxAtmdAccAalType aalServiceType, + IxAtmRxQueueId rxQueueId, + IxAtmdAccUserId userCallbackId, + IxAtmdAccRxVcRxCallback rxCallback, + unsigned int minimumReplenishCount, + IxAtmConnId * connIdPtr, + IxAtmNpeRxVcId * npeVcIdPtr ) + * + * @brief Connect to a Aal Pdu receive service for a particular + * port/vpi/vci, and service type. + * + * This function allows a user to connect to an Aal5/Aal0/OAM Pdu receive service + * for a particular port/vpi/vci. It registers the callback and allocates + * internal resources and a Connection Id to be used in further API calls + * related to this VCC. + * + * The function will setup VC receive service on the specified rx queue. + * + * This function is blocking and makes use internal locks, and hence + * should not be called from an interrupt context. + * + * On return from @a ixAtmdAccRxVcConnect() with a failure status, the + * connection Id parameter is unspecified. Its value cannot be used. + * A connId is the reference by which IxAtmdAcc refers to a + * connected VC. This identifier is the result of a succesful call + * to a connect function. This identifier is invalid after a + * sucessful call to a disconnect function. + * + * Calling this function for the same combination of Vpi, Vci and more + * than once without calling @a ixAtmdAccRxVcTryDisconnect() will result in a + * failure status. + * + * If this function returns success the user should supply receive + * buffers by calling @a ixAtmdAccRxVcFreeReplenish() and then call + * @a ixAtmdAccRxVcEnable() to begin receiving pdus. + * + * There is a choice of two receive Qs on which the VC pdus could be + * receive. The user must associate the VC with one of these. Essentially + * having two qs allows more flexible system configuration such as have + * high prioriy traffic on one q (e.g. voice) and low priority traffic on + * the other (e.g. data). The high priority Q could be serviced in + * preference to the low priority Q. One queue may be configured to be + * serviced as soon as there is traffic, the other queue may be configured + * to be serviced by a polling mechanism running at idle time. + * + * Two AAL0 services supporting 48 or 52 byte cell data are provided. + * Received AAL0 PDUs will be be a multiple of the cell data size (48/52). + * AAL0_52 is a raw cell service and includes an ATM cell header + * (excluding HEC) at the start of each cell. + * + * A single "OAM Rx channel" for all ports may be enabled by + * establishing a dedicated OAM Rx connection. + * + * The OAM service allows buffers containing 52 byte OAM F4/F5 cells + * to be transmitted and received over the dedicated OAM channels. + * HEC is appended/removed, and CRC-10 performed by the NPE. The OAM + * service offered by AtmdAcc is a raw cell transport service. + * It is assumed that ITU I.610 procedures that make use of this + * service are implemented above AtmdAcc. + * + * Note that the dedicated OAM connections are established on + * reserved VPI,VCI, and (in the case of Rx) port values. + * These values are used purely to descriminate the dedicated OAM channels + * and do not identify a particular OAM F4/F5 flow. F4/F5 flows may be + * realised for particluar VPI/VCIs by manipulating the VPI,VCI + * fields of the ATM cell headers of cells in the buffers passed + * to AtmdAcc. + * + * Calling this function prior to enable the port will fail. + * + * @sa ixAtmdAccRxDispatch + * @sa ixAtmdAccRxVcEnable + * @sa ixAtmdAccRxVcDisable + * @sa ixAtmdAccRxVcTryDisconnect + * @sa ixAtmdAccPortEnable + * + * @param port @ref IxAtmLogicalPort [in] - VC identification : logical PHY port + * [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] + * @param vpi unsigned int [in] - VC identification : ATM Vpi [0..255] or IX_ATMDACC_OAM_VPI + * @param vci unsigned int [in] - VC identification : ATM Vci [0..65535] or IX_ATMDACC_OAM_VCI + * @param aalServiceType @ref IxAtmdAccAalType [in] - type of service: AAL5, AAL0_48, AAL0_52, or OAM + * @param rxQueueId @ref IxAtmRxQueueId [in] - this identifieds which of two Qs the VC + * should use.when icoming traffic is processed + * @param userCallbackId @ref IxAtmdAccUserId [in] - user Id used later as a parameter to + * the supplied rxCallback. + * @param rxCallback [in] @ref IxAtmdAccRxVxRxCallback - function called when mbufs are received. + * This parameter cannot be a null pointer. + * @param bufferFreeCallback [in] - function to be called to return + * ownership of buffers to IxAtmdAcc user. + * @param minimumReplenishCount unsigned int [in] - For AAL5/AAL0 the number of free mbufs + * to be used with this channel. Use a high number when the expected traffic + * rate on this channel is high, or when the user's mbufs are small, or when + * the RxVcFreeLow Notification has to be invoked less often. When this + * value is IX_ATMDACC_DEFAULT_REPLENISH_COUNT, the minimum of + * resources will be used. Depending on traffic rate, pdu + * size and mbuf size, rxfree queue size, polling/interrupt rate, this value may + * require to be replaced by a different value in the range 1-128 + * For OAM the rxFree queue size is fixed by atmdAcc and this parameter is ignored. + * @param connIdPtr @ref IxAtmConnId [out] - pointer to a connection Id + * This parameter cannot be a null pointer. + * @param npeVcIdPtr @ref IxAtmNpeRxVcId [out] - pointer to an npe Vc Id + * This parameter cannot be a null pointer. + * + * @return @li IX_SUCCESS successful call to IxAtmdAccRxVcConnect + * @return @li IX_ATMDACC_BUSY cannot process this request : + * no VC is available + * @return @li IX_FAIL + * parameter error, + * VC already in use, + * attempt to connect AAL service on reserved OAM VPI/VCI, + * attempt to connect OAM service on VPI/VCI other than the reserved OAM VPI/VCI, + * port is not initialised, + * or some other error occurs during processing. + * + */ +PUBLIC IX_STATUS ixAtmdAccRxVcConnect (IxAtmLogicalPort port, + unsigned int vpi, + unsigned int vci, + IxAtmdAccAalType aalServiceType, + IxAtmRxQueueId rxQueueId, + IxAtmdAccUserId userCallbackId, + IxAtmdAccRxVcRxCallback rxCallback, + unsigned int minimumReplenishCount, + IxAtmConnId * connIdPtr, + IxAtmNpeRxVcId * npeVcIdPtr ); + +/** + * + * @ingroup IxAtmdAccAPI + * + * @fn ixAtmdAccRxVcFreeReplenish (IxAtmConnId connId, + IX_OSAL_MBUF * mbufPtr) + * + * @brief Provide free mbufs for data reception on a connection. + * + * This function provides mbufs for data reception by the hardware. This + * function needs to be called by the user on a regular basis to ensure + * no packet loss. Providing free buffers is a connection-based feature; + * each connection can have different requirements in terms of buffer size + * number of buffers, recycling rate. This function could be invoked from + * within the context of a @a IxAtmdAccRxVcFreeLowCallback() callback + * for a particular VC + * + * Mbufs provided through this function call can be chained. They will be + * unchained internally. A call to this function with chained mbufs or + * multiple calls with unchained mbufs are equivalent, but calls with + * unchained mbufs are more efficients. + * + * Mbufs provided to this interface need to be able to hold at least one + * full cell payload (48/52 bytes, depending on service type). + * Chained buffers with a size less than the size supported by the hardware + * will be returned through the rx callback provided during the connect step. + * + * Failing to invoke this function prior to enabling the RX traffic + * can result in packet loss. + * + * This function is not reentrant for the same connId. + * + * This function does not use system resources and can be + * invoked from an interrupt context. + * + * @note - Over replenish is detected, and extra mbufs are returned through + * the rx callback provided during the connect step. + * + * @note - Mbuf provided to the replenish function should have a length greater or + * equal to 48/52 bytes according to service type. + * + * @note - The memory cache of mMbuf payload should be invalidated prior to Mbuf + * submission. Flushing the Mbuf headers is handled by IxAtmdAcc. + * + * @note - When a chained mbuf is provided, this function process the mbufs + * up to the hardware limit and invokes the user-supplied callback + * to release extra buffers. + * + * @sa ixAtmdAccRxVcFreeLowCallbackRegister + * @sa IxAtmdAccRxVcFreeLowCallback + * @sa ixAtmdAccRxVcConnect + * + * @param connId @ref IxAtmConnId [in] - connection Id as returned from a succesfull call to + * @a IxAtmdAccRxVcConnect() + * @param mbufPtr @ref IX_OSAL_MBUF [in] - pointer to a mbuf structure to be used for data + * reception. The mbuf pointed to by this parameter can be chained + * to an other mbuf. + * + * @return @li IX_SUCCESS successful call to @a ixAtmdAccRxVcFreeReplenish() + * and the mbuf is now ready to use for incoming traffic. + * @return @li IX_ATMDACC_BUSY cannot process this request because + * the max number of outstanding free buffers has been reached + * or the internal resources have exhausted for this VC. + * The user is responsible for retrying this request later. + * @return @li IX_FAIL cannot process this request because of parameter + * errors or some unspecified internal error has occurred. + * + * @note - It is not always guaranteed the replenish step to be as fast as the + * hardware is consuming Rx Free mbufs. There is nothing in IxAtmdAcc to + * guarantee that replenish reaches the rxFree threshold level. If the + * threshold level is not reached, the next rxFree low notification for + * this channel will not be triggered. + * The preferred ways to replenish can be as follows (depending on + * applications and implementations) : + * @li Replenish in a rxFree low notification until the function + * ixAtmdAccRxVcFreeReplenish() returns IX_ATMDACC_BUSY + * @li Query the queue level using @sa ixAtmdAccRxVcFreeEntriesQuery, then + * , replenish using @a ixAtmdAccRxVcFreeReplenish(), then query the queue + * level again, and replenish if the threshold is still not reached. + * @li Trigger replenish from an other event source and use rxFree starvation + * to throttle the Rx traffic. + * + */ +PUBLIC IX_STATUS ixAtmdAccRxVcFreeReplenish (IxAtmConnId connId, + IX_OSAL_MBUF * mbufPtr); + +/** + * + * @ingroup IxAtmdAccAPI + * + * @fn ixAtmdAccRxVcFreeLowCallbackRegister (IxAtmConnId connId, + unsigned int numberOfMbufs, + IxAtmdAccRxVcFreeLowCallback callback) + * + * @brief Configure the RX Free threshold value and register a callback + * to handle threshold notifications. + * + * The function ixAtmdAccRxVcFreeLowCallbackRegister sets the threshold value for + * a particular RX VC. When the number of buffers reaches this threshold + * the callback is invoked. + * + * This function should be called once per VC before RX traffic is + * enabled.This function will fail if the curent level of the free buffers + * is equal or less than the threshold value. + * + * @sa ixAtmdAccRxVcFreeLowCallbackRegister + * @sa IxAtmdAccRxVcFreeLowCallback + * @sa ixAtmdAccRxVcFreeReplenish + * @sa ixAtmdAccRxVcFreeEntriesQuery + * @sa ixAtmdAccRxVcConnect + * + * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call + * to @a IxAtmdAccRxVcConnect() + * @param numberOfMbufs unsigned int [in] - threshold number of buffers. This number + * has to be a power of 2, one of the values 0,1,2,4,8,16,32.... + * The maximum value cannot be more than half of the rxFree queue + * size (which can be retrieved using @a ixAtmdAccRxVcFreeEntriesQuery() + * before any use of the @a ixAtmdAccRxVcFreeReplenish() function) + * @param callback @ref IxAtmdAccRxVcFreeLowCallback [in] - function telling the user that the number of + * free buffers has reduced to the threshold value. + * + * @return @li IX_SUCCESS Threshold set successfully. + * @return @li IX_FAIL parameter error or the current number of free buffers + * is less than or equal to the threshold supplied or some + * unspecified error has occrred. + * + * @note - the callback will be called when the threshold level will drop from + * exactly (numberOfMbufs + 1) to (numberOfMbufs). + * + */ +PUBLIC IX_STATUS ixAtmdAccRxVcFreeLowCallbackRegister (IxAtmConnId connId, + unsigned int numberOfMbufs, + IxAtmdAccRxVcFreeLowCallback callback); + +/** + * + * @ingroup IxAtmdAccAPI + * + * @fn ixAtmdAccRxVcFreeEntriesQuery (IxAtmConnId connId, + unsigned int *numberOfMbufsPtr) + * + * @brief Get the number of rx mbufs the system can accept to replenish the + * the rx reception mechanism on a particular channel + * + * The ixAtmdAccRxVcFreeEntriesQuery function is used to retrieve the current + * number of available mbuf entries for reception, on a per-VC basis. This + * function can be used to know the number of mbufs which can be provided + * using @a ixAtmdAccRxVcFreeReplenish(). + * + * This function can be used from a timer context, or can be associated + * with a threshold event, or can be used inside an active polling + * mechanism which is under user control. + * + * This function is reentrant and does not use system resources and can + * be invoked from an interrupt context. + * + * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call + * to @a IxAtmdAccRxVcConnect() + * @param numberOfMbufsPtr unsigned int [out] - Pointer to the number of available entries. + * . This parameter cannot be a null pointer. + * + * @return @li IX_SUCCESS the current number of mbufs not yet used for incoming traffic + * @return @li IX_FAIL invalid parameter + * + * @sa ixAtmdAccRxVcFreeReplenish + * + */ +PUBLIC IX_STATUS ixAtmdAccRxVcFreeEntriesQuery (IxAtmConnId connId, + unsigned int *numberOfMbufsPtr); + +/** + * + * @ingroup IxAtmdAccAPI + * + * @fn ixAtmdAccRxVcEnable (IxAtmConnId connId) + * + * @brief Start the RX service on a VC. + * + * This functions kicks-off the traffic reception for a particular VC. + * Once invoked, incoming PDUs will be made available by the hardware + * and are eventually directed to the @a IxAtmdAccRxVcRxCallback() callback + * registered for the connection. + * + * If the traffic is already running, this function returns IX_SUCCESS. + * This function can be invoked many times. + * + * IxAtmdAccRxVcFreeLowCallback event will occur only after + * @a ixAtmdAccRxVcEnable() function is invoked. + * + * Before using this function, the @a ixAtmdAccRxVcFreeReplenish() function + * has to be used to replenish the RX Free queue. If not, incoming traffic + * may be discarded.and in the case of interrupt driven reception the + * @a IxAtmdAccRxVcFreeLowCallback() callback may be invoked as a side effect + * during a replenish action. + * + * This function is not reentrant and should not be used inside an + * interrupt context. + * + * For an VC connection this function can be called after a call to + * @a ixAtmdAccRxVcDisable() and should not be called after + * @a ixAtmdAccRxVcTryDisconnect() + * + * @sa ixAtmdAccRxVcDisable + * @sa ixAtmdAccRxVcConnect + * @sa ixAtmdAccRxVcFreeReplenish + * + * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call + * to @a IxAtmdAccRxVcConnect() + * + * @return @li IX_SUCCESS successful call to ixAtmdAccRxVcEnable + * @return @li IX_ATMDACC_WARNING the channel is already enabled + * @return @li IX_FAIL invalid parameters or some unspecified internal + * error occured. + * + */ +PUBLIC IX_STATUS ixAtmdAccRxVcEnable (IxAtmConnId connId); + +/** + * + * @ingroup IxAtmdAccAPI + * + * @fn ixAtmdAccRxVcDisable (IxAtmConnId connId) + * + * @brief Stop the RX service on a VC. + * + * This functions stops the traffic reception for a particular VC connection. + * + * Once invoked, incoming Pdus are discarded by the hardware. Any Pdus + * pending will be freed to the user + * + * Hence once this function returns no more receive callbacks will be + * called for that VC. However, buffer free callbacks will be invoked + * until such time as all buffers supplied by the user have been freed + * back to the user + * + * Calling this function doe not invalidate the connId. + * @a ixAtmdAccRxVcEnable() can be invoked to enable Pdu reception again. + * + * If the traffic is already stopped, this function returns IX_SUCCESS. + * + * This function is not reentrant and should not be used inside an + * interrupt context. + * + * @sa ixAtmdAccRxVcConnect + * @sa ixAtmdAccRxVcEnable + * @sa ixAtmdAccRxVcDisable + * + * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call to @a + * IxAtmdAccRxVcConnect() + * + * @return @li IX_SUCCESS successful call to @a ixAtmdAccRxVcDisable(). + * @return @li IX_ATMDACC_WARNING the channel is already disabled + * @return @li IX_FAIL invalid parameters or some unspecified internal error occured + * + */ +PUBLIC IX_STATUS ixAtmdAccRxVcDisable (IxAtmConnId connId); + +/** + * + * @ingroup IxAtmdAccAPI + * + * @fn ixAtmdAccRxVcTryDisconnect (IxAtmConnId connId) + * + * @brief Disconnect a VC from the RX service. + * + * This function deregisters the VC and guarantees that all resources + * associated with this VC are free. After its execution, the connection + * Id is not available. + * + * This function will fail until such time as all resources allocated to + * the VC connection have been freed. The user is responsible to delay and + * call again this function many times until a success status is returned. + * + * This function needs internal locks and should not be called from an + * interrupt context + * + * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call to + * @a IxAtmdAccRxVcConnect() + * + * @return @li IX_SUCCESS successful call to ixAtmdAccRxVcDisable + * @return @li IX_ATMDACC_RESOURCES_STILL_ALLOCATED not all resources + * associated with the connection have been freed. + * @return @li IX_FAIL cannot process this request because of a parameter + * error + * + */ +PUBLIC IX_STATUS ixAtmdAccRxVcTryDisconnect (IxAtmConnId connId); + +/* ------------------------------------------------------ + Part of the IxAtmdAcc interface related to TX traffic + ------------------------------------------------------ */ + +/** + * + * @ingroup IxAtmdAccAPI + * + * @fn ixAtmdAccTxVcConnect (IxAtmLogicalPort port, + unsigned int vpi, + unsigned int vci, + IxAtmdAccAalType aalServiceType, + IxAtmdAccUserId userId, + IxAtmdAccTxVcBufferReturnCallback bufferFreeCallback, + IxAtmConnId * connIdPtr) + * + * @brief Connect to a Aal Pdu transmit service for a particular + * port/vpi/vci and service type. + * + * This function allows a user to connect to an Aal5/Aal0/OAM Pdu transmit service + * for a particular port/vpi/vci. It registers the callback and allocates + * internal resources and a Connection Id to be used in further API calls + * related to this VC. + * + * The function will setup VC transmit service on the specified on the + * specified port. A connId is the reference by which IxAtmdAcc refers to a + * connected VC. This identifier is the result of a succesful call + * to a connect function. This identifier is invalid after a + * sucessful call to a disconnect function. + * + * This function needs internal locks, and hence should not be called + * from an interrupt context. + * + * On return from @a ixAtmdAccTxVcConnect() with a failure status, the + * connection Id parameter is unspecified. Its value cannot be used. + * + * Calling this function for the same combination of port, Vpi, Vci and + * more than once without calling @a ixAtmdAccTxVcTryDisconnect() will result + * in a failure status. + * + * Two AAL0 services supporting 48 or 52 byte cell data are provided. + * Submitted AAL0 PDUs must be a multiple of the cell data size (48/52). + * AAL0_52 is a raw cell service the client must format + * the PDU with an ATM cell header (excluding HEC) at the start of + * each cell, note that AtmdAcc does not validate the cell headers in + * a submitted PDU. + * + * For the OAM service an "OAM Tx channel" may be enabled for a port + * by establishing a single dedicated OAM Tx connection on that port. + * + * The OAM service allows buffers containing 52 byte OAM F4/F5 cells + * to be transmitted and received over the dedicated OAM channels. + * HEC is appended/removed, and CRC-10 performed by the NPE. The OAM + * service offered by AtmdAcc is a raw cell transport service. + * It is assumed that ITU I.610 procedures that make use of this + * service are implemented above AtmdAcc. + * + * Note that the dedicated OAM connections are established on + * reserved VPI,VCI, and (in the case of Rx) port values. + * These values are used purely to descriminate the dedicated OAM channels + * and do not identify a particular OAM F4/F5 flow. F4/F5 flows may be + * realised for particluar VPI/VCIs by manipulating the VPI,VCI + * fields of the ATM cell headers of cells in the buffers passed + * to AtmdAcc. + * + * Calling this function before enabling the port will fail. + * + * @sa ixAtmdAccTxVcTryDisconnect + * @sa ixAtmdAccPortTxScheduledModeEnable + * @sa ixAtmdAccPortEnable + * + * @param port @ref IxAtmLogicalPort [in] - VC identification : logical PHY port + * [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] + * @param vpi unsigned int [in] - VC identification : ATM Vpi [0..255] or IX_ATMDACC_OAM_VPI + * @param vci unsigned int [in] - VC identification : ATM Vci [0..65535] or IX_ATMDACC_OAM_VCI + * @param aalServiceType @ref IxAtmdAccAalType [in] - type of service AAL5, AAL0_48, AAL0_52, or OAM + * @param userId @ref IxAtmdAccUserId [in] - user id to be used later during callbacks related + * to this channel + * @param bufferFreeCallback @ref IxAtmdAccTxVcBufferReturnCallback [in] - function called when mbufs + * transmission is complete. This parameter cannot be a null + * pointer. + * @param connIdPtr @ref IxAtmConnId [out] - Pointer to a connection Id. + * This parameter cannot be a null pointer. + * + * @return @li IX_SUCCESS successful call to @a IxAtmdAccRxVcConnect(). + * @return @li IX_ATMDACC_BUSY cannot process this request + * because no VC is available + * @return @li IX_FAIL + * parameter error, + * VC already in use, + * attempt to connect AAL service on reserved OAM VPI/VCI, + * attempt to connect OAM service on VPI/VCI other than the reserved OAM VPI/VCI, + * port is not initialised, + * or some other error occurs during processing. + * + * @note - Unscheduled mode is not supported in ixp425 1.0. Therefore, the + * function @a ixAtmdAccPortTxScheduledModeEnable() need to be called + * for this port before any establishing a Tx Connection + */ +PUBLIC IX_STATUS ixAtmdAccTxVcConnect (IxAtmLogicalPort port, + unsigned int vpi, + unsigned int vci, + IxAtmdAccAalType aalServiceType, + IxAtmdAccUserId userId, + IxAtmdAccTxVcBufferReturnCallback bufferFreeCallback, + IxAtmConnId * connIdPtr); + +/** + * + * @ingroup IxAtmdAccAPI + * + * @fn ixAtmdAccTxVcPduSubmit (IxAtmConnId connId, + IX_OSAL_MBUF * mbufPtr, + IxAtmdAccClpStatus clp, + unsigned int numberOfCells) + * + * @brief Submit a Pdu for transmission on connection. + * + * A data user calls this function to submit an mbufs containing a Pdu + * to be transmitted. The buffer supplied can be chained and the Pdu it + * contains must be complete. + * + * The transmission behavior of this call depends on the operational mode + * of the port on which the connection is made. + * + * In unscheduled mode the mbuf will be submitted to the hardware + * immediately if sufficent resource is available. Otherwise the function + * will return failure. + * + * In scheduled mode the buffer is queued internally in IxAtmdAcc. The cell + * demand is made known to the traffic shaping entity. Cells from the + * buffers are MUXed onto the port some time later as dictated by the + * traffic shaping entity. The traffic shaping entity does this by sending + * transmit schedules to IxAtmdAcc via @a ixAtmdAccPortTxProcess() function call. + * + * Note that the dedicated OAM channel is scheduled just like any + * other channel. This means that any OAM traffic relating to an + * active AAL0/AAL5 connection will be scheduled independantly of the + * AAL0/AAL5 traffic for that connection. + * + * When transmission is complete, the TX Done mechanism will give the + * owmnership of these buffers back to the customer. The tx done mechanism + * must be in operation before transmission is attempted. + * + * For AAL0/OAM submitted AAL0 PDUs must be a multiple of the cell data + * size (48/52). AAL0_52 and OAM are raw cell services, and the client + * must format the PDU with an ATM cell header (excluding HEC) at the + * start of each cell, note that AtmdAcc does not validate the cell headers in + * a submitted PDU. + * + * + * @sa IxAtmdAccTxVcBufferReturnCallback + * @sa ixAtmdAccTxDoneDispatch + * + * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call to + * @a ixAtmdAccTxVcConnect() + * @param mbufPtr @ref IX_OSAL_MBUF [in] - pointer to a chained structure of mbufs to transmit. + * This parameter cannot be a null pointer. + * @param clp @ref IxAtmdAccClpStatus [in] - clp indication for this PDU. All cells of this pdu + * will be sent with the clp bit set + * @param numberOfCells unsigned int [in] - number of cells in the PDU. + * + * @return @li IX_SUCCESS successful call to @a ixAtmdAccTxVcPduSubmit() + * The pdu pointed by the mbufPtr parameter will be + * transmitted + * @return @li IX_ATMDACC_BUSY unable to process this request because + * internal resources are all used. The caller is responsible + * for retrying this request later. + * @return @li IX_FAIL unable to process this request because of error + * in the parameters (wrong connId supplied, + * or wrong mbuf pointer supplied), the total length of all buffers + * in the chain should be a multiple of the cell size + * ( 48/52 depending on the service type ), + * or unspecified error during processing + * + * @note - This function in not re-entrant for the same VC (e.g. : two + * thread cannot send PDUs for the same VC). But two threads can + * safely call this function with a different connection Id + * + * @note - In unscheduled mode, this function is not re-entrant on a per + * port basis. The size of pdus is limited to 8Kb. + * + * @note - 0-length mbufs should be removed from the chain before submission. + * The total length of the pdu (sdu + padding +trailer) has to be + * updated in the header of the first mbuf of a chain of mbufs. + * + * @note - Aal5 trailer information (UUI, CPI, SDU length) has to be supplied + * before submission. + * + * @note - The payload memory cache should be flushed, if needed, prior to + * transmission. Mbuf headers are flushed by IxAtmdAcc + * + * @note - This function does not use system resources and can be used + * inside an interrupt context + */ +PUBLIC IX_STATUS ixAtmdAccTxVcPduSubmit (IxAtmConnId connId, + IX_OSAL_MBUF * mbufPtr, + IxAtmdAccClpStatus clp, + unsigned int numberOfCells); + +/** + * + * @ingroup IxAtmdAccAPI + * + * @fn ixAtmdAccTxVcTryDisconnect (IxAtmConnId connId) + * + * @brief Disconnect from a Aal Pdu transmit service for a particular + * port/vpi/vci. + * + * This function deregisters the VC and guarantees that all resources + * associated with this VC are free. After its execution, the connection + * Id is not available. + * + * This function will fail until such time as all resources allocated to + * the VC connection have been freed. The user is responsible to delay + * and call again this function many times until a success status is + * returned. + * + * After its execution, the connection Id is not available. + * + * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call to + * @a ixAtmdAccTxVcConnect() + * + * @return @li IX_SUCCESS successful call to @a ixAtmdAccTxVcTryDisconnect() + * @return @li IX_ATMDACC_RESOURCES_STILL_ALLOCATED not all resources + * associated with the connection have been freed. This condition will + * disappear after Tx and TxDone is complete for this channel. + * @return @li IX_FAIL unable to process this request because of errors + * in the parameters (wrong connId supplied) + * + * @note - This function needs internal locks and should not be called + * from an interrupt context + * + * @note - If the @a IX_ATMDACC_RESOURCES_STILL_ALLOCATED error does not + * clear after a while, this may be linked to a previous problem + * of cell overscheduling. Diabling the port and retry a disconnect + * will free the resources associated with this channel. + * + * @sa ixAtmdAccPortTxProcess + * + */ +PUBLIC IX_STATUS ixAtmdAccTxVcTryDisconnect (IxAtmConnId connId); + +#endif /* IXATMDACC_H */ + +/** + * @} defgroup IxAtmdAccAPI + */ + + diff --git a/arch/arm/cpu/ixp/npe/include/IxAtmdAccCtrl.h b/arch/arm/cpu/ixp/npe/include/IxAtmdAccCtrl.h new file mode 100644 index 0000000000..e2230493f2 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/IxAtmdAccCtrl.h @@ -0,0 +1,1958 @@ + +/** + * @file IxAtmdAccCtrl.h + * + * @date 20-Mar-2002 + * + * @brief IxAtmdAcc Public API + * + * This file contains the public API of IxAtmdAcc, related to the + * control functions of the component. + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +/* ------------------------------------------------------ + Doxygen group definitions + ------------------------------------------------------ */ + +/** + * + * @defgroup IxAtmdAccCtrlAPI IXP400 ATM Driver Access (IxAtmdAcc) Control API + * + * @brief The public API for the IXP400 Atm Driver Control component + * + * IxAtmdAcc is the low level interface by which AAL PDU get transmitted + * to,and received from the Utopia bus + * + * This part is related to the Control configuration + * + * @{ + */ + +#ifndef IXATMDACCCTRL_H +#define IXATMDACCCTRL_H + +#include "IxAtmdAcc.h" + +/* ------------------------------------------------------ + AtmdAccCtrl Data Types definition + ------------------------------------------------------ */ + +/** +* +* @ingroup IxAtmdAccCtrlAPI +* +* @def IX_ATMDACC_PORT_DISABLE_IN_PROGRESS +* +* @brief Port enable return code +* +* This constant is used to tell IxAtmDAcc user that the port disable +* functions are not complete. The user can call ixAtmdAccPortDisableComplete() +* to find out when the disable has finished. The port enable can then proceed. +* +*/ +#define IX_ATMDACC_PORT_DISABLE_IN_PROGRESS 5 + +/** +* +* @ingroup IxAtmdAccCtrlAPI +* +* @def IX_ATMDACC_ALLPDUS +* +* @brief All PDUs +* +* This constant is used to tell IxAtmDAcc to process all PDUs from +* the RX queue or the TX Done +* +* @sa IxAtmdAccRxDispatcher +* @sa IxAtmdAccTxDoneDispatcher +* +*/ +#define IX_ATMDACC_ALLPDUS 0xffffffff + +/* ------------------------------------------------------ + Part of the IxAtmdAcc interface related to RX traffic + ------------------------------------------------------ */ + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @brief Callback prototype for notification of available PDUs for + * an Rx Q. + * + * This a protoype for a function which is called when there is at + * least one Pdu available for processing on a particular Rx Q. + * + * This function should call @a ixAtmdAccRxDispatch() with + * the aprropriate number of parameters to read and process the Rx Q. + * + * @sa ixAtmdAccRxDispatch + * @sa ixAtmdAccRxVcConnect + * @sa ixAtmdAccRxDispatcherRegister + * + * @param rxQueueId @ref IxAtmRxQueueId [in] indicates which RX queue to has Pdus to process. + * @param numberOfPdusToProcess unsigned int [in] indicates the minimum number of + * PDUs available to process all PDUs from the queue. + * @param reservedPtr unsigned int* [out] pointer to a int location which can + * be written to, but does not retain written values. This is + * provided to make this prototype compatible + * with @a ixAtmdAccRxDispatch() + * + * @return @li int - ignored. + * + */ +typedef IX_STATUS (*IxAtmdAccRxDispatcher) (IxAtmRxQueueId rxQueueId, + unsigned int numberOfPdusToProcess, + unsigned int *reservedPtr); + +/* ------------------------------------------------------ + Part of the IxAtmdAcc interface related to TX traffic + ------------------------------------------------------ */ + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @brief Callback prototype for transmitted mbuf when threshold level is + * crossed. + * + * IxAtmdAccTxDoneDispatcher is the prototype of the user function + * which get called when pdus are completely transmitted. This function + * is likely to call the @a ixAtmdAccTxDoneDispatch() function. + * + * This function is called when the number of available pdus for + * reception is crossing the threshold level as defined + * in @a ixAtmdAccTxDoneDispatcherRegister() + * + * This function is called inside an Qmgr dispatch context. No system + * resource or interrupt-unsafe feature should be used inside this + * callback. + * + * Transmitted buffers recycling implementation is a sytem-wide mechanism + * and needs to be set before any traffic is started. If this threshold + * mechanism is not used, the user is responsible for polling the + * transmitted buffers with @a ixAtmdAccTxDoneDispatch() + * and @a ixAtmdAccTxDoneLevelQuery() functions. + * + * @sa ixAtmdAccTxDoneDispatcherRegister + * @sa ixAtmdAccTxDoneDispatch + * @sa ixAtmdAccTxDoneLevelQuery + * + * @param numberOfPdusToProcess unsigned int [in] - The current number of pdus currently + * available for recycling + * @param *reservedPtr unsigned int [out] - pointer to a int location which can be + * written to but does not retain written values. This is provided + * to make this prototype compatible + * with @a ixAtmdAccTxDoneDispatch() + * + * @return @li IX_SUCCESS This is provided to make + * this prototype compatible with @a ixAtmdAccTxDoneDispatch() + * @return @li IX_FAIL invalid parameters or some unspecified internal + * error occured. This is provided to make + * this prototype compatible with @a ixAtmdAccTxDoneDispatch() + * + */ +typedef IX_STATUS (*IxAtmdAccTxDoneDispatcher) (unsigned int numberOfPdusToProcess, + unsigned int *reservedPtr); + +/** +* +* @ingroup IxAtmdAccCtrlAPI +* +* @brief Notification that the threshold number of scheduled cells +* remains in a port's transmit Q. +* +* The is the prototype for of the user notification function which +* gets called on a per-port basis, when the number of remaining +* scheduled cells to be transmitted decreases to the threshold level. +* The number of cells passed as a parameter can be used for scheduling +* purposes as the maximum number of cells that can be passed in a +* schedule table to the @a ixAtmdAccPortTxProcess() function. +* +* @sa ixAtmdAccPortTxCallbackRegister +* @sa ixAtmdAccPortTxProcess +* @sa ixAtmdAccPortTxFreeEntriesQuery +* +* @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] +* @param numberOfAvailableCells unsigned int [in] - number of available +* cell entries.for the port +* +* @note - This functions shall not use system resources when used +* inside an interrupt context. +* +*/ +typedef void (*IxAtmdAccPortTxLowCallback) (IxAtmLogicalPort port, + unsigned int numberOfAvailableCells); + +/** +* +* @ingroup IxAtmdAccCtrlAPI +* +* @brief Prototype to submit cells for transmission +* +* IxAtmdAccTxVcDemandUpdateCallback is the prototype of the callback +* function used by AtmD to notify an ATM Scheduler that the user of +* a VC has submitted cells for transmission. +* +* @sa IxAtmdAccTxVcDemandUpdateCallback +* @sa IxAtmdAccTxVcDemandClearCallback +* @sa IxAtmdAccTxSchVcIdGetCallback +* @sa ixAtmdAccPortTxScheduledModeEnable +* +* @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the VC to be updated +* is established +* @param vcId int [in] - Identifies the VC to be updated. This is the value +* returned by the @a IxAtmdAccTxSchVcIdGetCallback() call . +* @param numberOfCells unsigned int [in] - Indicates how many ATM cells should be added +* to the queue for this VC. +* +* @return @li IX_SUCCESS the function is registering the cell demand for +* this VC. +* @return @li IX_FAIL the function cannot register cell for this VC : the +* scheduler maybe overloaded or misconfigured +* +*/ +typedef IX_STATUS (*IxAtmdAccTxVcDemandUpdateCallback) (IxAtmLogicalPort port, + int vcId, + unsigned int numberOfCells); + +/** +* +* @ingroup IxAtmdAccCtrlAPI +* +* @brief prototype to remove all currently queued cells from a +* registered VC +* +* IxAtmdAccTxVcDemandClearCallback is the prototype of the function +* to remove all currently queued cells from a registered VC. The +* pending cell count for the specified VC is reset to zero. After the +* use of this callback, the scheduler shall not schedule more cells +* for this VC. +* +* This callback function is called during a VC disconnection +* @a ixAtmdAccTxVcTryDisconnect() +* +* @sa IxAtmdAccTxVcDemandUpdateCallback +* @sa IxAtmdAccTxVcDemandClearCallback +* @sa IxAtmdAccTxSchVcIdGetCallback +* @sa ixAtmdAccPortTxScheduledModeEnable +* @sa ixAtmdAccTxVcTryDisconnect +* +* @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the VC to be cleared +* is established +* @param vcId int [in] - Identifies the VC to be cleared. This is the value +* returned by the @a IxAtmdAccTxSchVcIdGetCallback() call . +* +* @return none +* +*/ +typedef void (*IxAtmdAccTxVcDemandClearCallback) (IxAtmLogicalPort port, + int vcId); + +/** +* +* @ingroup IxAtmdAccCtrlAPI +* +* @brief prototype to get a scheduler vc id +* +* IxAtmdAccTxSchVcIdGetCallback is the prototype of the function to get +* a scheduler vcId +* +* @sa IxAtmdAccTxVcDemandUpdateCallback +* @sa IxAtmdAccTxVcDemandClearCallback +* @sa IxAtmdAccTxSchVcIdGetCallback +* @sa ixAtmdAccPortTxScheduledModeEnable +* +* @param port @ref IxAtmLogicalPort [in] - Specifies the ATM logical port on which the VC is +* established +* @param vpi unsigned int [in] - For AAL0/AAL5 specifies the ATM vpi on which the +* VC is established. +* For OAM specifies the dedicated "OAM Tx channel" VPI. +* @param vci unsigned int [in] - For AAL0/AAL5 specifies the ATM vci on which the +* VC is established. +* For OAM specifies the dedicated "OAM Tx channel" VCI. +* @param connId @ref IxAtmConnId [in] - specifies the IxAtmdAcc connection Id already +* associated with this VC +* @param vcId int* [out] - pointer to a vcId +* +* @return @li IX_SUCCESS the function is returning a Scheduler vcId for this +* VC +* @return @li IX_FAIL the function cannot process scheduling for this VC. +* the contents of vcId is unspecified +* +*/ +typedef IX_STATUS (*IxAtmdAccTxSchVcIdGetCallback) (IxAtmLogicalPort port, + unsigned int vpi, + unsigned int vci, + IxAtmConnId connId, + int *vcId); + +/* ------------------------------------------------------ + Part of the IxAtmdAcc interface related to RX traffic + ------------------------------------------------------ */ + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @fn ixAtmdAccRxDispatcherRegister ( + IxAtmRxQueueId queueId, + IxAtmdAccRxDispatcher callback) + * + * @brief Register a notification callback to be invoked when there is + * at least one entry on a particular Rx queue. + * + * This function registers a callback to be invoked when there is at + * least one entry in a particular queue. The registered callback is + * called every time when the hardware adds one or more pdus to the + * specified Rx queue. + * + * This function cannot be used when a Rx Vc using this queue is + * already existing. + * + * @note -The callback function can be the API function + * @a ixAtmdAccRxDispatch() : every time the threhold level + * of the queue is reached, the ixAtmdAccRxDispatch() is + * invoked to remove all entries from the queue. + * + * @sa ixAtmdAccRxDispatch + * @sa IxAtmdAccRxDispatcher + * + * @param queueId @ref IxAtmRxQueueId [in] RX queue identification + * @param callback @ref IxAtmdAccRxDispatcher [in] function triggering the delivery of incoming + * traffic. This parameter cannot be a null pointer. + * + * @return @li IX_SUCCESS Successful call to @a ixAtmdAccRxDispatcherRegister() + * @return @li IX_FAIL error in the parameters, or there is an + * already active RX VC for this queue or some unspecified + * internal error occurred. + * + */ +PUBLIC IX_STATUS ixAtmdAccRxDispatcherRegister ( + IxAtmRxQueueId queueId, + IxAtmdAccRxDispatcher callback); + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @fn ixAtmdAccRxDispatch (IxAtmRxQueueId rxQueueId, + unsigned int numberOfPdusToProcess, + unsigned int *numberOfPdusProcessedPtr) + * + * + * @brief Control function which executes Rx processing for a particular + * Rx stream. + * + * The @a IxAtmdAccRxDispatch() function is used to process received Pdus + * available from one of the two incoming RX streams. When this function + * is invoked, the incoming traffic (up to the number of PDUs passed as + * a parameter) will be transferred to the IxAtmdAcc users through the + * callback @a IxAtmdAccRxVcRxCallback(), as registered during the + * @a ixAtmdAccRxVcConnect() call. + * + * The user receive callbacks will be executed in the context of this + * function. + * + * Failing to use this function on a regular basis when there is traffic + * will block incoming traffic and can result in Pdus being dropped by + * the hardware. + * + * This should be used to control when received pdus are handed off from + * the hardware to Aal users from a particluar stream. The function can + * be used from a timer context, or can be registered as a callback in + * response to an rx stream threshold event, or can be used inside an + * active polling mechanism which is under user control. + * + * @note - The signature of this function is directly compatible with the + * callback prototype which can be register with @a ixAtmdAccRxDispatcherRegister(). + * + * @sa ixAtmdAccRxDispatcherRegister + * @sa IxAtmdAccRxVcRxCallback + * @sa ixAtmdAccRxVcFreeEntriesQuery + * + * @param rxQueueId @ref IxAtmRxQueueId [in] - indicates which RX queue to process. + * @param numberOfPdusToProcess unsigned int [in] - indicates the maxiumum number of PDU to + * remove from the RX queue. A value of IX_ATMDACC_ALLPDUS indicates + * to process all PDUs from the queue. This includes at least the PDUs + * in the queue when the fuction is invoked. Because of real-time + * constraints, there is no guarantee thatthe queue will be empty + * when the function exits. If this parameter is greater than the + * number of entries of the queues, the function will succeed + * and the parameter numberOfPdusProcessedPtr will reflect the exact + * number of PDUs processed. + * @param *numberOfPdusProcessedPtr unsigned int [out] - indicates the actual number of PDU + * processed during this call. This parameter cannot be a null + * pointer. + * + * @return @li IX_SUCCESS the number of PDUs as indicated in + * numberOfPdusProcessedPtr are removed from the RX queue and the VC callback + * are called. + * @return @li IX_FAIL invalid parameters or some unspecified internal + * error occured. + * + */ +PUBLIC IX_STATUS ixAtmdAccRxDispatch (IxAtmRxQueueId rxQueueId, + unsigned int numberOfPdusToProcess, + unsigned int *numberOfPdusProcessedPtr); + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @fn ixAtmdAccRxLevelQuery (IxAtmRxQueueId rxQueueId, + unsigned int *numberOfPdusPtr) + * + * @brief Query the number of entries in a particular RX queue. + * + * This function is used to retrieve the number of pdus received by + * the hardware and ready for distribution to users. + * + * @param rxQueueId @ref IxAtmRxQueueId [in] - indicates which of two RX queues to query. + * @param numberOfPdusPtr unsigned int* [out] - Pointer to store the number of available + * PDUs in the RX queue. This parameter cannot be a null pointer. + * + * @return @li IX_SUCCESS the value in numberOfPdusPtr specifies the + * number of incoming pdus waiting in this queue + * @return @li IX_FAIL an error occurs during processing. + * The value in numberOfPdusPtr is unspecified. + * + * @note - This function is reentrant, doesn't use system resources + * and can be used from an interrupt context. + * + */ +PUBLIC IX_STATUS ixAtmdAccRxLevelQuery (IxAtmRxQueueId rxQueueId, + unsigned int *numberOfPdusPtr); + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @fn ixAtmdAccRxQueueSizeQuery (IxAtmRxQueueId rxQueueId, + unsigned int *numberOfPdusPtr) + * + * @brief Query the size of a particular RX queue. + * + * This function is used to retrieve the number of pdus the system is + * able to queue when reception is complete. + * + * @param rxQueueId @ref IxAtmRxQueueId [in] - indicates which of two RX queues to query. + * @param numberOfPdusPtr unsigned int* [out] - Pointer to store the number of pdus + * the system is able to queue in the RX queue. This parameter + * cannot be a null pointer. + * + * @return @li IX_SUCCESS the value in numberOfPdusPtr specifies the + * number of pdus the system is able to queue. + * @return @li IX_FAIL an error occurs during processing. + * The value in numberOfPdusPtr is unspecified. + * + * @note - This function is reentrant, doesn't use system resources + * and can be used from an interrupt context. + * + */ +PUBLIC IX_STATUS ixAtmdAccRxQueueSizeQuery (IxAtmRxQueueId rxQueueId, + unsigned int *numberOfPdusPtr); + +/* ------------------------------------------------------ + Part of the IxAtmdAcc interface related to TX traffic + ------------------------------------------------------ */ + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @fn ixAtmdAccPortTxFreeEntriesQuery (IxAtmLogicalPort port, + unsigned int *numberOfCellsPtr) + * + * @brief Get the number of available cells the system can accept for + * transmission. + * + * The function is used to retrieve the number of cells that can be + * queued for transmission to the hardware. + * + * This number is based on the worst schedule table where one cell + * is stored in one schedule table entry, depending on the pdus size + * and mbuf size and fragmentation. + * + * This function doesn't use system resources and can be used from a + * timer context, or can be associated with a threshold event, or can + * be used inside an active polling mechanism + * + * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] + * @param numberOfCellsPtr unsigned int* [out] - number of available cells. + * This parameter cannot be a null pointer. + * + * @sa ixAtmdAccPortTxProcess + * + * @return @li IX_SUCCESS numberOfCellsPtr contains the number of cells that can be scheduled + * for this port. + * @return @li IX_FAIL error in the parameters, or some processing error + * occured. + * + */ +PUBLIC IX_STATUS ixAtmdAccPortTxFreeEntriesQuery (IxAtmLogicalPort port, + unsigned int *numberOfCellsPtr); + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @fn ixAtmdAccPortTxCallbackRegister (IxAtmLogicalPort port, + unsigned int numberOfCells, + IxAtmdAccPortTxLowCallback callback) + * + * @brief Configure the Tx port threshold value and register a callback to handle + * threshold notifications. + * + * This function sets the threshold in cells + * + * @sa ixAtmdAccPortTxCallbackRegister + * @sa ixAtmdAccPortTxProcess + * @sa ixAtmdAccPortTxFreeEntriesQuery + * + * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] + * @param numberOfCells unsigned int [in] - threshold value which triggers the callback + * invocation, This number has to be one of the + * values 0,1,2,4,8,16,32 .... + * The maximum value cannot be more than half of the txVc queue + * size (which can be retrieved using @a ixAtmdAccPortTxFreeEntriesQuery() + * before any Tx traffic is sent for this port) + * @param callback @ref IxAtmdAccPortTxLowCallback [in] - callback function to invoke when the threshold + * level is reached. + * This parameter cannot be a null pointer. + * + * @return @li IX_SUCCESS Successful call to @a ixAtmdAccPortTxCallbackRegister() + * @return @li IX_FAIL error in the parameters, Tx channel already set for this port + * threshold level is not correct or within the range regarding the + * queue size:or unspecified error during processing: + * + * @note - This callback function get called when the threshold level drops from + * (numberOfCells+1) cells to (numberOfCells) cells + * + * @note - This function should be called during system initialisation, + * outside an interrupt context + * + */ +PUBLIC IX_STATUS ixAtmdAccPortTxCallbackRegister (IxAtmLogicalPort port, + unsigned int numberOfCells, + IxAtmdAccPortTxLowCallback callback); + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @fn ixAtmdAccPortTxScheduledModeEnable (IxAtmLogicalPort port, + IxAtmdAccTxVcDemandUpdateCallback vcDemandUpdateCallback, + IxAtmdAccTxVcDemandClearCallback vcDemandClearCallback, + IxAtmdAccTxSchVcIdGetCallback vcIdGetCallback) + * + * @brief Put the port into Scheduled Mode + * + * This function puts the specified port into scheduled mode of + * transmission which means an external s/w entity controls the + * transmission of cells on this port. This faciltates traffic shaping on + * the port. + * + * Any buffers submitted on a VC for this port will be queued in IxAtmdAcc. + * The transmission of these buffers to and by the hardware will be driven + * by a transmit schedule submitted regulary in calls to + * @a ixAtmdAccPortTxProcess() by traffic shaping entity. + * + * The transmit schedule is expected to be dynamic in nature based on + * the demand in cells for each VC on the port. Hence the callback + * parameters provided to this function allow IxAtmdAcc to inform the + * shaping entity of demand changes for each VC on the port. + * + * By default a port is in Unscheduled Mode so if this function is not + * called, transmission of data is done without sheduling rules, on a + * first-come, first-out basis. + * + * Once a port is put in scheduled mode it cannot be reverted to + * un-scheduled mode. Note that unscheduled mode is not supported + * in ixp425 1.0 + * + * @note - This function should be called before any VCs have be + * connected on a port. Otherwise this function call will return failure. + * + * @note - This function uses internal locks and should not be called from + * an interrupt context + * + * @sa IxAtmdAccTxVcDemandUpdateCallback + * @sa IxAtmdAccTxVcDemandClearCallback + * @sa IxAtmdAccTxSchVcIdGetCallback + * @sa ixAtmdAccPortTxProcess + * + * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] + * @param vcDemandUpdateCallback @ref IxAtmdAccTxVcDemandUpdateCallback [in] - callback function used to update + * the number of outstanding cells for transmission. This parameter + * cannot be a null pointer. + * @param vcDemandClearCallback @ref IxAtmdAccTxVcDemandClearCallback [in] - callback function used to remove all + * clear the number of outstanding cells for a VC. This parameter + * cannot be a null pointer. + * @param vcIdGetCallback @ref IxAtmdAccTxSchVcIdGetCallback [in] - callback function used to exchange vc + * Identifiers between IxAtmdAcc and the entity supplying the + * transmit schedule. This parameter cannot be a null pointer. + * + * @return @li IX_SUCCESS scheduler registration is complete and the port + * is now in scheduled mode. + * @return @li IX_FAIL failed (wrong parameters, or traffic is already + * enabled on this port, possibly without ATM shaping) + * + */ +PUBLIC IX_STATUS ixAtmdAccPortTxScheduledModeEnable (IxAtmLogicalPort port, + IxAtmdAccTxVcDemandUpdateCallback vcDemandUpdateCallback, + IxAtmdAccTxVcDemandClearCallback vcDemandClearCallback, + IxAtmdAccTxSchVcIdGetCallback vcIdGetCallback); + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @fn ixAtmdAccPortTxProcess (IxAtmLogicalPort port, + IxAtmScheduleTable* scheduleTablePtr) + * + * @brief Transmit queue cells to the H/W based on the supplied schedule + * table. + * + * This function @a ixAtmdAccPortTxProcess() process the schedule + * table provided as a parameter to the function. As a result cells are + * sent to the underlaying hardware for transmission. + * + * The schedule table is executed in its entirety or not at all. So the + * onus is on the caller not to submit a table containing more cells than + * can be transmitted at that point. The maximum numbers that can be + * transmitted is guaranteed to be the number of cells as returned by the + * function @a ixAtmdAccPortTxFreeEntriesQuery(). + * + * When the scheduler is invoked on a threshold level, IxAtmdAcc gives the + * minimum number of cells (to ensure the callback will fire again later) + * and the maximum number of cells that @a ixAtmdAccPortTxProcess() + * will be able to process (assuming the ATM scheduler is able + * to produce the worst-case schedule table, i.e. one entry per cell). + * + * When invoked ouside a threshold level, the overall number of cells of + * the schedule table should be less than the number of cells returned + * by the @a ixAtmdAccPortTxFreeEntriesQuery() function. + * + * After invoking the @a ixAtmdAccPortTxProcess() function, it is the + * user choice to query again the queue level with the function + * @a ixAtmdAccPortTxFreeEntriesQuery() and, depending on a new cell + * number, submit an other schedule table. + * + * IxAtmdAcc will check that the number of cells in the schedule table + * is compatible with the current transmit level. If the + * + * Obsolete or invalid connection Id will be silently discarded. + * + * This function is not reentrant for the same port. + * + * This functions doesn't use system resources and can be used inside an + * interrupt context. + * + * This function is used as a response to the hardware requesting more + * cells to transmit. + * + * @sa ixAtmdAccPortTxScheduledModeEnable + * @sa ixAtmdAccPortTxFreeEntriesQuery + * @sa ixAtmdAccPortTxCallbackRegister + * @sa ixAtmdAccPortEnable + * + * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] + * @param scheduleTablePtr @ref IxAtmScheduleTable* [in] - pointer to a scheduler update table. The + * content of this table is not modified by this function. This + * parameter cannot be a null pointer. + * + * @return @li IX_SUCCESS the schedule table process is complete + * and cells are transmitted to the hardware + * @return @li IX_ATMDACC_WARNING : Traffic will be dropped: the schedule table exceed + * the hardware capacity If this error is ignored, further traffic + * and schedule will work correctly. + * Overscheduling does not occur when the schedule table does + * not contain more entries that the number of free entries returned + * by @a ixAtmdAccPortTxFreeEntriesQuery(). + * However, Disconnect attempts just after this error will fail permanently + * with the error code @a IX_ATMDACC_RESOURCES_STILL_ALLOCATED, and it is + * necessary to disable the port to make @a ixAtmdAccTxVcTryDisconnect() + * successful. + * @return @li IX_FAIL a wrong parameter is supplied, or the format of + * the schedule table is invalid, or the port is not Enabled, or + * an internal severe error occured. No cells is transmitted to the hardware + * + * @note - If the failure is linked to an overschedule of data cells + * the result is an inconsistency in the output traffic (one or many + * cells may be missing and the traffic contract is not respected). + * + */ +PUBLIC IX_STATUS ixAtmdAccPortTxProcess (IxAtmLogicalPort port, + IxAtmScheduleTable* scheduleTablePtr); + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @fn ixAtmdAccTxDoneDispatch (unsigned int numberOfPdusToProcess, + unsigned int *numberOfPdusProcessedPtr) + * + * @brief Process a number of pending transmit done pdus from the hardware. + * + * As a by-product of Atm transmit operation buffers which transmission + * is complete need to be recycled to users. This function is invoked + * to service the oustanding list of transmitted buffers and pass them + * to VC users. + * + * Users are handed back pdus by invoking the free callback registered + * during the @a ixAtmdAccTxVcConnect() call. + * + * There is a single Tx done stream servicing all active Atm Tx ports + * which can contain a maximum of 64 entries. If this stream fills port + * transmission will stop so this function must be call sufficently + * frequently to ensure no disruption to the transmit operation. + * + * This function can be used from a timer context, or can be associated + * with a TxDone level threshold event (see @a ixAtmdAccTxDoneDispatcherRegister() ), + * or can be used inside an active polling mechanism under user control. + * + * For ease of use the signature of this function is compatible with the + * TxDone threshold event callback prototype. + * + * This functions can be used inside an interrupt context. + * + * @sa ixAtmdAccTxDoneDispatcherRegister + * @sa IxAtmdAccTxVcBufferReturnCallback + * @sa ixAtmdAccTxDoneLevelQuery + * + * @param numberOfPdusToProcess unsigned int [in] - maxiumum number of pdus to remove + * from the TX Done queue + * @param *numberOfPdusProcessedPtr unsigned int [out] - number of pdus removed from + * the TX Done queue. This parameter cannot be a null pointer. + * + * @return @li IX_SUCCESS the number of pdus as indicated in + * numberOfPdusToProcess are removed from the TX Done hardware + * and passed to the user through the Tx Done callback registered + * during a call to @a ixAtmdAccTxVcConnect() + * @return @li IX_FAIL invalid parameters or numberOfPdusProcessedPtr is + * a null pointer or some unspecified internal error occured. + * + */ +PUBLIC IX_STATUS +ixAtmdAccTxDoneDispatch (unsigned int numberOfPdusToProcess, + unsigned int *numberOfPdusProcessedPtr); + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @fn ixAtmdAccTxDoneLevelQuery (unsigned int *numberOfPdusPtr) + * + * @brief Query the current number of transmit pdus ready for + * recycling. + * + * This function is used to get the number of transmitted pdus which + * the hardware is ready to hand back to user. + * + * This function can be used from a timer context, or can be associated + * with a threshold event, on can be used inside an active polling + * mechanism + * + * @sa ixAtmdAccTxDoneDispatch + * + * @param *numberOfPdusPtr unsigned int [out] - Pointer to the number of pdus transmitted + * at the time of this function call, and ready for recycling + * This parameter cannot be a null pointer. + * + * @return @li IX_SUCCESS numberOfPdusPtr contains the number of pdus + * ready for recycling at the time of this function call + * + * @return @li IX_FAIL wrong parameter (null pointer as parameter).or + * unspecified rocessing error occurs..The value in numberOfPdusPtr + * is unspecified. + * + */ +PUBLIC IX_STATUS +ixAtmdAccTxDoneLevelQuery (unsigned int *numberOfPdusPtr); + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @fn ixAtmdAccTxDoneQueueSizeQuery (unsigned int *numberOfPdusPtr) + * + * @brief Query the TxDone queue size. + * + * This function is used to get the number of pdus which + * the hardware is able to store after transmission is complete + * + * The returned value can be used to set a threshold and enable + * a callback to be notified when the number of pdus is going over + * the threshold. + * + * @sa ixAtmdAccTxDoneDispatcherRegister + * + * @param *numberOfPdusPtr unsigned int [out] - Pointer to the number of pdus the system + * is able to queue after transmission + * + * @return @li IX_SUCCESS numberOfPdusPtr contains the the number of + * pdus the system is able to queue after transmission + * @return @li IX_FAIL wrong parameter (null pointer as parameter).or + * unspecified rocessing error occurs..The value in numberOfPdusPtr + * is unspecified. + * + * @note - This function is reentrant, doesn't use system resources + * and can be used from an interrupt context. + */ +PUBLIC IX_STATUS +ixAtmdAccTxDoneQueueSizeQuery (unsigned int *numberOfPdusPtr); + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @fn ixAtmdAccTxDoneDispatcherRegister (unsigned int numberOfPdus, + IxAtmdAccTxDoneDispatcher notificationCallback) + * + * @brief Configure the Tx Done stream threshold value and register a + * callback to handle threshold notifications. + * + * This function sets the threshold level in term of number of pdus at + * which the supplied notification function should be called. + * + * The higher the threshold value is, the less events will be necessary + * to process transmitted buffers. + * + * Transmitted buffers recycling implementation is a sytem-wide mechanism + * and needs to be set prior any traffic is started. If this threshold + * mechanism is not used, the user is responsible for polling the + * transmitted buffers thanks to @a ixAtmdAccTxDoneDispatch() and + * @a ixAtmdAccTxDoneLevelQuery() functions. + * + * This function should be called during system initialisation outside + * an interrupt context + * + * @sa ixAtmdAccTxDoneDispatcherRegister + * @sa ixAtmdAccTxDoneDispatch + * @sa ixAtmdAccTxDoneLevelQuery + * + * @param numberOfPdus unsigned int [in] - The number of TxDone pdus which triggers the + * callback invocation This number has to be a power of 2, one of the + * values 0,1,2,4,8,16,32 ... + * The maximum value cannot be more than half of the txDone queue + * size (which can be retrieved using @a ixAtmdAccTxDoneQueueSizeQuery()) + * @param notificationCallback @ref IxAtmdAccTxDoneDispatcher [in] - The function to invoke. (This + * parameter can be @a ixAtmdAccTxDoneDispatch()).This + * parameter ust not be a null pointer. + * + * @return @li IX_SUCCESS Successful call to ixAtmdAccTxDoneDispatcherRegister + * @return @li IX_FAIL error in the parameters: + * + * @note - The notificationCallback will be called exactly when the threshold level + * will increase from (numberOfPdus) to (numberOfPdus+1) + * + * @note - If there is no Tx traffic, there is no guarantee that TxDone Pdus will + * be released to the user (when txDone level is permanently under the threshold + * level. One of the preffered way to return resources to the user is to use + * a mix of txDone notifications, used together with a slow + * rate timer and an exclusion mechanism protecting from re-entrancy + * + * @note - The TxDone threshold will only hand back buffers when the threshold level is + * crossed. Setting this threshold to a great number reduce the interrupt rate + * and the cpu load, but also increase the number of outstanding mbufs and has + * a system wide impact when these mbufs are needed by other components. + * + */ +PUBLIC IX_STATUS ixAtmdAccTxDoneDispatcherRegister (unsigned int numberOfPdus, + IxAtmdAccTxDoneDispatcher notificationCallback); + +/* ------------------------------------------------------ + Part of the IxAtmdAcc interface related to Utopia config + ------------------------------------------------------ */ + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @defgroup IxAtmdAccUtopiaCtrlAPI IXP400 ATM Driver Access (IxAtmdAcc) Utopia Control API + * + * @brief The public API for the IXP400 Atm Driver Control component + * + * IxAtmdAcc is the low level interface by which AAL PDU get + * transmitted to,and received from the Utopia bus + * + * This part is related to the UTOPIA configuration. + * + * @{ + */ + +/** + * + * @brief Utopia configuration + * + * This structure is used to set the Utopia parameters + * @li contains the values of Utopia registers, to be set during initialisation + * @li contains debug commands for NPE, to be used during development steps + * + * @note - the exact description of all parameters is done in the Utopia reference + * documents. + * + */ +typedef struct +{ + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtTxConfig_ + * @brief Utopia Tx Config Register + */ + struct UtTxConfig_ + { + + unsigned int reserved_1:1; /**< [31] These bits are always 0.*/ + unsigned int txInterface:1; /**< [30] Utopia Transmit Interface. The following encoding + * is used to set the Utopia Transmit interface as ATM master + * or PHY slave: + * @li 1 - PHY + * @li 0 - ATM + */ + unsigned int txMode:1; /**< [29] Utopia Transmit Mode. The following encoding is used + * to set the Utopia Transmit mode to SPHY or MPHY: + * @li 1 - SPHY + * @li 0 - MPHY + */ + unsigned int txOctet:1; /**< [28] Utopia Transmit cell transfer protocol. Used to set + * the Utopia cell transfer protocol to Octet-level handshaking. + * Note this is only applicable in SPHY mode. + * @li 1 - Octet-handshaking enabled + * @li 0 - Cell-handshaking enabled + */ + unsigned int txParity:1; /**< [27] Utopia Transmit parity enabled when set. TxEvenParity + * defines the parity format odd/even. + * @li 1 - Enable Parity generation. + * @li 0 - ut_op_prty held low. + */ + unsigned int txEvenParity:1; /**< [26] Utopia Transmit Parity Mode + * @li 1 - Even Parity Generated. + * @li 0 - Odd Parity Generated. + */ + unsigned int txHEC:1; /**< [25] Header Error Check Insertion Mode. Specifies if the transmit + * cell header check byte is calculated and inserted when set. + * @li 1 - Generate HEC. + * @li 0 - Disable HEC generation. + */ + unsigned int txCOSET:1; /**< [24] If enabled the HEC is Exclusive-ORÆed with the value 0x55 before + * being presented on the Utopia bus. + * @li 1 - Enable HEC ExOR with value 0x55 + * @li 0 - Use generated HEC value. + */ + + unsigned int reserved_2:1; /**< [23] These bits are always 0 + */ + unsigned int txCellSize:7; /**< [22:16] Transmit expected cell size. Configures the cell size + * for the transmit module: Values between 52-64 are valid. + */ + unsigned int reserved_3:3; /**< [15:13] These bits are always 0 */ + unsigned int txAddrRange:5; /**< [12:8] When configured as an ATM master in MPHY mode this + * register specifies the upper limit of the PHY polling logical + * range. The number of active PHYs are TxAddrRange + 1. + */ + unsigned int reserved_4:3; /**< [7:5] These bits are always 0 */ + unsigned int txPHYAddr:5; /**< [4:0] When configured as a slave in an MPHY system this register + * specifies the physical address of the PHY. + */ + } + + utTxConfig; /**< Tx config Utopia register */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtTxStatsConfig_ + * @brief Utopia Tx stats Register + */ + struct UtTxStatsConfig_ + { + + unsigned int vpi:12; /**< [31:20] ATM VPI [11:0] OR GFC [3:0] and VPI [7:0] + @li Note: if VCStatsTxGFC is set to 0 the GFC field is ignored in test. */ + + unsigned int vci:16; /**< [19:4] ATM VCI [15:0] or PHY Address[4] */ + + unsigned int pti:3; /**< [3:1] ATM PTI [2:0] or PHY Address[3:1] + @li Note: if VCStatsTxPTI is set to 0 the PTI field is ignored in test. + @li Note: if VCStatsTxEnb is set to 0 only the transmit PHY port + address as defined by this register is used for ATM statistics [4:0]. */ + + unsigned int clp:1; /**< [0] ATM CLP or PHY Address [0] + @li Note: if VCStatsTxCLP is set to 0 the CLP field is ignored in test. + @li Note: if VCStatsTxEnb is set to 0 only the transmit PHY port + address as defined by this register is used for ATM statistics [4:0]. */ + } + + utTxStatsConfig; /**< Tx stats config Utopia register */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtTxDefineIdle_ + * @brief Utopia Tx idle cells Register + */ + struct UtTxDefineIdle_ + { + + unsigned int vpi:12; /**< [31:20] ATM VPI [11:0] OR GFC [3:0] and VPI [7:0] + @li Note: if VCIdleTxGFC is set to 0 the GFC field is ignored in test. */ + + unsigned int vci:16; /**< [19:4] ATM VCI [15:0] */ + + unsigned int pti:3; /**< [3:1] ATM PTI PTI [2:0] + @li Note: if VCIdleTxPTI is set to 0 the PTI field is ignored in test.*/ + + unsigned int clp:1; /**< [0] ATM CLP [0] + @li Note: if VCIdleTxCLP is set to 0 the CLP field is ignored in test.*/ + } + + utTxDefineIdle; /**< Tx idle cell config Utopia register */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtTxEnableFields_ + * @brief Utopia Tx ienable fields Register + */ + struct UtTxEnableFields_ + { + + unsigned int defineTxIdleGFC:1; /**< [31] This register is used to include or exclude the GFC + field of the ATM header when testing for Idle cells. + @li 1 - GFC field is valid. + @li 0 - GFC field ignored.*/ + + unsigned int defineTxIdlePTI:1; /**< [30] This register is used to include or exclude the PTI + field of the ATM header when testing for Idle cells. + @li 1 - PTI field is valid + @li 0 - PTI field ignored.*/ + + unsigned int defineTxIdleCLP:1; /**< [29] This register is used to include or + exclude the CLP field of the ATM header when testing for Idle cells. + @li 1 - CLP field is valid. + @li 0 - CLP field ignored. */ + + unsigned int phyStatsTxEnb:1; /**< [28] This register is used to enable or disable ATM + statistics gathering based on the specified PHY address as defined + in TxStatsConfig register. + @li 1 - Enable statistics for specified transmit PHY address. + @li 0 - Disable statistics for specified transmit PHY address. */ + + unsigned int vcStatsTxEnb:1; /**< [27] This register is used to change the ATM + statistics-gathering mode from the specified logical PHY address + to a specific VPI/VCI address. + @li 1 - Enable statistics for specified VPI/VCI address. + @li 0 - Disable statistics for specified VPI/VCI address */ + + unsigned int vcStatsTxGFC:1; /**< [26] This register is used to include or exclude the GFC + field of the ATM header when ATM VPI/VCI statistics are enabled. + GFC is only available at the UNI and uses the first 4-bits of + the VPI field. + @li 1 - GFC field is valid + @li 0 - GFC field ignored.*/ + + unsigned int vcStatsTxPTI:1; /**< [25] This register is used to include or exclude the PTI + field of the ATM header when ATM VPI/VCI statistics are enabled. + @li 1 - PTI field is valid + @li 0 - PTI field ignored.*/ + + unsigned int vcStatsTxCLP:1; /**< [24] This register is used to include or exclude the CLP + field of the ATM header when ATM VPI/VCI statistics are enabled. + @li 1 - CLP field is valid + @li 0 - CLP field ignored. */ + + unsigned int reserved_1:3; /**< [23-21] These bits are always 0 */ + + unsigned int txPollStsInt:1; /**< [20] Enable the assertion of the ucp_tx_poll_sts condition + where there is a change in polling status. + @li 1 - ucp_tx_poll_sts asserted whenever there is a change in status + @li 0 - ucp_tx_poll_sts asserted if ANY transmit PHY is available + */ + unsigned int txCellOvrInt:1; /**< [19] Enable TxCellCount overflow CBI Transmit Status condition + assertion. + @li 1 - If TxCellCountOvr is set assert the Transmit Status Condition. + @li 0 - No CBI Transmit Status condition assertion */ + + unsigned int txIdleCellOvrInt:1; /**< [18] Enable TxIdleCellCount overflow Transmit Status Condition + @li 1 - If TxIdleCellCountOvr is set assert the Transmit Status Condition + @li 0 - No CBI Transmit Status condition assertion..*/ + + unsigned int enbIdleCellCnt:1; /**< [17] Enable Transmit Idle Cell Count. + @li 1 - Enable count of Idle cells transmitted. + @li 0 - No count is maintained. */ + + unsigned int enbTxCellCnt:1; /**< [16] Enable Transmit Valid Cell Count of non-idle/non-error cells + @li 1 - Enable count of valid cells transmitted- non-idle/non-error + @li 0 - No count is maintained.*/ + + unsigned int reserved_2:16; /**< [15:0] These bits are always 0 */ + } utTxEnableFields; /**< Tx enable Utopia register */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtTxTransTable0_ + * @brief Utopia Tx translation table Register + */ + struct UtTxTransTable0_ + { + + unsigned int phy0:5; /**< [31-27] Tx Mapping value of logical phy 0 */ + + unsigned int phy1:5; /**< [26-22] Tx Mapping value of logical phy 1 */ + + unsigned int phy2:5; /**< [21-17] Tx Mapping value of logical phy 2 */ + + unsigned int reserved_1:1; /**< [16] These bits are always 0.*/ + + unsigned int phy3:5; /**< [15-11] Tx Mapping value of logical phy 3 */ + + unsigned int phy4:5; /**< [10-6] Tx Mapping value of logical phy 4 */ + + unsigned int phy5:5; /**< [5-1] Tx Mapping value of logical phy 5 */ + + unsigned int reserved_2:1; /**< [0] These bits are always 0 */ + } utTxTransTable0; /**< Tx translation table */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtTxTransTable1_ + * @brief Utopia Tx translation table Register + */ + struct UtTxTransTable1_ + { + + unsigned int phy6:5; /**< [31-27] Tx Mapping value of logical phy 6 */ + + unsigned int phy7:5; /**< [26-22] Tx Mapping value of logical phy 7 */ + + unsigned int phy8:5; /**< [21-17] Tx Mapping value of logical phy 8 */ + + unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */ + + unsigned int phy9:5; /**< [15-11] Tx Mapping value of logical phy 3 */ + + unsigned int phy10:5; /**< [10-6] Tx Mapping value of logical phy 4 */ + + unsigned int phy11:5; /**< [5-1] Tx Mapping value of logical phy 5 */ + + unsigned int reserved_2:1; /**< [0] These bits are always 0 */ + } utTxTransTable1; /**< Tx translation table */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtTxTransTable2_ + * @brief Utopia Tx translation table Register + */ + struct UtTxTransTable2_ + { + + unsigned int phy12:5; /**< [31-27] Tx Mapping value of logical phy 6 */ + + unsigned int phy13:5; /**< [26-22] Tx Mapping value of logical phy 7 */ + + unsigned int phy14:5; /**< [21-17] Tx Mapping value of logical phy 8 */ + + unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */ + + unsigned int phy15:5; /**< [15-11] Tx Mapping value of logical phy 3 */ + + unsigned int phy16:5; /**< [10-6] Tx Mapping value of logical phy 4 */ + + unsigned int phy17:5; /**< [5-1] Tx Mapping value of logical phy 5 */ + + unsigned int reserved_2:1; /**< [0] These bits are always 0 */ + } utTxTransTable2; /**< Tx translation table */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtTxTransTable3_ + * @brief Utopia Tx translation table Register + */ + struct UtTxTransTable3_ + { + + unsigned int phy18:5; /**< [31-27] Tx Mapping value of logical phy 6 */ + + unsigned int phy19:5; /**< [26-22] Tx Mapping value of logical phy 7 */ + + unsigned int phy20:5; /**< [21-17] Tx Mapping value of logical phy 8 */ + + unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */ + + unsigned int phy21:5; /**< [15-11] Tx Mapping value of logical phy 3 */ + + unsigned int phy22:5; /**< [10-6] Tx Mapping value of logical phy 4 */ + + unsigned int phy23:5; /**< [5-1] Tx Mapping value of logical phy 5 */ + + unsigned int reserved_2:1; /**< [0] These bits are always 0 */ + } utTxTransTable3; /**< Tx translation table */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtTxTransTable4_ + * @brief Utopia Tx translation table Register + */ + struct UtTxTransTable4_ + { + + unsigned int phy24:5; /**< [31-27] Tx Mapping value of logical phy 6 */ + + unsigned int phy25:5; /**< [26-22] Tx Mapping value of logical phy 7 */ + + unsigned int phy26:5; /**< [21-17] Tx Mapping value of logical phy 8 */ + + unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */ + + unsigned int phy27:5; /**< [15-11] Tx Mapping value of logical phy 3 */ + + unsigned int phy28:5; /**< [10-6] Tx Mapping value of logical phy 4 */ + + unsigned int phy29:5; /**< [5-1] Tx Mapping value of logical phy 5 */ + + unsigned int reserved_2:1; /**< [0] These bits are always 0 */ + } utTxTransTable4; /**< Tx translation table */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtTxTransTable5_ + * @brief Utopia Tx translation table Register + */ + struct UtTxTransTable5_ + { + + unsigned int phy30:5; /**< [31-27] Tx Mapping value of logical phy 6 */ + + unsigned int reserved_1:27; /**< [26-0] These bits are always 0 */ + + } utTxTransTable5; /**< Tx translation table */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtRxConfig_ + * @brief Utopia Rx config Register + */ + struct UtRxConfig_ + { + + unsigned int rxInterface:1; /**< [31] Utopia Receive Interface. The following encoding is used + to set the Utopia Receive interface as ATM master or PHY slave: + @li 1 - PHY + @li 0 - ATM */ + + unsigned int rxMode:1; /**< [30] Utopia Receive Mode. The following encoding is used to set + the Utopia Receive mode to SPHY or MPHY: + @li 1 - SPHY + @li 0 - MPHY */ + + unsigned int rxOctet:1; /**< [29] Utopia Receive cell transfer protocol. Used to set the Utopia + cell transfer protocol to Octet-level handshaking. Note this is only + applicable in SPHY mode. + @li 1 - Octet-handshaking enabled + @li 0 - Cell-handshaking enabled */ + + unsigned int rxParity:1; /**< [28] Utopia Receive Parity Checking enable. + @li 1 - Parity checking enabled + @li 0 - Parity checking disabled */ + + unsigned int rxEvenParity:1;/**< [27] Utopia Receive Parity Mode + @li 1 - Check for Even Parity + @li 0 - Check for Odd Parity.*/ + + unsigned int rxHEC:1; /**< [26] RxHEC Header Error Check Mode. Enables/disables cell header + error checking on the received cell header. + @li 1 - HEC checking enabled + @li 0 - HEC checking disabled */ + + unsigned int rxCOSET:1; /**< [25] If enabled the HEC is Exclusive-ORÆed with the value 0x55 + before being tested with the received HEC. + @li 1 - Enable HEC ExOR with value 0x55. + @li 0 - Use generated HEC value.*/ + + unsigned int rxHECpass:1; /**< [24] Specifies if the incoming cell HEC byte should be transferred + after optional processing to the NPE2 Coprocessor Bus Interface or + if it should be discarded. + @li 1 - HEC maintained 53-byte/UDC cell sent to NPE2. + @li 0 - HEC discarded 52-byte/UDC cell sent to NPE2 coprocessor.*/ + + unsigned int reserved_1:1; /**< [23] These bits are always 0 */ + + unsigned int rxCellSize:7; /**< [22:16] Receive cell size. Configures the receive cell size. + Values between 52-64 are valid */ + + unsigned int rxHashEnbGFC:1; /**< [15] Specifies if the VPI field [11:8]/GFC field should be + included in the Hash data input or if the bits should be padded + with 1Æb0. + @li 1 - VPI [11:8]/GFC field valid and used in Hash residue calculation. + @li 0 - VPI [11:8]/GFC field padded with 1Æb0 */ + + unsigned int rxPreHash:1; /**< [14] Enable Pre-hash value generation. Specifies if the + incoming cell data should be pre-hashed to allow VPI/VCI header look-up + in a hash table. + @li 1 - Pre-hashing enabled + @li 0 - Pre-hashing disabled */ + + unsigned int reserved_2:1; /**< [13] These bits are always 0 */ + + unsigned int rxAddrRange:5; /**< [12:8] In ATM master, MPHY mode, + * this register specifies the upper + * limit of the PHY polling logical range. The number of active PHYs are + * RxAddrRange + 1. + */ + unsigned int reserved_3:3; /**< [7-5] These bits are always 0 .*/ + unsigned int rxPHYAddr:5; /**< [4:0] When configured as a slave in an MPHY system this register + * specifies the physical address of the PHY. + */ + } utRxConfig; /**< Rx config Utopia register */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtRxStatsConfig_ + * @brief Utopia Rx stats config Register + */ + struct UtRxStatsConfig_ + { + + unsigned int vpi:12; /**< [31:20] ATM VPI VPI [11:0] OR GFC [3:0] and VPI [7:0] + @li Note: if VCStatsRxGFC is set to 0 the GFC field is ignored in test. */ + + unsigned int vci:16; /**< [19:4] VCI [15:0] or PHY Address [4] */ + + unsigned int pti:3; /**< [3:1] PTI [2:0] or or PHY Address [3:1] + @li Note: if VCStatsRxPTI is set to 0 the PTI field is ignored in test. + @li Note: if VCStatsRxEnb is set to 0 only the PHY port address is used + for statistics gathering.. */ + + unsigned int clp:1; /**< [0] CLP [0] or PHY Address [0] + @li Note: if VCStatsRxCLP is set to 0 the CLP field is ignored in test. + @li Note: if VCStatsRxEnb is set to 0 only the PHY port address is used + for statistics gathering.. */ + } utRxStatsConfig; /**< Rx stats config Utopia register */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtRxDefineIdle_ + * @brief Utopia Rx idle cells config Register + */ + struct UtRxDefineIdle_ + { + + unsigned int vpi:12; /**< [31:20] ATM VPI [11:0] OR GFC [3:0] and VPI [7:0] + @li Note: if VCIdleRxGFC is set to 0 the GFC field is ignored in test. */ + + unsigned int vci:16; /**< [19:4] ATM VCI [15:0] */ + + unsigned int pti:3; /**< [3:1] ATM PTI PTI [2:0] + @li Note: if VCIdleRxPTI is set to 0 the PTI field is ignored in test.*/ + + unsigned int clp:1; /**< [0] ATM CLP [0] + @li Note: if VCIdleRxCLP is set to 0 the CLP field is ignored in test.*/ + } utRxDefineIdle; /**< Rx idle cell config Utopia register */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtRxEnableFields_ + * @brief Utopia Rx enable Register + */ + struct UtRxEnableFields_ + { + + unsigned int defineRxIdleGFC:1;/**< [31] This register is used to include or exclude the GFC + field of the ATM header when testing for Idle cells. + @li 1 - GFC field is valid. + @li 0 - GFC field ignored.*/ + + unsigned int defineRxIdlePTI:1;/**< [30] This register is used to include or exclude the PTI + field of the ATM header when testing for Idle cells. + @li 1 - PTI field is valid. + @li 0 - PTI field ignored.*/ + + unsigned int defineRxIdleCLP:1;/**< [29] This register is used to include or exclude the CLP + field of the ATM header when testing for Idle cells. + @li 1 - CLP field is valid. + @li 0 - CLP field ignored.*/ + + unsigned int phyStatsRxEnb:1;/**< [28] This register is used to enable or disable ATM statistics + gathering based on the specified PHY address as defined in RxStatsConfig + register. + @li 1 - Enable statistics for specified receive PHY address. + @li 0 - Disable statistics for specified receive PHY address.*/ + + unsigned int vcStatsRxEnb:1;/**< [27] This register is used to enable or disable ATM statistics + gathering based on a specific VPI/VCI address. + @li 1 - Enable statistics for specified VPI/VCI address. + @li 0 - Disable statistics for specified VPI/VCI address.*/ + + unsigned int vcStatsRxGFC:1;/**< [26] This register is used to include or exclude the GFC field + of the ATM header when ATM VPI/VCI statistics are enabled. GFC is only + available at the UNI and uses the first 4-bits of the VPI field. + @li 1 - GFC field is valid. + @li 0 - GFC field ignored. */ + + unsigned int vcStatsRxPTI:1;/**< [25] This register is used to include or exclude the PTI field + of the ATM header when ATM VPI/VCI statistics are enabled. + @li 1 - PTI field is valid. + @li 0 - PTI field ignored.*/ + + unsigned int vcStatsRxCLP:1;/**< [24] This register is used to include or exclude the CLP field + of the ATM header when ATM VPI/VCI statistics are enabled. + @li 1 - CLP field is valid. + @li 0 - CLP field ignored. */ + + unsigned int discardHecErr:1;/**< [23] Discard cells with an invalid HEC. + @li 1 - Discard cells with HEC errors + @li 0 - Cells with HEC errors are passed */ + + unsigned int discardParErr:1;/**< [22] Discard cells containing parity errors. + @li 1 - Discard cells with parity errors + @li 0 - Cells with parity errors are passed */ + + unsigned int discardIdle:1; /**< [21] Discard Idle Cells based on DefineIdle register values + @li 1 - Discard IDLE cells + @li 0 - IDLE cells passed */ + + unsigned int enbHecErrCnt:1;/**< [20] Enable Receive HEC Error Count. + @li 1 - Enable count of received cells containing HEC errors + @li 0 - No count is maintained. */ + + unsigned int enbParErrCnt:1;/**< [19] Enable Parity Error Count + @li 1 - Enable count of received cells containing Parity errors + @li 0 - No count is maintained. */ + + unsigned int enbIdleCellCnt:1;/**< [18] Enable Receive Idle Cell Count. + @li 1 - Enable count of Idle cells received. + @li 0 - No count is maintained.*/ + + unsigned int enbSizeErrCnt:1;/**< [17] Enable Receive Size Error Count. + @li 1 - Enable count of received cells of incorrect size + @li 0 - No count is maintained. */ + + unsigned int enbRxCellCnt:1;/**< [16] Enable Receive Valid Cell Count of non-idle/non-error cells. + @li 1 - Enable count of valid cells received - non-idle/non-error + @li 0 - No count is maintained. */ + + unsigned int reserved_1:3; /**< [15:13] These bits are always 0 */ + + unsigned int rxCellOvrInt:1; /**< [12] Enable CBI Utopia Receive Status Condition if the RxCellCount + register overflows. + @li 1 - CBI Receive Status asserted. + @li 0 - No CBI Receive Status asserted.*/ + + unsigned int invalidHecOvrInt:1; /**< [11] Enable CBI Receive Status Condition if the InvalidHecCount + register overflows. + @li 1 - CBI Receive Condition asserted. + @li 0 - No CBI Receive Condition asserted */ + + unsigned int invalidParOvrInt:1; /**< [10] Enable CBI Receive Status Condition if the InvalidParCount + register overflows + @li 1 - CBI Receive Condition asserted. + @li 0 - No CBI Receive Condition asserted */ + + unsigned int invalidSizeOvrInt:1; /**< [9] Enable CBI Receive Status Condition if the InvalidSizeCount + register overflows. + @li 1 - CBI Receive Status Condition asserted. + @li¸0 - No CBI Receive Status asserted */ + + unsigned int rxIdleOvrInt:1; /**< [8] Enable CBI Receive Status Condition if the RxIdleCount overflows. + @li 1 - CBI Receive Condition asserted. + @li 0 - No CBI Receive Condition asserted */ + + unsigned int reserved_2:3; /**< [7:5] These bits are always 0 */ + + unsigned int rxAddrMask:5; /**< [4:0] This register is used as a mask to allow the user to increase + the PHY receive address range. The register should be programmed with + the address-range limit, i.e. if set to 0x3 the address range increases + to a maximum of 4 addresses. */ + } utRxEnableFields; /**< Rx enable Utopia register */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtRxTransTable0_ + * @brief Utopia Rx translation table Register + */ + struct UtRxTransTable0_ + { + + unsigned int phy0:5; /**< [31-27] Rx Mapping value of logical phy 0 */ + + unsigned int phy1:5; /**< [26-22] Rx Mapping value of logical phy 1 */ + + unsigned int phy2:5; /**< [21-17] Rx Mapping value of logical phy 2 */ + + unsigned int reserved_1:1; /**< [16] These bits are always 0 */ + + unsigned int phy3:5; /**< [15-11] Rx Mapping value of logical phy 3 */ + + unsigned int phy4:5; /**< [10-6] Rx Mapping value of logical phy 4 */ + + unsigned int phy5:5; /**< [5-1] Rx Mapping value of logical phy 5 */ + + unsigned int reserved_2:1; /**< [0] These bits are always 0 */ + } + + utRxTransTable0; /**< Rx translation table */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtRxTransTable1_ + * @brief Utopia Rx translation table Register + */ + struct UtRxTransTable1_ + { + + unsigned int phy6:5; /**< [31-27] Rx Mapping value of logical phy 6 */ + + unsigned int phy7:5; /**< [26-22] Rx Mapping value of logical phy 7 */ + + unsigned int phy8:5; /**< [21-17] Rx Mapping value of logical phy 8 */ + + unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */ + + unsigned int phy9:5; /**< [15-11] Rx Mapping value of logical phy 3 */ + + unsigned int phy10:5; /**< [10-6] Rx Mapping value of logical phy 4 */ + + unsigned int phy11:5; /**< [5-1] Rx Mapping value of logical phy 5 */ + + unsigned int reserved_2:1; /**< [0] These bits are always 0 */ + } + + utRxTransTable1; /**< Rx translation table */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtRxTransTable2_ + * @brief Utopia Rx translation table Register + */ + struct UtRxTransTable2_ + { + + unsigned int phy12:5; /**< [31-27] Rx Mapping value of logical phy 6 */ + + unsigned int phy13:5; /**< [26-22] Rx Mapping value of logical phy 7 */ + + unsigned int phy14:5; /**< [21-17] Rx Mapping value of logical phy 8 */ + + unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */ + + unsigned int phy15:5; /**< [15-11] Rx Mapping value of logical phy 3 */ + + unsigned int phy16:5; /**< [10-6] Rx Mapping value of logical phy 4 */ + + unsigned int phy17:5; /**< [5-1] Rx Mapping value of logical phy 5 */ + + unsigned int reserved_2:1; /**< [0] These bits are always 0 */ + } utRxTransTable2; /**< Rx translation table */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtRxTransTable3_ + * @brief Utopia Rx translation table Register + */ + struct UtRxTransTable3_ + { + + unsigned int phy18:5; /**< [31-27] Rx Mapping value of logical phy 6 */ + + unsigned int phy19:5; /**< [26-22] Rx Mapping value of logical phy 7 */ + + unsigned int phy20:5; /**< [21-17] Rx Mapping value of logical phy 8 */ + + unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */ + + unsigned int phy21:5; /**< [15-11] Rx Mapping value of logical phy 3 */ + + unsigned int phy22:5; /**< [10-6] Rx Mapping value of logical phy 4 */ + + unsigned int phy23:5; /**< [5-1] Rx Mapping value of logical phy 5 */ + + unsigned int reserved_2:1; /**< [0] These bits are always 0 */ + } utRxTransTable3; /**< Rx translation table */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtRxTransTable4_ + * @brief Utopia Rx translation table Register + */ + struct UtRxTransTable4_ + { + + unsigned int phy24:5; /**< [31-27] Rx Mapping value of logical phy 6 */ + + unsigned int phy25:5; /**< [26-22] Rx Mapping value of logical phy 7 */ + + unsigned int phy26:5; /**< [21-17] Rx Mapping value of logical phy 8 */ + + unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */ + + unsigned int phy27:5; /**< [15-11] Rx Mapping value of logical phy 3 */ + + unsigned int phy28:5; /**< [10-6] Rx Mapping value of logical phy 4 */ + + unsigned int phy29:5; /**< [5-1] Rx Mapping value of logical phy 5 */ + + unsigned int reserved_2:1; /**< [0] These bits are always 0 */ + } utRxTransTable4; /**< Rx translation table */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtRxTransTable5_ + * @brief Utopia Rx translation table Register + */ + struct UtRxTransTable5_ + { + + unsigned int phy30:5; /**< [31-27] Rx Mapping value of logical phy 6 */ + + unsigned int reserved_1:27; /**< [26-0] These bits are always 0 */ + + } utRxTransTable5; /**< Rx translation table */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtSysConfig_ + * @brief NPE setup Register + */ + struct UtSysConfig_ + { + + unsigned int reserved_1:2; /**< [31-30] These bits are always 0 */ + unsigned int txEnbFSM:1; /**< [29] Enables the operation ofthe Utopia Transmit FSM + * @li 1 - FSM enabled + * @li 0 - FSM inactive + */ + unsigned int rxEnbFSM:1; /**< [28] Enables the operation ofthe Utopia Revieve FSM + * @li 1 - FSM enabled + * @li 0 - FSM inactive + */ + unsigned int disablePins:1; /**< [27] Disable Utopia interface I/O pins forcing the signals to an + * inactive state. Note that this bit is set on reset and must be + * de-asserted + * @li 0 - Normal data transfer + * @li 1 - Utopia interface pins are forced inactive + */ + unsigned int tstLoop:1; /**< [26] Test Loop Back Enable. + * @li Note: For loop back to function RxMode and Tx Mode must both be set + * to single PHY mode. + * @li 0 - Loop back + * @li 1 - Normal operating mode + */ + + unsigned int txReset:1; /**< [25] Resets the Utopia Coprocessor transmit module to a known state. + * @li Note: All transmit configuration and status registers will be reset + * to their reset values. + * @li 0 - Normal operating mode¸ + * @li 1 - Reset transmit modules + */ + + unsigned int rxReset:1; /**< [24] Resets the Utopia Coprocessor receive module to a known state. + * @li Note: All receive configuration and status registers will be reset + * to their reset values. + * @li 0 - Normal operating mode + * @li 1 - Reset receive modules + */ + + unsigned int reserved_2:24; /**< [23-0] These bits are always 0 */ + } utSysConfig; /**< NPE debug config */ + +} +IxAtmdAccUtopiaConfig; + +/** +* +* @brief Utopia status +* +* This structure is used to set/get the Utopia status parameters +* @li contains debug cell counters, to be accessed during a read operation +* +* @note - the exact description of all parameters is done in the Utopia reference +* documents. +* +*/ +typedef struct +{ + + unsigned int utTxCellCount; /**< count of cells transmitted */ + + unsigned int utTxIdleCellCount; /**< count of idle cells transmitted */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtTxCellConditionStatus_ + * @brief Utopia Tx Status Register + */ + struct UtTxCellConditionStatus_ + { + + unsigned int reserved_1:2; /**< [31:30] These bits are always 0 */ + unsigned int txFIFO2Underflow:1; /**< [29] This bit is set if 64-byte + * Transmit FIFO2 indicates a FIFO underflow + * error condition. + */ + unsigned int txFIFO1Underflow:1; /**< [28] This bit is set if + * 64-byte Transmit FIFO1 indicates a FIFO + * underflow error condition. + */ + unsigned int txFIFO2Overflow:1; /**< [27] This bit is set if 64-byte + * Transmit FIFO2 indicates a FIFO overflow + * error condition. + */ + unsigned int txFIFO1Overflow:1; /**< [26] This bit is set if 64-byte + * Transmit FIFO1 indicates a FIFO overflow + * error condition. + */ + unsigned int txIdleCellCountOvr:1; /**< [25] This bit is set if the + * TxIdleCellCount register overflows. + */ + unsigned int txCellCountOvr:1; /**< [24] This bit is set if the + * TxCellCount register overflows + */ + unsigned int reserved_2:24; /**< [23:0] These bits are always 0 */ + } utTxCellConditionStatus; /**< Tx cells condition status */ + + unsigned int utRxCellCount; /**< count of cell received */ + unsigned int utRxIdleCellCount; /**< count of idle cell received */ + unsigned int utRxInvalidHECount; /**< count of invalid cell + * received because of HEC errors + */ + unsigned int utRxInvalidParCount; /**< count of invalid cell received + * because of parity errors + */ + unsigned int utRxInvalidSizeCount; /**< count of invalid cell + * received because of cell + * size errors + */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtRxCellConditionStatus_ + * @brief Utopia Rx Status Register + */ + struct UtRxCellConditionStatus_ + { + + unsigned int reserved_1:3; /**< [31:29] These bits are always 0.*/ + unsigned int rxCellCountOvr:1; /**< [28] This bit is set if the RxCellCount register overflows. */ + unsigned int invalidHecCountOvr:1; /**< [27] This bit is set if the InvalidHecCount register overflows.*/ + unsigned int invalidParCountOvr:1; /**< [26] This bit is set if the InvalidParCount register overflows.*/ + unsigned int invalidSizeCountOvr:1; /**< [25] This bit is set if the InvalidSizeCount register overflows.*/ + unsigned int rxIdleCountOvr:1; /**< [24] This bit is set if the RxIdleCount register overflows.*/ + unsigned int reserved_2:4; /**< [23:20] These bits are always 0 */ + unsigned int rxFIFO2Underflow:1; /**< [19] This bit is set if 64-byte Receive FIFO2 + * indicates a FIFO underflow error condition. + */ + unsigned int rxFIFO1Underflow:1; /**< [18] This bit is set if 64-byte Receive + * FIFO1 indicates a FIFO underflow error condition + . */ + unsigned int rxFIFO2Overflow:1; /**< [17] This bit is set if 64-byte Receive FIFO2 + * indicates a FIFO overflow error condition. + */ + unsigned int rxFIFO1Overflow:1; /**< [16] This bit is set if 64-byte Receive FIFO1 + * indicates a FIFO overflow error condition. + */ + unsigned int reserved_3:16; /**< [15:0] These bits are always 0. */ + } utRxCellConditionStatus; /**< Rx cells condition status */ + +} IxAtmdAccUtopiaStatus; + +/** + * @} defgroup IxAtmdAccUtopiaCtrlAPI + */ + + /** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @fn ixAtmdAccUtopiaConfigSet (const IxAtmdAccUtopiaConfig * + ixAtmdAccUtopiaConfigPtr) + * + * @brief Send the configuration structure to the Utopia interface + * + * This function downloads the @a IxAtmdAccUtopiaConfig structure to + * the Utopia and has the following effects + * @li setup the Utopia interface + * @li initialise the NPE + * @li reset the Utopia cell counters and status registers to known values + * + * This action has to be done once at initialisation. A lock is preventing + * the concurrent use of @a ixAtmdAccUtopiaStatusGet() and + * @A ixAtmdAccUtopiaConfigSet() + * + * @param *ixAtmdAccNPEConfigPtr @ref IxAtmdAccUtopiaConfig [in] - pointer to a structure to download to + * Utopia. This parameter cannot be a null pointer. + * + * @return @li IX_SUCCESS successful download + * @return @li IX_FAIL error in the parameters, or configuration is not + * complete or failed + * + * @sa ixAtmdAccUtopiaStatusGet + * + */ +PUBLIC IX_STATUS ixAtmdAccUtopiaConfigSet (const IxAtmdAccUtopiaConfig * + ixAtmdAccUtopiaConfigPtr); + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @fn ixAtmdAccUtopiaStatusGet (IxAtmdAccUtopiaStatus * + ixAtmdAccUtopiaStatus) + * + * @brief Get the Utopia interface configuration. + * + * This function reads the Utopia registers and the Cell counts + * and fills the @a IxAtmdAccUtopiaStatus structure + * + * A lock is preventing the concurrent + * use of @a ixAtmdAccUtopiaStatusGet() and @A ixAtmdAccUtopiaConfigSet() + * + * @param ixAtmdAccUtopiaStatus @ref IxAtmdAccUtopiaStatus [out] - pointer to structure to be updated from internal + * hardware counters. This parameter cannot be a NULL pointer. + * + * @return @li IX_SUCCESS successful read + * @return @li IX_FAIL error in the parameters null pointer, or + * configuration read is not complete or failed + * + * @sa ixAtmdAccUtopiaConfigSet + * + */ +PUBLIC IX_STATUS ixAtmdAccUtopiaStatusGet (IxAtmdAccUtopiaStatus * + ixAtmdAccUtopiaStatus); + +/** + * + * @ingroup IxAtmdAcc + * + * @fn ixAtmdAccPortEnable (IxAtmLogicalPort port) + * + * @brief enable a PHY logical port + * + * This function enables the transmission over one port. It should be + * called before accessing any resource from this port and before the + * establishment of a VC. + * + * When a port is enabled, the cell transmission to the Utopia interface + * is started. If there is no traffic already running, idle cells are + * sent over the interface. + * + * This function can be called multiple times. + * + * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] + * + * @return @li IX_SUCCESS enable is complete + * @return @li IX_ATMDACC_WARNING port already enabled + * @return @li IX_FAIL enable failed, wrong parameter, or cannot + * initialise this port (the port is maybe already in use, + * or there is a hardware issue) + * + * @note - This function needs internal locks and should not be + * called from an interrupt context + * + * @sa ixAtmdAccPortDisable + * + */ +PUBLIC IX_STATUS ixAtmdAccPortEnable (IxAtmLogicalPort port); + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @fn ixAtmdAccPortDisable (IxAtmLogicalPort port) + * + * @brief disable a PHY logical port + * + * This function disable the transmission over one port. + * + * When a port is disabled, the cell transmission to the Utopia interface + * is stopped. + * + * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] + * + * @return @li IX_SUCCESS disable is complete + * @return @li IX_ATMDACC_WARNING port already disabled + * @return @li IX_FAIL disable failed, wrong parameter . + * + * @note - This function needs internal locks and should not be called + * from an interrupt context + * + * @note - The response from hardware is done through the txDone mechanism + * to ensure the synchrnisation with tx resources. Therefore, the + * txDone mechanism needs to be serviced to make a PortDisable complete. + * + * @sa ixAtmdAccPortEnable + * @sa ixAtmdAccPortDisableComplete + * @sa ixAtmdAccTxDoneDispatch + * + */ +PUBLIC IX_STATUS ixAtmdAccPortDisable (IxAtmLogicalPort port); + +/** +* +* @ingroup IxAtmdAccCtrlAPI +* +* @fn ixAtmdAccPortDisableComplete (IxAtmLogicalPort port) +* +* @brief disable a PHY logical port +* +* This function indicates if the port disable for a port has completed. This +* function will return TRUE if the port has never been enabled. +* +* @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] +* +* @return @li TRUE disable is complete +* @return @li FALSE disable failed, wrong parameter . +* +* @note - This function needs internal locks and should not be called +* from an interrupt context +* +* @sa ixAtmdAccPortEnable +* @sa ixAtmdAccPortDisable +* +*/ +PUBLIC BOOL ixAtmdAccPortDisableComplete (IxAtmLogicalPort port); + +#endif /* IXATMDACCCTRL_H */ + +/** + * @} defgroup IxAtmdAccCtrlAPI + */ + + diff --git a/arch/arm/cpu/ixp/npe/include/IxAtmm.h b/arch/arm/cpu/ixp/npe/include/IxAtmm.h new file mode 100644 index 0000000000..fcf523fca4 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/IxAtmm.h @@ -0,0 +1,795 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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 */ + +/** @} */ diff --git a/arch/arm/cpu/ixp/npe/include/IxDmaAcc.h b/arch/arm/cpu/ixp/npe/include/IxDmaAcc.h new file mode 100644 index 0000000000..45c7527de9 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/IxDmaAcc.h @@ -0,0 +1,260 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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 */ + diff --git a/arch/arm/cpu/ixp/npe/include/IxEthAcc.h b/arch/arm/cpu/ixp/npe/include/IxEthAcc.h new file mode 100644 index 0000000000..ff706c451d --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/IxEthAcc.h @@ -0,0 +1,2512 @@ +/** @file IxEthAcc.h + * + * @brief this file contains the public API of @ref IxEthAcc component + * + * Design notes: + * The IX_OSAL_MBUF address is to be specified on bits [31-5] and must + * be cache aligned (bits[4-0] cleared) + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + * + */ + +#ifndef IxEthAcc_H +#define IxEthAcc_H + +#include +#include + +/** + * @defgroup IxEthAcc IXP400 Ethernet Access (IxEthAcc) API + * + * @brief ethAcc is a library that does provides access to the internal IXP400 10/100Bt Ethernet MACs. + * + *@{ + */ + +/** + * @ingroup IxEthAcc + * @brief Definition of the Ethernet Access status + */ +typedef enum /* IxEthAccStatus */ +{ + IX_ETH_ACC_SUCCESS = IX_SUCCESS, /**< return success*/ + IX_ETH_ACC_FAIL = IX_FAIL, /**< return fail*/ + IX_ETH_ACC_INVALID_PORT, /**< return invalid port*/ + IX_ETH_ACC_PORT_UNINITIALIZED, /**< return uninitialized*/ + IX_ETH_ACC_MAC_UNINITIALIZED, /**< return MAC uninitialized*/ + IX_ETH_ACC_INVALID_ARG, /**< return invalid arg*/ + IX_ETH_TX_Q_FULL, /**< return tx queue is full*/ + IX_ETH_ACC_NO_SUCH_ADDR /**< return no such address*/ +} IxEthAccStatus; + +/** + * @ingroup IxEthAcc + * @enum IxEthAccPortId + * @brief Definition of the IXP400 Mac Ethernet device. + */ +typedef enum +{ + IX_ETH_PORT_1 = 0, /**< Ethernet Port 1 */ + IX_ETH_PORT_2 = 1 /**< Ethernet port 2 */ + ,IX_ETH_PORT_3 = 2 /**< Ethernet port 3 */ +} IxEthAccPortId; + +/** + * @ingroup IxEthAcc + * + * @def IX_ETH_ACC_NUMBER_OF_PORTS + * + * @brief Definition of the number of ports + * + */ +#ifdef __ixp46X +#define IX_ETH_ACC_NUMBER_OF_PORTS (3) +#else +#define IX_ETH_ACC_NUMBER_OF_PORTS (2) +#endif + +/** + * @ingroup IxEthAcc + * + * @def IX_IEEE803_MAC_ADDRESS_SIZE + * + * @brief Definition of the size of the MAC address + * + */ +#define IX_IEEE803_MAC_ADDRESS_SIZE (6) + + +/** + * + * @brief Definition of the IEEE 802.3 Ethernet MAC address structure. + * + * The data should be packed with bytes xx:xx:xx:xx:xx:xx + * @note + * The data must be packed in network byte order. + */ +typedef struct +{ + UINT8 macAddress[IX_IEEE803_MAC_ADDRESS_SIZE]; /**< MAC address */ +} IxEthAccMacAddr; + +/** + * @ingroup IxEthAcc + * @def IX_ETH_ACC_NUM_TX_PRIORITIES + * @brief Definition of the number of transmit priorities + * + */ +#define IX_ETH_ACC_NUM_TX_PRIORITIES (8) + +/** + * @ingroup IxEthAcc + * @enum IxEthAccTxPriority + * @brief Definition of the relative priority used to transmit a frame + * + */ +typedef enum +{ + IX_ETH_ACC_TX_PRIORITY_0 = 0, /** STA */ + IX_ETHACC_RX_APTYPE = 0x30 /**< 802.11, AP <=> AP */ +} IxEthAccRxFrameType; + +/** + * @ingroup IxEthAcc + * @enum IxEthAccDuplexMode + * @brief Definition to provision the duplex mode of the MAC. + * + */ +typedef enum +{ + IX_ETH_ACC_FULL_DUPLEX, /**< Full duplex operation of the MAC */ + IX_ETH_ACC_HALF_DUPLEX /**< Half duplex operation of the MAC */ +} IxEthAccDuplexMode; + + +/** + * @ingroup IxEthAcc + * @struct IxEthAccNe + * @brief Definition of service-specific informations. + * + * This structure defines the Ethernet service-specific informations + * and enable QoS and VLAN features. + */ +typedef struct +{ + UINT32 ixReserved_next; /**< reserved for chaining */ + UINT32 ixReserved_lengths; /**< reserved for buffer lengths */ + UINT32 ixReserved_data; /**< reserved for buffer pointer */ + UINT8 ixDestinationPortId; /**< Destination portId for this packet, if known by NPE */ + UINT8 ixSourcePortId; /**< Source portId for this packet */ + UINT16 ixFlags; /**< BitField of option for this frame */ + UINT8 ixQoS; /**< QoS class of the frame */ + UINT8 ixReserved; /**< reserved */ + UINT16 ixVlanTCI; /**< Vlan TCI */ + UINT8 ixDestMac[IX_IEEE803_MAC_ADDRESS_SIZE]; /**< Destination MAC address */ + UINT8 ixSourceMac[IX_IEEE803_MAC_ADDRESS_SIZE]; /**< Source MAC address */ +} IxEthAccNe; + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_PORT_UNKNOWN + * + * @brief Contents of the field @a IX_ETHACC_NE_DESTPORTID when no + * destination port can be found by the NPE for this frame. + * + */ +#define IX_ETHACC_NE_PORT_UNKNOWN (0xff) + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_DESTMAC + * + * @brief The location of the destination MAC address in the Mbuf header. + * + */ +#define IX_ETHACC_NE_DESTMAC(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixDestMac + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_SOURCEMAC + * + * @brief The location of the source MAC address in the Mbuf header. + * + */ +#define IX_ETHACC_NE_SOURCEMAC(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixSourceMac + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_VLANTCI + * + * @brief The VLAN Tag Control Information associated with this frame + * + * The VLAN Tag Control Information associated with this frame. On Rx + * path, this field is extracted from the packet header. + * On Tx path, the value of this field is inserted in the frame when + * the port is configured to insert or replace vlan tags in the + * egress frames. + * + * @sa IX_ETHACC_NE_FLAGS + */ +#define IX_ETHACC_NE_VLANTCI(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixVlanTCI + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_SOURCEPORTID + * + * @brief The port where this frame came from. + * + * The port where this frame came from. This field is set on receive + * with the port information. This field is ignored on Transmit path. + */ +#define IX_ETHACC_NE_SOURCEPORTID(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixSourcePortId + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_DESTPORTID + * + * @brief The destination port where this frame should be sent. + * + * The destination port where this frame should be sent. + * + * @li In the transmit direction, this field contains the destination port + * and is ignored unless @a IX_ETHACC_NE_FLAG_DST is set. + * + * @li In the receive direction, this field contains the port where the + * destination MAC addresses has been learned. If the destination + * MAC address is unknown, then this value is set to the reserved value + * @a IX_ETHACC_NE_PORT_UNKNOWN + * + */ +#define IX_ETHACC_NE_DESTPORTID(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixDestinationPortId + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_QOS + * + * @brief QualityOfService class (QoS) for this received frame. + * + */ +#define IX_ETHACC_NE_QOS(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixQoS + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_FLAGS + * + * @brief Bit Mask of the different flags associated with a frame + * + * The flags are the bit-oring combination + * of the following different fields : + * + * @li IP flag (Rx @a IX_ETHACC_NE_IPMASK) + * @li Spanning Tree flag (Rx @a IX_ETHACC_NE_STMASK) + * @li Link layer type (Rx and Tx @a IX_ETHACC_NE_LINKMASK) + * @li VLAN Tagged Frame (Rx @a IX_ETHACC_NE_VLANMASK) + * @li New source MAC address (Rx @a IX_ETHACC_NE_NEWSRCMASK) + * @li Multicast flag (Rx @a IX_ETHACC_NE_MCASTMASK) + * @li Broadcast flag (Rx @a IX_ETHACC_NE_BCASTMASK) + * @li Destination port flag (Tx @a IX_ETHACC_NE_PORTMASK) + * @li Tag/Untag Tx frame (Tx @a IX_ETHACC_NE_TAGMODEMASK) + * @li Overwrite destination port (Tx @a IX_ETHACC_NE_PORTOVERMASK) + * @li Filtered frame (Rx @a IX_ETHACC_NE_STMASK) + * @li VLAN Enabled (Rx and Tx @a IX_ETHACC_NE_VLANENABLEMASK) + */ +#define IX_ETHACC_NE_FLAGS(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixFlags + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_BCASTMASK + * + * @brief This mask defines if a received frame is a broadcast frame. + * + * This mask defines if a received frame is a broadcast frame. + * The BCAST flag is set when the destination MAC address of + * a frame is broadcast. + * + * @sa IX_ETHACC_NE_FLAGS + * + */ +#define IX_ETHACC_NE_BCASTMASK (0x1) + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_MCASTMASK + * + * @brief This mask defines if a received frame is a multicast frame. + * + * This mask defines if a received frame is a multicast frame. + * The MCAST flag is set when the destination MAC address of + * a frame is multicast. + * + * @sa IX_ETHACC_NE_FLAGS + * + */ +#define IX_ETHACC_NE_MCASTMASK (0x1 << 1) + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_IPMASK + * + * @brief This mask defines if a received frame is a IP frame. + * + * This mask applies to @a IX_ETHACC_NE_FLAGS and defines if a received + * frame is a IP frame. The IP flag is set on Rx direction, depending on + * the frame contents. The flag is set when the length/type field of a + * received frame is 0x8000. + * + * @sa IX_ETHACC_NE_FLAGS + * + */ +#define IX_ETHACC_NE_IPMASK (0x1 << 2) + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_VLANMASK + * + * @brief This mask defines if a received frame is VLAN tagged. + * + * This mask defines if a received frame is VLAN tagged. + * When set, the Rx frame is VLAN-tagged and the tag value + * is available thru @a IX_ETHACC_NE_VLANID. + * Note that when sending frames which are already tagged + * this flag should be set, to avoid inserting another VLAN tag. + * + * @sa IX_ETHACC_NE_FLAGS + * @sa IX_ETHACC_NE_VLANID + * + */ +#define IX_ETHACC_NE_VLANMASK (0x1 << 3) + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_LINKMASK + * + * @brief This mask is the link layer protocol indicator + * + * This mask applies to @a IX_ETHACC_NE_FLAGS. + * It reflects the state of a frame as it exits an NPE on the Rx path + * or enters an NPE on the Tx path. Its values are as follows: + * @li 0x00 - IEEE802.3 - 8802 (Rx) / IEEE802.3 - 8802 (Tx) + * @li 0x01 - IEEE802.3 - Ethernet (Rx) / IEEE802.3 - Ethernet (Tx) + * @li 0x02 - IEEE802.11 AP -> STA (Rx) / IEEE802.11 STA -> AP (Tx) + * @li 0x03 - IEEE802.11 AP -> AP (Rx) / IEEE802.11 AP->AP (Tx) + * + * @sa IX_ETHACC_NE_FLAGS + * + */ +#define IX_ETHACC_NE_LINKMASK (0x3 << 4) + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_STMASK + * + * @brief This mask defines if a received frame is a Spanning Tree frame. + * + * This mask applies to @a IX_ETHACC_NE_FLAGS. + * On rx direction, it defines if a received if frame is a Spanning Tree frame. + * Setting this fkag on transmit direction overrides the port settings + * regarding the VLAN options and + * + * @sa IX_ETHACC_NE_FLAGS + * + */ +#define IX_ETHACC_NE_STMASK (0x1 << 6) + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_FILTERMASK + * + * @brief This bit indicates whether a frame has been filtered by the Rx service. + * + * This mask applies to @a IX_ETHACC_NE_FLAGS. + * Certain frames, which should normally be fully filtered by the NPE to due + * the destination MAC address being on the same segment as the Rx port are + * still forwarded to the XScale (although the payload is invalid) in order + * to learn the MAC address of the transmitting station, if this is unknown. + * Normally EthAcc will filter and recycle these framess internally and no + * frames with the FILTER bit set will be received by the client. + * + * @sa IX_ETHACC_NE_FLAGS + * + */ +#define IX_ETHACC_NE_FILTERMASK (0x1 << 7) + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_PORTMASK + * + * @brief This mask defines the rule to transmit a frame + * + * This mask defines the rule to transmit a frame. When set, a frame + * is transmitted to the destination port as set by the macro + * @a IX_ETHACC_NE_DESTPORTID. If not set, the destination port + * is searched using the destination MAC address. + * + * @note This flag is meaningful only for multiport Network Engines. + * + * @sa IX_ETHACC_NE_FLAGS + * @sa IX_ETHACC_NE_DESTPORTID + * + */ +#define IX_ETHACC_NE_PORTOVERMASK (0x1 << 8) + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_TAGMODEMASK + * + * @brief This mask defines the tagging rules to apply to a transmit frame. + * + * This mask defines the tagging rules to apply to a transmit frame + * regardless of the default setting for a port. When used together + * with @a IX_ETHACC_NE_TAGOVERMASK and when set, the + * frame will be tagged prior to transmission. When not set, + * the frame will be untagged prior to transmission. This is accomplished + * irrespective of the Egress tagging rules, constituting a per-frame override. + * + * @sa IX_ETHACC_NE_FLAGS + * @sa IX_ETHACC_NE_TAGOVERMASK + * + */ +#define IX_ETHACC_NE_TAGMODEMASK (0x1 << 9) + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_TAGOVERMASK + * + * @brief This mask defines the rule to transmit a frame + * + * This mask defines the rule to transmit a frame. When set, the + * default transmit rules of a port are overriden. + * When not set, the default rules as set by @ref IxEthDB should apply. + * + * @sa IX_ETHACC_NE_FLAGS + * @sa IX_ETHACC_NE_TAGMODEMASK + * + */ +#define IX_ETHACC_NE_TAGOVERMASK (0x1 << 10) + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_VLANENABLEMASK + * + * @brief This mask defines if a frame is a VLAN frame or not + * + * When set, frames undergo normal VLAN processing on the Tx path + * (membership filtering, tagging, tag removal etc). If this flag is + * not set, the frame is considered to be a regular non-VLAN frame + * and no VLAN processing will be performed. + * + * Note that VLAN-enabled NPE images will always set this flag in all + * Rx frames, and images which are not VLAN enabled will clear this + * flag for all received frames. + * + * @sa IX_ETHACC_NE_FLAGS + * + */ +#define IX_ETHACC_NE_VLANENABLEMASK (0x1 << 14) + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_NEWSRCMASK + * + * @brief This mask defines if a received frame has been learned. + * + * This mask defines if the source MAC address of a frame is + * already known. If the bit is set, the source MAC address was + * unknown to the NPE at the time the frame was received. + * + * @sa IX_ETHACC_NE_FLAGS + * + */ +#define IX_ETHACC_NE_NEWSRCMASK (0x1 << 15) + +/** + * @ingroup IxEthAcc + * + * @brief This defines the recommanded minimum size of MBUF's submitted + * to the frame receive service. + * + */ +#define IX_ETHACC_RX_MBUF_MIN_SIZE (2048) + +/** + * @ingroup IxEthAcc + * + * @brief This defines the highest MII address of any attached PHYs + * + * The maximum number for PHY address is 31, add on for range checking. + * + */ +#define IXP425_ETH_ACC_MII_MAX_ADDR 32 + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccInit(void) + * + * @brief Initializes the IXP400 Ethernet Access Service. + * + * @li Reentrant - no + * @li ISR Callable - no + * + * This should be called once per module initialization. + * @pre + * The NPE must first be downloaded with the required microcode which supports all + * required features. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_FAIL : Service has failed to initialize. + * + *
+ */ +PUBLIC IxEthAccStatus ixEthAccInit(void); + + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccUnload(void) + * + * @brief Unload the Ethernet Access Service. + * + * @li Reentrant - no + * @li ISR Callable - no + * + * @return void + * + *
+ */ +PUBLIC void ixEthAccUnload(void); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortInit( IxEthAccPortId portId) + * + * @brief Initializes an NPE/Ethernet MAC Port. + * + * The NPE/Ethernet port initialisation includes the following steps + * @li Initialize the NPE/Ethernet MAC hardware. + * @li Verify NPE downloaded and operational. + * @li The NPE shall be available for usage once this API returns. + * @li Verify that the Ethernet port is present before initializing + * + * @li Reentrant - no + * @li ISR Callable - no + * + * This should be called once per mac device. + * The NPE/MAC shall be in disabled state after init. + * + * @pre + * The component must be initialized via @a ixEthAccInit + * The NPE must first be downloaded with the required microcode which supports all + * required features. + * + * Dependant on Services: (Must be initialized before using this service may be initialized) + * ixNPEmh - NPE Message handling service. + * ixQmgr - Queue Manager component. + * + * @param portId @ref IxEthAccPortId [in] + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS: if the ethernet port is not present, a warning is issued. + * @li @a IX_ETH_ACC_FAIL : The NPE processor has failed to initialize. + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * + *
+ */ +PUBLIC IxEthAccStatus ixEthAccPortInit(IxEthAccPortId portId); + + +/************************************************************************* + + ##### ## ##### ## ##### ## ##### # # + # # # # # # # # # # # # # # + # # # # # # # # # # # # ###### + # # ###### # ###### ##### ###### # # # + # # # # # # # # # # # # # + ##### # # # # # # # # # # # + +*************************************************************************/ + + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortTxFrameSubmit( + IxEthAccPortId portId, + IX_OSAL_MBUF *buffer, + IxEthAccTxPriority priority) + * + * @brief This function shall be used to submit MBUFs buffers for transmission on a particular MAC device. + * + * When the frame is transmitted, the buffer shall be returned thru the + * callback @a IxEthAccPortTxDoneCallback. + * + * In case of over-submitting, the order of the frames on the + * network may be modified. + * + * Buffers shall be not queued for transmission if the port is disabled. + * The port can be enabled using @a ixEthAccPortEnable + * + * + * @li Reentrant - yes + * @li ISR Callable - yes + * + * + * @pre + * @a ixEthAccPortTxDoneCallbackRegister must be called to register a function to allow this service to + * return the buffer to the calling service. + * + * @note + * If the buffer submit fails for any reason the user has retained ownership of the buffer. + * + * @param portId @ref IxEthAccPortId [in] - MAC port ID to transmit Ethernet frame on. + * @param buffer @ref IX_OSAL_MBUF [in] - pointer to an MBUF formatted buffer. Chained buffers are supported for transmission. + * Chained packets are not supported and the field IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR is ignored. + * @param priority @ref IxEthAccTxPriority [in] + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_FAIL : Failed to queue frame for transmission. + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ + +PUBLIC IxEthAccStatus ixEthAccPortTxFrameSubmit( + IxEthAccPortId portId, + IX_OSAL_MBUF *buffer, + IxEthAccTxPriority priority); + +/** + * @ingroup IxEthAcc + * + * @brief Function prototype for Ethernet Tx Buffer Done callback. Registered + * via @a ixEthAccTxBufferDoneCallbackRegister + * + * This function is called once the previously submitted buffer is no longer required by this service. + * It may be returned upon successful transmission of the frame or during the shutdown of + * the port prior to the transmission of a queued frame. + * The calling of this registered function is not a guarantee of successful transmission of the buffer. + * + * + * @li Reentrant - yes , The user provided function should be reentrant. + * @li ISR Callable - yes , The user provided function must be callable from an ISR. + * + * + * Calling Context : + * @par + * This callback is called in the context of the queue manager dispatch loop @a ixQmgrgrDispatcherLoopRun + * within the @ref IxQMgrAPI component. The calling context may be from interrupt or high priority thread. + * The decision is system specific. + * + * @param callbackTag UINT32 [in] - This tag is that provided when the callback was registered for a particular MAC + * via @a ixEthAccPortTxDoneCallbackRegister. It allows the same callback to be used for multiple MACs. + * @param mbuf @ref IX_OSAL_MBUF [in] - Pointer to the Tx mbuf descriptor. + * + * @return void + * + * @note + * The field IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR is modified by the access layer and reset to NULL. + * + *
+ */ +typedef void (*IxEthAccPortTxDoneCallback) ( UINT32 callbackTag, IX_OSAL_MBUF *buffer ); + + + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortTxDoneCallbackRegister( IxEthAccPortId portId, + IxEthAccPortTxDoneCallback txCallbackFn, + UINT32 callbackTag) + * + * @brief Register a callback function to allow + * the transmitted buffers to return to the user. + * + * This function registers the transmit buffer done function callback for a particular port. + * + * The registered callback function is called once the previously submitted buffer is no longer required by this service. + * It may be returned upon successful transmission of the frame or shutdown of port prior to submission. + * The calling of this registered function is not a guarantee of successful transmission of the buffer. + * + * If called several times the latest callback shall be registered for a particular port. + * + * @li Reentrant - yes + * @li ISR Callable - yes + * + * @pre + * The port must be initialized via @a ixEthAccPortInit + * + * + * @param portId @ref IxEthAccPortId [in] - Register callback for a particular MAC device. + * @param txCallbackFn @ref IxEthAccPortTxDoneCallback [in] - Function to be called to return transmit buffers to the user. + * @param callbackTag UINT32 [in] - This tag shall be provided to the callback function. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * @li @a IX_ETH_ACC_INVALID_ARG : An argument other than portId is invalid. + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortTxDoneCallbackRegister(IxEthAccPortId portId, + IxEthAccPortTxDoneCallback txCallbackFn, + UINT32 callbackTag); + + + +/** + * @ingroup IxEthAcc + * + * @brief Function prototype for Ethernet Frame Rx callback. Registered via @a ixEthAccPortRxCallbackRegister + * + * It is the responsibility of the user function to free any MBUF's which it receives. + * + * @li Reentrant - yes , The user provided function should be reentrant. + * @li ISR Callable - yes , The user provided function must be callable from an ISR. + * @par + * + * This function dispatches frames to the user level + * via the provided function. The invocation shall be made for each + * frame dequeued from the Ethernet QM queue. The user is required to free any MBUF's + * supplied via this callback. In addition the registered callback must free up MBUF's + * from the receive free queue when the port is disabled + * + * If called several times the latest callback shall be registered for a particular port. + * + * Calling Context : + * @par + * This callback is called in the context of the queue manager dispatch loop @a ixQmgrgrDispatcherLoopRun + * within the @ref IxQMgrAPI component. The calling context may be from interrupt or high priority thread. + * The decision is system specific. + * + * + * @param callbackTag UINT32 [in] - This tag is that provided when the callback was registered for a particular MAC + * via @a ixEthAccPortRxCallbackRegister. It allows the same callback to be used for multiple MACs. + * @param mbuf @ref IX_OSAL_MBUF [in] - Pointer to the Rx mbuf header. Mbufs may be chained if + * the frame length is greater than the supplied mbuf length. + * @param reserved [in] - deprecated parameter The information is passed + * thru the IxEthAccNe header destination port ID field + * (@sa IX_ETHACC_NE_DESTPORTID). For backward + * compatibility,the value is equal to IX_ETH_DB_UNKNOWN_PORT (0xff). + * + * @return void + * + * @note + * Buffers may not be filled up to the length supplied in + * @a ixEthAccPortRxFreeReplenish(). The firmware fills + * them to the previous 64 bytes boundary. The user has to be aware + * that the length of the received mbufs may be smaller than the length + * of the supplied mbufs. + * The mbuf header contains the following modified field + * @li @a IX_OSAL_MBUF_PKT_LEN is set in the header of the first mbuf and indicates + * the total frame size + * @li @a IX_OSAL_MBUF_MLEN is set each mbuf header and indicates the payload length + * @li @a IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR contains a pointer to the next + * mbuf, or NULL at the end of a chain. + * @li @a IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR is modified. Its value is reset to NULL + * @li @a IX_OSAL_MBUF_FLAGS contains the bit 4 set for a broadcast packet and the bit 5 + * set for a multicast packet. Other bits are unmodified. + * + *
+ */ +typedef void (*IxEthAccPortRxCallback) (UINT32 callbackTag, IX_OSAL_MBUF *buffer, UINT32 reserved); + +/** + * @ingroup IxEthAcc + * + * @brief Function prototype for Ethernet Frame Rx callback. Registered via @a ixEthAccPortMultiBufferRxCallbackRegister + * + * It is the responsibility of the user function to free any MBUF's which it receives. + * + * @li Reentrant - yes , The user provided function should be reentrant. + * @li ISR Callable - yes , The user provided function must be callable from an ISR. + * @par + * + * This function dispatches many frames to the user level + * via the provided function. The invocation shall be made for multiple frames + * dequeued from the Ethernet QM queue. The user is required to free any MBUF's + * supplied via this callback. In addition the registered callback must free up MBUF's + * from the receive free queue when the port is disabled + * + * If called several times the latest callback shall be registered for a particular port. + * + * Calling Context : + * @par + * This callback is called in the context of the queue manager dispatch loop @a ixQmgrDispatcherLoopRun + * within the @ref IxQMgrAPI component. The calling context may be from interrupt or high priority thread. + * The decision is system specific. + * + * + * @param callbackTag - This tag is that provided when the callback was registered for a particular MAC + * via @a ixEthAccPortMultiBufferRxCallbackRegister. It allows the same callback to be used for multiple MACs. + * @param mbuf - Pointer to an array of Rx mbuf headers. Mbufs + * may be chained if + * the frame length is greater than the supplied mbuf length. + * The end of the array contains a zeroed entry (NULL pointer). + * + * @return void + * + * @note The mbufs passed to this callback have the same structure than the + * buffers passed to @a IxEthAccPortRxCallback interfac. + * + * @note The usage of this callback is exclusive with the usage of + * @a ixEthAccPortRxCallbackRegister and @a IxEthAccPortRxCallback + * + * @sa ixEthAccPortMultiBufferRxCallbackRegister + * @sa IxEthAccPortMultiBufferRxCallback + * @sa ixEthAccPortRxCallbackRegister + * @sa IxEthAccPortRxCallback + *
+ */ + +typedef void (*IxEthAccPortMultiBufferRxCallback) (UINT32 callbackTag, IX_OSAL_MBUF **buffer); + + + + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortRxCallbackRegister( IxEthAccPortId portId, IxEthAccPortRxCallback rxCallbackFn, UINT32 callbackTag) + * + * @brief Register a callback function to allow + * the reception of frames. + * + * The registered callback function is called once a frame is received by this service. + * + * If called several times the latest callback shall be registered for a particular port. + * + * + * @li Reentrant - yes + * @li ISR Callable - yes + * + * + * @param portId @ref IxEthAccPortId [in] - Register callback for a particular MAC device. + * @param rxCallbackFn @ref IxEthAccPortRxCallback [in] - Function to be called when Ethernet frames are availble. + * @param callbackTag UINT32 [in] - This tag shall be provided to the callback function. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * @li @a IX_ETH_ACC_INVALID_ARG : An argument other than portId is invalid. + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortRxCallbackRegister(IxEthAccPortId portId, + IxEthAccPortRxCallback rxCallbackFn, + UINT32 callbackTag); + + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortMultiBufferRxCallbackRegister( IxEthAccPortId portId, IxEthAccPortMultiBufferRxCallback rxCallbackFn, UINT32 callbackTag) + * + * @brief Register a callback function to allow + * the reception of frames. + * + * The registered callback function is called once a frame is + * received by this service. If many frames are already received, + * the function is called once. + * + * If called several times the latest callback shall be registered for a particular port. + * + * @li Reentrant - yes + * @li ISR Callable - yes + * + * + * @param portId - Register callback for a particular MAC device. + * @param rxCallbackFn - @a IxEthAccMultiBufferRxCallbackFn - Function to be called when Ethernet frames are availble. + * @param callbackTag - This tag shall be provided to the callback function. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * @li @a IX_ETH_ACC_INVALID_ARG : An argument other than portId is invalid. + * + * @sa ixEthAccPortMultiBufferRxCallbackRegister + * @sa IxEthAccPortMultiBufferRxCallback + * @sa ixEthAccPortRxCallbackRegister + * @sa IxEthAccPortRxCallback + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortMultiBufferRxCallbackRegister(IxEthAccPortId portId, + IxEthAccPortMultiBufferRxCallback rxCallbackFn, + UINT32 callbackTag); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortRxFreeReplenish( IxEthAccPortId portId, IX_OSAL_MBUF *buffer) + * + * @brief This function provides buffers for the Ethernet receive path. + * + * This component does not have a buffer management mechanisms built in. All Rx buffers must be supplied to it + * via this interface. + * + * @li Reentrant - yes + * @li ISR Callable - yes + * + * @param portId @ref IxEthAccPortId [in] - Provide buffers only to specific Rx MAC. + * @param buffer @ref IX_OSAL_MBUF [in] - Provide an MBUF to the Ethernet receive mechanism. + * Buffers size smaller than IX_ETHACC_RX_MBUF_MIN_SIZE may result in poor + * performances and excessive buffer chaining. Buffers + * larger than this size may be suitable for jumbo frames. + * Chained packets are not supported and the field IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR must be NULL. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_FAIL : Buffer has was not able to queue the + * buffer in the receive service. + * @li @a IX_ETH_ACC_FAIL : Buffer size is less than IX_ETHACC_RX_MBUF_MIN_SIZE + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + * @note + * If the buffer replenish operation fails it is the responsibility + * of the user to free the buffer. + * + * @note + * Sufficient buffers must be supplied to the component to maintain + * receive throughput and avoid rx buffer underflow conditions. + * To meet this goal, It is expected that the user preload the + * component with a sufficent number of buffers prior to enabling the + * NPE Ethernet receive path. The recommended minimum number of + * buffers is 8. + * + * @note + * For maximum performances, the mbuf size should be greater + * than the maximum frame size (Ethernet header, payload and FCS) + 64. + * Supplying smaller mbufs to the service results in mbuf + * chaining and degraded performances. The recommended size + * is @a IX_ETHACC_RX_MBUF_MIN_SIZE, which is + * enough to take care of 802.3 frames and "baby jumbo" frames without + * chaining, and "jumbo" frame within chaining. + * + * @note + * Buffers may not be filled up to their length. The firware fills + * them up to the previous 64 bytes boundary. The user has to be aware + * that the length of the received mbufs may be smaller than the length + * of the supplied mbufs. + * + * @warning This function checks the parameters if the NDEBUG + * flag is not defined. Turning on the argument checking (disabled by + * default) results in a lower EthAcc performance as this function + * is part of the data path. + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortRxFreeReplenish( IxEthAccPortId portId, IX_OSAL_MBUF *buffer); + + + +/*************************************************************** + + #### #### # # ##### ##### #### # + # # # # ## # # # # # # # + # # # # # # # # # # # # + # # # # # # # ##### # # # + # # # # # ## # # # # # # + #### #### # # # # # #### ###### + + + ##### # ## # # ###### + # # # # # ## # # + # # # # # # # # ##### + ##### # ###### # # # # + # # # # # ## # + # ###### # # # # ###### + +***************************************************************/ + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortEnable(IxEthAccPortId portId) + * + * @brief This enables an Ethernet port for both Tx and Rx. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @pre The port must first be initialized via @a ixEthAccPortInit and the MAC address + * must be set using @a ixEthAccUnicastMacAddressSet before enabling it + * The rx and Tx Done callbacks registration via @a + * ixEthAccPortTxDoneCallbackRegister amd @a ixEthAccPortRxCallbackRegister + * has to be done before enabling the traffic. + * + * @param portId @ref IxEthAccPortId [in] - Port id to act upon. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is not initialized + * @li @a IX_ETH_ACC_MAC_UNINITIALIZED : port MAC address is not initialized + * + *
+ */ +PUBLIC IxEthAccStatus ixEthAccPortEnable(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortDisable(IxEthAccPortId portId) + * + * @brief This disables an Ethernet port for both Tx and Rx. + * + * Free MBufs are returned to the user via the registered callback when the port is disabled + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @pre The port must be enabled with @a ixEthAccPortEnable, otherwise this + * function has no effect + * + * @param portId @ref IxEthAccPortId [in] - Port id to act upon. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is not initialized + * @li @a IX_ETH_ACC_MAC_UNINITIALIZED : port MAC address is not initialized + * + *
+ */ +PUBLIC IxEthAccStatus ixEthAccPortDisable(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortEnabledQuery(IxEthAccPortId portId, BOOL *enabled) + * + * @brief Get the enabled state of a port. + * + * @li Reentrant - yes + * @li ISR Callable - yes + * + * @pre The port must first be initialized via @a ixEthAccPortInit + * + * @param portId @ref IxEthAccPortId [in] - Port id to act upon. + * @param enabled BOOL [out] - location to store the state of the port + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortEnabledQuery(IxEthAccPortId portId, BOOL *enabled); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortPromiscuousModeClear(IxEthAccPortId portId) + * + * @brief Put the Ethernet MAC device in non-promiscuous mode. + * + * In non-promiscuous mode the MAC filters all frames other than + * destination MAC address which matches the following criteria: + * @li Unicast address provisioned via @a ixEthAccUnicastMacAddressSet + * @li All broadcast frames. + * @li Multicast addresses provisioned via @a ixEthAccMulticastAddressJoin + * + * Other functions modify the MAC filtering + * + * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast + * frames are forwarded to the application + * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the + * effects of @a ixEthAccPortMulticastAddressJoinAll() + * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new + * filtering address + * @li @a ixEthAccPortMulticastAddressJoin() - provision a new + * filtering address + * @li @a ixEthAccPortPromiscuousModeSet() - all frames are + * forwarded to the application regardless of the multicast + * address provisioned + * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded + * to the application following the multicast address provisioned + * + * In all cases, unicast and broadcast addresses are forwarded to + * the application. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @sa ixEthAccPortPromiscuousModeSet + * + * @param portId @ref IxEthAccPortId [in] - Ethernet port id. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus ixEthAccPortPromiscuousModeClear(IxEthAccPortId portId); + + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortPromiscuousModeSet(IxEthAccPortId portId) + * + * @brief Put the MAC device in promiscuous mode. + * + * If the device is in promiscuous mode then all all received frames shall be forwared + * to the NPE for processing. + * + * Other functions modify the MAC filtering + * + * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast + * frames are forwarded to the application + * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the + * effects of @a ixEthAccPortMulticastAddressJoinAll() + * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new + * filtering address + * @li @a ixEthAccPortMulticastAddressJoin() - provision a new + * filtering address + * @li @a ixEthAccPortPromiscuousModeSet() - all frames are + * forwarded to the application regardless of the multicast + * address provisioned + * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded + * to the application following the multicast address provisioned + * + * In all cases, unicast and broadcast addresses are forwarded to + * the application. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @sa ixEthAccPortPromiscuousModeClear + * + * @param portId @ref IxEthAccPortId [in] - Ethernet port id. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus ixEthAccPortPromiscuousModeSet(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortUnicastMacAddressSet( IxEthAccPortId portId, + IxEthAccMacAddr *macAddr) + * + * @brief Configure unicast MAC address for a particular port + * + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @param portId @ref IxEthAccPortId [in] - Ethernet port id. + * @param *macAddr @ref IxEthAccMacAddr [in] - Ethernet Mac address. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus ixEthAccPortUnicastMacAddressSet(IxEthAccPortId portId, + IxEthAccMacAddr *macAddr); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortUnicastMacAddressGet( IxEthAccPortId portId, + IxEthAccMacAddr *macAddr) + * + * @brief Get unicast MAC address for a particular MAC port + * + * @pre + * The MAC address must first be set via @a ixEthAccMacPromiscuousModeSet + * If the MAC address has not been set, the function returns a + * IX_ETH_ACC_MAC_UNINITIALIZED status + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @param portId @ref IxEthAccPortId [in] - Ethernet port id. + * @param *macAddr @ref IxEthAccMacAddr [out] - Ethernet MAC address. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_MAC_UNINITIALIZED : port MAC address is not initialized. + * @li @a IX_ETH_ACC_FAIL : macAddr is invalid. + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortUnicastMacAddressGet(IxEthAccPortId portId, + IxEthAccMacAddr *macAddr); + + + + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortMulticastAddressJoin( IxEthAccPortId portId, + IxEthAccMacAddr *macAddr) + * + * @brief Add a multicast address to the MAC address table. + * + * @note + * Due to the operation of the Ethernet MAC multicast filtering mechanism, frames which do not + * have a multicast destination address which were provisioned via this API may be forwarded + * to the NPE's. This is a result of the hardware comparison algorithm used in the destination mac address logic + * within the Ethernet MAC. + * + * See Also: IXP425 hardware development manual. + * + * Other functions modify the MAC filtering + * + * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast + * frames are forwarded to the application + * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the + * effects of @a ixEthAccPortMulticastAddressJoinAll() + * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new + * filtering address + * @li @a ixEthAccPortMulticastAddressJoin() - provision a new + * filtering address + * @li @a ixEthAccPortPromiscuousModeSet() - all frames are + * forwarded to the application regardless of the multicast + * address provisioned + * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded + * to the application following the multicast address provisioned + * + * In all cases, unicast and broadcast addresses are forwarded to + * the application. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @param portId @ref IxEthAccPortId [in] - Ethernet port id. + * @param *macAddr @ref IxEthAccMacAddr [in] - Ethernet Mac address. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_FAIL : Error writing to the MAC registers + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortMulticastAddressJoin(IxEthAccPortId portId, + IxEthAccMacAddr *macAddr); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortMulticastAddressJoinAll( IxEthAccPortId portId) + * + * @brief Filter all frames with multicast dest. + * + * This function clears the MAC address table, and then sets + * the MAC to forward ALL multicast frames to the NPE. + * Specifically, it forwards all frames whose destination address + * has the LSB of the highest byte set (01:00:00:00:00:00). This + * bit is commonly referred to as the "multicast bit". + * Broadcast frames will still be forwarded. + * + * Other functions modify the MAC filtering + * + * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast + * frames are forwarded to the application + * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the + * effects of @a ixEthAccPortMulticastAddressJoinAll() + * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new + * filtering address + * @li @a ixEthAccPortMulticastAddressJoin() - provision a new + * filtering address + * @li @a ixEthAccPortPromiscuousModeSet() - all frames are + * forwarded to the application regardless of the multicast + * address provisioned + * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded + * to the application following the multicast address provisioned + * + * In all cases, unicast and broadcast addresses are forwarded to + * the application. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @param portId @ref IxEthAccPortId [in] - Ethernet port id. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortMulticastAddressJoinAll(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortMulticastAddressLeave( IxEthAccPortId portId, + IxEthAccMacAddr *macAddr) + * + * @brief Remove a multicast address from the MAC address table. + * + * Other functions modify the MAC filtering + * + * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast + * frames are forwarded to the application + * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the + * effects of @a ixEthAccPortMulticastAddressJoinAll() + * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new + * filtering address + * @li @a ixEthAccPortMulticastAddressJoin() - provision a new + * filtering address + * @li @a ixEthAccPortPromiscuousModeSet() - all frames are + * forwarded to the application regardless of the multicast + * address provisioned + * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded + * to the application following the multicast address provisioned + * + * In all cases, unicast and broadcast addresses are forwarded to + * the application. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @param portId @ref IxEthAccPortId [in] - Ethernet port id. + * @param *macAddr @ref IxEthAccMacAddr [in] - Ethernet Mac address. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_NO_SUCH_ADDR : Failed if MAC address was not in the table. + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortMulticastAddressLeave(IxEthAccPortId portId, + IxEthAccMacAddr *macAddr); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortMulticastAddressLeaveAll( IxEthAccPortId portId) + * + * @brief This function unconfigures the multicast filtering settings + * + * This function first clears the MAC address table, and then sets + * the MAC as configured by the promiscuous mode current settings. + * + * Other functions modify the MAC filtering + * + * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast + * frames are forwarded to the application + * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the + * effects of @a ixEthAccPortMulticastAddressJoinAll() + * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new + * filtering address + * @li @a ixEthAccPortMulticastAddressJoin() - provision a new + * filtering address + * @li @a ixEthAccPortPromiscuousModeSet() - all frames are + * forwarded to the application regardless of the multicast + * address provisioned + * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded + * to the application following the multicast address provisioned + * + * In all cases, unicast and broadcast addresses are forwarded to + * the application. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @param portId @ref IxEthAccPortId [in] - Ethernet port id. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortMulticastAddressLeaveAll(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortUnicastAddressShow(IxEthAccPortId portId) + * + * @brief Displays unicast MAC address + * + * Displays unicast address which is configured using + * @a ixEthAccUnicastMacAddressSet. This function also displays the MAC filter used + * to filter multicast frames. + * + * Other functions modify the MAC filtering + * + * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast + * frames are forwarded to the application + * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the + * effects of @a ixEthAccPortMulticastAddressJoinAll() + * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new + * filtering address + * @li @a ixEthAccPortMulticastAddressJoin() - provision a new + * filtering address + * @li @a ixEthAccPortPromiscuousModeSet() - all frames are + * forwarded to the application regardless of the multicast + * address provisioned + * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded + * to the application following the multicast address provisioned + * + * In all cases, unicast and broadcast addresses are forwarded to + * the application. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @param portId @ref IxEthAccPortId [in] - Ethernet port id. + * + * @return void + * + *
+ */ +PUBLIC IxEthAccStatus ixEthAccPortUnicastAddressShow(IxEthAccPortId portId); + + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortMulticastAddressShow( IxEthAccPortId portId) + * + * @brief Displays multicast MAC address + * + * Displays multicast address which have been configured using @a ixEthAccMulticastAddressJoin + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @param portId @ref IxEthAccPortId [in] - Ethernet port id. + * + * @return void + * + *
+ */ +PUBLIC void ixEthAccPortMulticastAddressShow( IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortDuplexModeSet( IxEthAccPortId portId, IxEthAccDuplexMode mode ) + * + * @brief Set the duplex mode for the MAC. + * + * Configure the IXP400 MAC to either full or half duplex. + * + * @note + * The configuration should match that provisioned on the PHY. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @param portId @ref IxEthAccPortId [in] + * @param mode @ref IxEthAccDuplexMode [in] + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortDuplexModeSet(IxEthAccPortId portId,IxEthAccDuplexMode mode); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortDuplexModeGet( IxEthAccPortId portId, IxEthAccDuplexMode *mode ) + * + * @brief Get the duplex mode for the MAC. + * + * return the duplex configuration of the IXP400 MAC. + * + * @note + * The configuration should match that provisioned on the PHY. + * See @a ixEthAccDuplexModeSet + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @param portId @ref IxEthAccPortId [in] + * @param *mode @ref IxEthAccDuplexMode [out] + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ * + */ +PUBLIC IxEthAccStatus +ixEthAccPortDuplexModeGet(IxEthAccPortId portId,IxEthAccDuplexMode *mode ); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortTxFrameAppendPaddingEnable( IxEthAccPortId portId) + * + * @brief Enable padding bytes to be appended to runt frames submitted to + * this port + * + * Enable up to 60 null-bytes padding bytes to be appended to runt frames + * submitted to this port. This is the default behavior of the access + * component. + * + * @warning Do not change this behaviour while the port is enabled. + * + * @note When Tx padding is enabled, Tx FCS generation is turned on + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @sa ixEthAccPortTxFrameAppendFCSDusable + * + * @param portId @ref IxEthAccPortId [in] + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortTxFrameAppendPaddingEnable(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortTxFrameAppendPaddingDisable( IxEthAccPortId portId) + * + * @brief Disable padding bytes to be appended to runt frames submitted to + * this port + * + * Disable padding bytes to be appended to runt frames + * submitted to this port. This is not the default behavior of the access + * component. + * + * @warning Do not change this behaviour while the port is enabled. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @param portId @ref IxEthAccPortId [in] + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortTxFrameAppendPaddingDisable(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortTxFrameAppendFCSEnable( IxEthAccPortId portId) + * + * @brief Enable the appending of Ethernet FCS to all frames submitted to this port + * + * When enabled, the FCS is added to the submitted frames. This is the default + * behavior of the access component. + * Do not change this behaviour while the port is enabled. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @param portId @ref IxEthAccPortId [in] + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortTxFrameAppendFCSEnable(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortTxFrameAppendFCSDisable( IxEthAccPortId portId) + * + * @brief Disable the appending of Ethernet FCS to all frames submitted to this port. + * + * When disabled, the Ethernet FCS is not added to the submitted frames. + * This is not the default + * behavior of the access component. + * + * @note Since the FCS is not appended to the frame it is expected that the frame submitted to the + * component includes a valid FCS at the end of the data, although this will not be validated. + * + * The component shall forward the frame to the Ethernet MAC WITHOUT modification. + * + * Do not change this behaviour while the port is enabled. + * + * @note Tx FCS append is not disabled while Tx padding is enabled. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @sa ixEthAccPortTxFrameAppendPaddingEnable + * + * @param portId @ref IxEthAccPortId [in] + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortTxFrameAppendFCSDisable(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortRxFrameAppendFCSEnable( IxEthAccPortId portId) + * + * @brief Forward frames with FCS included in the receive buffer. + * + * The FCS is not striped from the receive buffer. + * The received frame length includes the FCS size (4 bytes). ie. + * A minimum sized ethernet frame shall have a length of 64bytes. + * + * Frame FCS validity checks are still carried out on all received frames. + * + * This is not the default + * behavior of the access component. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @param portId @ref IxEthAccPortId [in] + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortRxFrameAppendFCSEnable(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortRxFrameAppendFCSDisable( IxEthAccPortId portId) + * + * @brief Do not forward the FCS portion of the received Ethernet frame to the user. + * The FCS is striped from the receive buffer. + * The received frame length does not include the FCS size (4 bytes). + * Frame FCS validity checks are still carried out on all received frames. + * + * This is the default behavior of the component. + * Do not change this behaviour while the port is enabled. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @param portId @ref IxEthAccPortId [in] + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortRxFrameAppendFCSDisable(IxEthAccPortId portId); + + + + +/** + * @ingroup IxEthAcc + * + * @enum IxEthAccSchedulerDiscipline + * + * @brief Definition for the port scheduling discipline + * + * Select the port scheduling discipline on receive and transmit path + * @li FIFO : No Priority : In this configuration all frames are processed + * in the access component in the strict order in which + * the component received them. + * @li FIFO : Priority : This shall be a very simple priority mechanism. + * Higher prior-ity frames shall be forwarded + * before lower priority frames. There shall be no + * fairness mechanisms applied across different + * priorities. Higher priority frames could starve + * lower priority frames indefinitely. + */ +typedef enum +{ + FIFO_NO_PRIORITY, /** + */ +PUBLIC IxEthAccStatus +ixEthAccTxSchedulingDisciplineSet(IxEthAccPortId portId, + IxEthAccSchedulerDiscipline sched); + + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccRxSchedulingDisciplineSet(IxEthAccSchedulerDiscipline sched) + * + * @brief Set the Rx scheduling to one of @a IxEthAccSchedulerDiscipline + * + * The default behavior of the component is @a FIFO_NO_PRIORITY. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @pre + * + * @param sched : @a IxEthAccSchedulerDiscipline + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS : Set appropriate discipline. + * @li @a IX_ETH_ACC_FAIL : Invalid/unsupported discipline. + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccRxSchedulingDisciplineSet(IxEthAccSchedulerDiscipline sched); + +/** + * @ingroup IxEthAcc + * + * @fn IxEthAccStatus ixEthAccNpeLoopbackEnable(IxEthAccPortId portId) + * + * @brief Enable NPE loopback + * + * When this loopback mode is enabled all the transmitted frames are + * received on the same port, without payload. + * + * This function is recommended for power-up diagnostic checks and + * should never be used under normal Ethernet traffic operations. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @pre + * + * @param portId : ID of the port + * + * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is + * guaranteed to restore correct Ethernet Tx/Rx operation. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS : NPE loopback mode enabled + * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortNpeLoopbackEnable(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn IxEthAccStatus ixEthAccPortNpeLoopbackDisable(IxEthAccPortId portId) + * + * @brief Disable NPE loopback + * + * This function is used to disable the NPE loopback if previously + * enabled using ixEthAccNpeLoopbackEnable. + * + * This function is recommended for power-up diagnostic checks and + * should never be used under normal Ethernet traffic operations. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @pre + * + * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is + * guaranteed to restore correct Ethernet Tx/Rx operation. + * + * @param portId : ID of the port + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS : NPE loopback successfully disabled + * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortNpeLoopbackDisable(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn IxEthAccStatus ixEthAccPortTxEnable(IxEthAccPortId portId) + * + * @brief Enable Tx on the port + * + * This function is the complement of ixEthAccPortTxDisable and should + * be used only after Tx was disabled. A MAC core reset is required before + * this function is called (see @a ixEthAccPortMacReset). + * + * This function is the recommended usage scenario for emergency security + * shutdown and hardware failure recovery and should never be used for throttling + * traffic. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @pre + * + * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is + * guaranteed to restore correct Ethernet Tx/Rx operation. + * + * @param portId : ID of the port + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS : Tx successfully enabled + * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortTxEnable(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn IxEthAccStatus ixEthAccPortTxDisable(IxEthAccPortId portId) + * + * @brief Disable Tx on the port + * + * This function can be used to disable Tx in the MAC core. + * Tx can be re-enabled, although this is not guaranteed, by performing + * a MAC core reset (@a ixEthAccPortMacReset) and calling ixEthAccPortTxEnable. + * Note that using this function is not recommended, except for shutting + * down Tx for emergency reasons. For proper port shutdown and re-enabling + * see ixEthAccPortEnable and ixEthAccPortDisable. + * + * This function is the recommended usage scenario for emergency security + * shutdown and hardware failure recovery and should never be used for throttling + * traffic. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is + * guaranteed to restore correct Ethernet Tx/Rx operation. + * + * @pre + * + * @param portId : ID of the port + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS : Tx successfully disabled + * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortTxDisable(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn IxEthAccStatus ixEthAccPortRxEnable(IxEthAccPortId portId) + * + * @brief Enable Rx on the port + * + * This function is the complement of ixEthAccPortRxDisable and should + * be used only after Rx was disabled. + * + * This function is the recommended usage scenario for emergency security + * shutdown and hardware failure recovery and should never be used for throttling + * traffic. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is + * guaranteed to restore correct Ethernet Tx/Rx operation. + * + * @pre + * + * @param portId : ID of the port + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS : Rx successfully enabled + * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortRxEnable(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn IxEthAccStatus ixEthAccPortRxDisable(IxEthAccPortId portId) + * + * @brief Disable Rx on the port + * + * This function can be used to disable Rx in the MAC core. + * Rx can be re-enabled, although this is not guaranteed, by performing + * a MAC core reset (@a ixEthAccPortMacReset) and calling ixEthAccPortRxEnable. + * Note that using this function is not recommended, except for shutting + * down Rx for emergency reasons. For proper port shutdown and re-enabling + * see ixEthAccPortEnable and ixEthAccPortDisable. + * + * This function is the recommended usage scenario for emergency security + * shutdown and hardware failure recovery and should never be used for throttling + * traffic. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @pre + * + * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is + * guaranteed to restore correct Ethernet Tx/Rx operation. + * + * @param portId : ID of the port + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS : Rx successfully disabled + * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortRxDisable(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn IxEthAccStatus ixEthAccPortMacReset(IxEthAccPortId portId) + * + * @brief Reset MAC core on the port + * + * This function will perform a MAC core reset (NPE Ethernet coprocessor). + * This function is inherently unsafe and the NPE recovery is not guaranteed + * after this function is called. The proper manner of performing port disable + * and enable (which will reset the MAC as well) is ixEthAccPortEnable/ixEthAccPortDisable. + * + * This function is the recommended usage scenario for hardware failure recovery + * and should never be used for throttling traffic. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @pre + * + * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is + * guaranteed to restore correct Ethernet Tx/Rx operation. + * + * @param portId : ID of the port + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS : MAC core reset + * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortMacReset(IxEthAccPortId portId); + +/********************************************************************************* + #### ##### ## ##### # #### ##### # #### #### + # # # # # # # # # # # # + #### # # # # # #### # # # #### + # # ###### # # # # # # # + # # # # # # # # # # # # # # # + #### # # # # # #### # # #### #### +**********************************************************************************/ + + +/** + * + * @brief This struct defines the statistics returned by this component. + * + * The component returns MIB2 EthObj variables which are obtained from the + * hardware or maintained by this component. + * + * + */ +typedef struct +{ + UINT32 dot3StatsAlignmentErrors; /**< link error count (rx) */ + UINT32 dot3StatsFCSErrors; /**< link error count (rx) */ + UINT32 dot3StatsInternalMacReceiveErrors; /**< link error count (rx) */ + UINT32 RxOverrunDiscards; /**< NPE: discarded frames count (rx) */ + UINT32 RxLearnedEntryDiscards; /**< NPE: discarded frames count(rx) */ + UINT32 RxLargeFramesDiscards; /**< NPE: discarded frames count(rx) */ + UINT32 RxSTPBlockedDiscards; /**< NPE: discarded frames count(rx) */ + UINT32 RxVLANTypeFilterDiscards; /**< NPE: discarded frames count (rx) */ + UINT32 RxVLANIdFilterDiscards; /**< NPE: discarded frames count (rx) */ + UINT32 RxInvalidSourceDiscards; /**< NPE: discarded frames count (rx) */ + UINT32 RxBlackListDiscards; /**< NPE: discarded frames count (rx) */ + UINT32 RxWhiteListDiscards; /**< NPE: discarded frames count (rx) */ + UINT32 RxUnderflowEntryDiscards; /**< NPE: discarded frames count (rx) */ + UINT32 dot3StatsSingleCollisionFrames; /**< link error count (tx) */ + UINT32 dot3StatsMultipleCollisionFrames; /**< link error count (tx) */ + UINT32 dot3StatsDeferredTransmissions; /**< link error count (tx) */ + UINT32 dot3StatsLateCollisions; /**< link error count (tx) */ + UINT32 dot3StatsExcessiveCollsions; /**< link error count (tx) */ + UINT32 dot3StatsInternalMacTransmitErrors; /**< link error count (tx) */ + UINT32 dot3StatsCarrierSenseErrors; /**< link error count (tx) */ + UINT32 TxLargeFrameDiscards; /**< NPE: discarded frames count (tx) */ + UINT32 TxVLANIdFilterDiscards; /**< NPE: discarded frames count (tx) */ + +}IxEthEthObjStats; + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccMibIIStatsGet(IxEthAccPortId portId ,IxEthEthObjStats *retStats ) + * + * @brief Returns the statistics maintained for a port. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @pre + * + * + * @param portId @ref IxEthAccPortId [in] + * @param retStats @ref IxEthEthObjStats [out] + * @note Please note the user is responsible for cache coheriency of the retStat + * buffer. The data is actually populated via the NPE's. As such cache safe + * memory should be used in the retStats argument. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_FAIL : Invalid arguments. + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccMibIIStatsGet(IxEthAccPortId portId, IxEthEthObjStats *retStats ); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccMibIIStatsGetClear(IxEthAccPortId portId, IxEthEthObjStats *retStats) + * + * @brief Returns and clears the statistics maintained for a port. + * + * @li Reentrant - yes + * @li ISR Callable - yes + * + * @pre + * + * @param portId @ref IxEthAccPortId [in] + * @param retStats @ref IxEthEthObjStats [out] + * @note Please note the user is responsible for cache coheriency of the retStats + * buffer. The data is actually populated via the NPE's. As such cache safe + * memory should be used in the retStats argument. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_FAIL : invalid arguments. + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccMibIIStatsGetClear(IxEthAccPortId portId, IxEthEthObjStats *retStats); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccMibIIStatsClear(IxEthAccPortId portId) + * + * @brief Clears the statistics maintained for a port. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @pre + * + * @param portId @ref IxEthAccPortId [in] + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_FAIL : Invalid arguments. + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus ixEthAccMibIIStatsClear(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccMacInit(IxEthAccPortId portId) + * + * @brief Initializes the ethernet MAC settings + * + * @li Reentrant - no + * @li ISR Callable - no + * + * @param portId @ref IxEthAccPortId [in] + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * + *
+ */ +PUBLIC IxEthAccStatus ixEthAccMacInit(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccStatsShow(IxEthAccPortId portId) + * + * + * @brief Displays a ports statistics on the standard io console using printf. + * + * @li Reentrant - no + * @li ISR Callable - no + * + * @pre + * + * @param portId @ref IxEthAccPortId [in] + * + * @return void + * + *
+ */ +PUBLIC void ixEthAccStatsShow(IxEthAccPortId portId); + +/************************************************************************* + + # # # # # # ##### # #### + ## ## # # ## ## # # # # # + # ## # # # # ## # # # # # # + # # # # # # # # # # # + # # # # # # # # # # # + # # # # # # ##### # #### + +*************************************************************************/ + + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccMiiReadRtn (UINT8 phyAddr, + UINT8 phyReg, + UINT16 *value) + * + * + * @brief Reads a 16 bit value from a PHY + * + * Reads a 16-bit word from a register of a MII-compliant PHY. Reading + * is performed through the MII management interface. This function returns + * when the read operation has successfully completed, or when a timeout has elapsed. + * + * @li Reentrant - no + * @li ISR Callable - no + * + * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock. + * + * @param phyAddr UINT8 [in] - the address of the Ethernet PHY (0-31) + * @param phyReg UINT8 [in] - the number of the MII register to read (0-31) + * @param value UINT16 [in] - the value read from the register + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_FAIL : failed to read the register. + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccMiiReadRtn (UINT8 phyAddr, UINT8 phyReg, UINT16 *value); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccMiiWriteRtn (UINT8 phyAddr, + UINT8 phyReg, + UINT16 value) + * + * + * @brief Writes a 16 bit value to a PHY + * + * Writes a 16-bit word from a register of a MII-compliant PHY. Writing + * is performed through the MII management interface. This function returns + * when the write operation has successfully completed, or when a timeout has elapsed. + * + * @li Reentrant - no + * @li ISR Callable - no + * + * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock. + * + * @param phyAddr UINT8 [in] - the address of the Ethernet PHY (0-31) + * @param phyReg UINT8 [in] - the number of the MII register to write (0-31) + * @param value UINT16 [out] - the value to write to the register + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_FAIL : failed to write register. + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccMiiWriteRtn (UINT8 phyAddr, UINT8 phyReg, UINT16 value); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccMiiAccessTimeoutSet(UINT32 timeout) + * + * @brief Overrides the default timeout value and retry count when reading or + * writing MII registers using ixEthAccMiiWriteRtn or ixEthAccMiiReadRtn + * + * The default behavior of the component is to use a IX_ETH_ACC_MII_10TH_SEC_IN_MILLIS ms + * timeout (declared as 100 in IxEthAccMii_p.h) and a retry count of IX_ETH_ACC_MII_TIMEOUT_10TH_SECS + * (declared as 5 in IxEthAccMii_p.h). + * + * The MII read and write functions will attempt to read the status of the register up + * to the retry count times, delaying between each attempt with the timeout value. + * + * @li Reentrant - no + * @li ISR Callable - no + * + * @pre + * + * @param timeout UINT32 [in] - new timeout value, in milliseconds + * @param timeout UINT32 [in] - new retry count (a minimum value of 1 must be used) + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_FAIL : invalid parameter(s) + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccMiiAccessTimeoutSet(UINT32 timeout, UINT32 retryCount); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccMiiStatsShow (UINT32 phyAddr) + * + * + * @brief Displays detailed information on a specified PHY + * + * Displays the current values of the first eigth MII registers for a PHY, + * + * @li Reentrant - no + * @li ISR Callable - no + * + * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and + * generating the MDIO clock. + * + * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31) + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_FAIL : invalid arguments. + * + *
+ */ +PUBLIC IxEthAccStatus ixEthAccMiiStatsShow (UINT32 phyAddr); + + + +/******* BOARD SPECIFIC DEPRECATED API *********/ + +/* The following functions are high level functions which rely + * on the properties and interface of some Ethernet PHYs. The + * implementation is hardware specific and has been moved to + * the hardware-specific component IxEthMii. + */ + + #include "IxEthMii.h" + +/** + * @ingroup IxEthAcc + * + * @def ixEthAccMiiPhyScan + * + * @brief : deprecated API entry point. This definition + * ensures backward compatibility + * + * See @ref ixEthMiiPhyScan + * + * @note this feature is board specific + * + */ +#define ixEthAccMiiPhyScan(phyPresent) ixEthMiiPhyScan(phyPresent,IXP425_ETH_ACC_MII_MAX_ADDR) + +/** + * @ingroup IxEthAcc + * + * @def ixEthAccMiiPhyConfig + * + * @brief : deprecated API entry point. This definition + * ensures backward compatibility + * + * See @ref ixEthMiiPhyConfig + * + * @note this feature is board specific + */ +#define ixEthAccMiiPhyConfig(phyAddr,speed100,fullDuplex,autonegotiate) \ + ixEthMiiPhyConfig(phyAddr,speed100,fullDuplex,autonegotiate) + +/** + * @ingroup IxEthAcc + * + * @def ixEthAccMiiPhyReset + * + * @brief : deprecated API entry point. This definition + * ensures backward compatibility + * + * See @ref ixEthMiiPhyReset + * + * @note this feature is board specific + */ +#define ixEthAccMiiPhyReset(phyAddr) \ + ixEthMiiPhyReset(phyAddr) + +/** + * @ingroup IxEthAcc + * + * @def ixEthAccMiiLinkStatus + * + * @brief : deprecated API entry point. This definition + * ensures backward compatibility + * + * See @ref ixEthMiiLinkStatus + * + * @note this feature is board specific + */ +#define ixEthAccMiiLinkStatus(phyAddr,linkUp,speed100,fullDuplex,autoneg) \ + ixEthMiiLinkStatus(phyAddr,linkUp,speed100,fullDuplex,autoneg) + + + +/** + * @ingroup IxEthAcc + * + * @def ixEthAccMiiShow + * + * @brief : deprecated API entry point. This definition + * ensures backward compatibility + * + * See @ref ixEthMiiPhyShow + * + * @note this feature is board specific + */ +#define ixEthAccMiiShow(phyAddr) \ + ixEthMiiPhyShow(phyAddr) + +#endif /* ndef IxEthAcc_H */ +/** + *@} + */ diff --git a/arch/arm/cpu/ixp/npe/include/IxEthAccDataPlane_p.h b/arch/arm/cpu/ixp/npe/include/IxEthAccDataPlane_p.h new file mode 100644 index 0000000000..8b8e6b256c --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/IxEthAccDataPlane_p.h @@ -0,0 +1,245 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + + + +#ifndef IxEthAccDataPlane_p_H +#define IxEthAccDataPlane_p_H + +#include +#include + +/** + * @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 */ + + +/** + *@} + */ + diff --git a/arch/arm/cpu/ixp/npe/include/IxEthAccMac_p.h b/arch/arm/cpu/ixp/npe/include/IxEthAccMac_p.h new file mode 100644 index 0000000000..93e9d98e76 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/IxEthAccMac_p.h @@ -0,0 +1,248 @@ +/* + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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*/ + diff --git a/arch/arm/cpu/ixp/npe/include/IxEthAccMii_p.h b/arch/arm/cpu/ixp/npe/include/IxEthAccMii_p.h new file mode 100644 index 0000000000..568d4a0fa4 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/IxEthAccMii_p.h @@ -0,0 +1,97 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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*/ diff --git a/arch/arm/cpu/ixp/npe/include/IxEthAccQueueAssign_p.h b/arch/arm/cpu/ixp/npe/include/IxEthAccQueueAssign_p.h new file mode 100644 index 0000000000..e5fd16e2fb --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/IxEthAccQueueAssign_p.h @@ -0,0 +1,137 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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 ) diff --git a/arch/arm/cpu/ixp/npe/include/IxEthAcc_p.h b/arch/arm/cpu/ixp/npe/include/IxEthAcc_p.h new file mode 100644 index 0000000000..0ee4123557 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/IxEthAcc_p.h @@ -0,0 +1,325 @@ +/** + * @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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @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; /**< Recieve 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 */ + + + diff --git a/arch/arm/cpu/ixp/npe/include/IxEthDB.h b/arch/arm/cpu/ixp/npe/include/IxEthDB.h new file mode 100644 index 0000000000..1189c9a140 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/IxEthDB.h @@ -0,0 +1,2373 @@ +/** @file IxEthDB.h + * + * @brief this file contains the public API of @ref IxEthDB component + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + * + */ + +#ifndef IxEthDB_H +#define IxEthDB_H + +#include +#include + +/** + * @defgroup IxEthDB IXP400 Ethernet Database (IxEthDB) API + * + * @brief ethDB is a library that does provides a MAC address database learning/filtering capability + * + *@{ + */ + +#define INLINE __inline__ + +#define IX_ETH_DB_PRIVATE PRIVATE /* imported from IxTypes.h */ + +#define IX_ETH_DB_PUBLIC PUBLIC + +/** + * @brief port ID => message handler NPE id conversion (0 => NPE_B, 1 => NPE_C) + */ +#define IX_ETH_DB_PORT_ID_TO_NPE(id) (id == 0 ? 1 : (id == 1 ? 2 : (id == 2 ? 0 : -1))) + +/** + * @def IX_ETH_DB_NPE_TO_PORT_ID(npe) + * @brief message handler NPE id => port ID conversion (NPE_B => 0, NPE_C => 1) + */ +#define IX_ETH_DB_NPE_TO_PORT_ID(npe) (npe == 0 ? 2 : (npe == 1 ? 0 : (npe == 2 ? 1 : -1))) + +/* temporary define - won't work for Azusa */ +#define IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(id) (IX_ETH_DB_PORT_ID_TO_NPE(id) << 4) +#define IX_ETH_DB_NPE_LOGICAL_ID_TO_PORT_ID(id) (IX_ETH_DB_NPE_TO_PORT_ID(id >> 4)) + +/** + * @def IX_IEEE803_MAC_ADDRESS_SIZE + * @brief The size of the MAC address + */ +#define IX_IEEE803_MAC_ADDRESS_SIZE (6) + +/** + * @def IX_IEEE802_1Q_QOS_PRIORITY_COUNT + * @brief Number of QoS priorities defined by IEEE802.1Q + */ +#define IX_IEEE802_1Q_QOS_PRIORITY_COUNT (8) + +/** + * @enum IxEthDBStatus + * @brief Ethernet Database API return values + */ +typedef enum /* IxEthDBStatus */ +{ + IX_ETH_DB_SUCCESS = IX_SUCCESS, /**< Success */ + IX_ETH_DB_FAIL = IX_FAIL, /**< Failure */ + IX_ETH_DB_INVALID_PORT, /**< Invalid port */ + IX_ETH_DB_PORT_UNINITIALIZED, /**< Port not initialized */ + IX_ETH_DB_MAC_UNINITIALIZED, /**< MAC not initialized */ + IX_ETH_DB_INVALID_ARG, /**< Invalid argument */ + IX_ETH_DB_NO_SUCH_ADDR, /**< Address not found for search or delete operations */ + IX_ETH_DB_NOMEM, /**< Learning database memory full */ + IX_ETH_DB_BUSY, /**< Learning database cannot complete operation, access temporarily blocked */ + IX_ETH_DB_END, /**< Database browser passed the end of the record set */ + IX_ETH_DB_INVALID_VLAN, /**< Invalid VLAN ID (valid range is 0..4094, 0 signifies no VLAN membership, used for priority tagged frames) */ + IX_ETH_DB_INVALID_PRIORITY, /**< Invalid QoS priority/traffic class (valid range for QoS priority is 0..7, valid range for traffic class depends on run-time configuration) */ + IX_ETH_DB_NO_PERMISSION, /**< No permission for attempted operation */ + IX_ETH_DB_FEATURE_UNAVAILABLE, /**< Feature not available (or not enabled) */ + IX_ETH_DB_INVALID_KEY, /**< Invalid search key */ + IX_ETH_DB_INVALID_RECORD_TYPE /**< Invalid record type */ +} IxEthDBStatus; + +/** @brief VLAN ID type, valid range is 0..4094, 0 signifying no VLAN membership */ +typedef UINT32 IxEthDBVlanId; + +/** @brief 802.1Q VLAN tag, contains 3 bits user priority, 1 bit CFI, 12 bits VLAN ID */ +typedef UINT32 IxEthDBVlanTag; + +/** @brief QoS priority/traffic class type, valid range is 0..7, 0 being the lowest */ +typedef UINT32 IxEthDBPriority; + +/** @brief Priority mapping table; 0..7 QoS priorities used to index, table contains traffic classes */ +typedef UINT8 IxEthDBPriorityTable[8]; + +/** @brief A 4096 bit array used to map the complete VLAN ID range */ +typedef UINT8 IxEthDBVlanSet[512]; + +#define IX_ETH_DB_802_1Q_VLAN_MASK (0xFFF) +#define IX_ETH_DB_802_1Q_QOS_MASK (0x7) + +#define IX_ETH_DB_802_1Q_MAX_VLAN_ID (0xFFE) + +/** + * @def IX_ETH_DB_SET_VLAN_ID + * @brief returns the given 802.1Q tag with the VLAN ID field substituted with the given VLAN ID + * + * This macro is used to change the VLAN ID in a 802.1Q tag. + * + * Example: + * + * tag = IX_ETH_DB_SET_VLAN_ID(tag, 32) + * + * inserts the VLAN ID "32" in the given tag. + */ +#define IX_ETH_DB_SET_VLAN_ID(vlanTag, vlanID) (((vlanTag) & 0xF000) | ((vlanID) & IX_ETH_DB_802_1Q_VLAN_MASK)) + +/** +* @def IX_ETH_DB_GET_VLAN_ID +* @brief returns the VLAN ID from the given 802.1Q tag +*/ +#define IX_ETH_DB_GET_VLAN_ID(vlanTag) ((vlanTag) & IX_ETH_DB_802_1Q_VLAN_MASK) + +#define IX_ETH_DB_GET_QOS_PRIORITY(vlanTag) (((vlanTag) >> 13) & IX_ETH_DB_802_1Q_QOS_MASK) + +#define IX_ETH_DB_SET_QOS_PRIORITY(vlanTag, priority) (((vlanTag) & 0x1FFF) | (((priority) & IX_ETH_DB_802_1Q_QOS_MASK) << 13)) + +#define IX_ETH_DB_CHECK_VLAN_TAG(vlanTag) { if(((vlanTag & 0xFFFF0000) != 0) || (IX_ETH_DB_GET_VLAN_ID(vlanTag) > 4094)) return IX_ETH_DB_INVALID_VLAN; } + +#define IX_ETH_DB_CHECK_VLAN_ID(vlanId) { if (vlanId > IX_ETH_DB_802_1Q_MAX_VLAN_ID) return IX_ETH_DB_INVALID_VLAN; } + +#define IX_IEEE802_1Q_VLAN_TPID (0x8100) + +typedef enum +{ + IX_ETH_DB_UNTAGGED_FRAMES = 0x1, /**< Accepts untagged frames */ + IX_ETH_DB_VLAN_TAGGED_FRAMES = 0x2, /**< Accepts tagged frames */ + IX_ETH_DB_PRIORITY_TAGGED_FRAMES = 0x4, /**< Accepts tagged frames with VLAN ID set to 0 (no VLAN membership) */ + IX_ETH_DB_ACCEPT_ALL_FRAMES = + IX_ETH_DB_UNTAGGED_FRAMES | IX_ETH_DB_VLAN_TAGGED_FRAMES /**< Accepts all the frames */ +} IxEthDBFrameFilter; + +typedef enum +{ + IX_ETH_DB_PASS_THROUGH = 0x1, /**< Leave frame as-is */ + IX_ETH_DB_ADD_TAG = 0x2, /**< Add default port VLAN tag */ + IX_ETH_DB_REMOVE_TAG = 0x3 /**< Remove VLAN tag from frame */ +} IxEthDBTaggingAction; + +typedef enum +{ + IX_ETH_DB_FIREWALL_WHITE_LIST = 0x1, /**< Firewall operates in white-list mode (MAC address based admission) */ + IX_ETH_DB_FIREWALL_BLACK_LIST = 0x2 /**< Firewall operates in black-list mode (MAC address based blocking) */ +} IxEthDBFirewallMode; + +typedef enum +{ + IX_ETH_DB_FILTERING_RECORD = 0x01, /**< + *
Filtering record
MAC address static/dynamic type age + *
+ */ + IX_ETH_DB_FILTERING_VLAN_RECORD = 0x02, /**< + *
VLAN-enabled filtering record
MAC address static/dynamic type age 802.1Q tag + *
+ */ + IX_ETH_DB_WIFI_RECORD = 0x04, /**< + *
WiFi header conversion record
MAC address optional gateway MAC address + *
+ */ + IX_ETH_DB_FIREWALL_RECORD = 0x08, /**< + *
Firewall record
MAC address + *
+ */ + IX_ETH_DB_GATEWAY_RECORD = 0x10, /**< For internal use only */ + IX_ETH_DB_MAX_RECORD_TYPE_INDEX = 0x10, /**< For internal use only */ + IX_ETH_DB_NO_RECORD_TYPE = 0, /**< None of the registered record types */ + IX_ETH_DB_ALL_FILTERING_RECORDS = IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD, /**< All the filtering records */ + IX_ETH_DB_ALL_RECORD_TYPES = IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD | + IX_ETH_DB_WIFI_RECORD | IX_ETH_DB_FIREWALL_RECORD /**< All the record types registered within EthDB */ +} IxEthDBRecordType; + +typedef enum +{ + IX_ETH_DB_LEARNING = 0x01, /**< Learning feature; enables EthDB to learn MAC address (filtering) records, including 802.1Q enabled records */ + IX_ETH_DB_FILTERING = 0x02, /**< Filtering feature; enables EthDB to communicate with the NPEs for downloading filtering information in the NPEs; depends on the learning feature */ + IX_ETH_DB_VLAN_QOS = 0x04, /**< VLAN/QoS feature; enables EthDB to configure NPEs to operate in VLAN/QoS aware modes */ + IX_ETH_DB_FIREWALL = 0x08, /**< Firewall feature; enables EthDB to configure NPEs to operate in firewall mode, using white/black address lists */ + IX_ETH_DB_SPANNING_TREE_PROTOCOL = 0x10, /**< Spanning tree protocol feature; enables EthDB to configure the NPEs as STP nodes */ + IX_ETH_DB_WIFI_HEADER_CONVERSION = 0x20 /**< WiFi 802.3 to 802.11 header conversion feature; enables EthDB to handle WiFi conversion data */ +} IxEthDBFeature; + +typedef UINT32 IxEthDBProperty; /**< Property ID type */ + +typedef enum +{ + IX_ETH_DB_INTEGER_PROPERTY = 0x1, /**< 4 byte unsigned integer type */ + IX_ETH_DB_STRING_PROPERTY = 0x2, /**< NULL-terminated string type of maximum 255 characters (including the terminator) */ + IX_ETH_DB_MAC_ADDR_PROPERTY = 0x3, /**< 6 byte MAC address type */ + IX_ETH_DB_BOOL_PROPERTY = 0x4 /**< 4 byte boolean type; can contain only TRUE and FALSE values */ +} IxEthDBPropertyType; + +/* list of supported properties for the IX_ETH_DB_VLAN_QOS feature */ +#define IX_ETH_DB_QOS_TRAFFIC_CLASS_COUNT_PROPERTY (0x01) /**< Property identifying number the supported number of traffic classes */ +#define IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY (0x10) /**< Rx queue assigned to traffic class 0 */ +#define IX_ETH_DB_QOS_TRAFFIC_CLASS_1_RX_QUEUE_PROPERTY (0x11) /**< Rx queue assigned to traffic class 1 */ +#define IX_ETH_DB_QOS_TRAFFIC_CLASS_2_RX_QUEUE_PROPERTY (0x12) /**< Rx queue assigned to traffic class 2 */ +#define IX_ETH_DB_QOS_TRAFFIC_CLASS_3_RX_QUEUE_PROPERTY (0x13) /**< Rx queue assigned to traffic class 3 */ +#define IX_ETH_DB_QOS_TRAFFIC_CLASS_4_RX_QUEUE_PROPERTY (0x14) /**< Rx queue assigned to traffic class 4 */ +#define IX_ETH_DB_QOS_TRAFFIC_CLASS_5_RX_QUEUE_PROPERTY (0x15) /**< Rx queue assigned to traffic class 5 */ +#define IX_ETH_DB_QOS_TRAFFIC_CLASS_6_RX_QUEUE_PROPERTY (0x16) /**< Rx queue assigned to traffic class 6 */ +#define IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY (0x17) /**< Rx queue assigned to traffic class 7 */ + +/* private property used by EthAcc to indicate queue configuration complete */ +#define IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE (0x18) + +/** + * + * @brief The IEEE 802.3 Ethernet MAC address structure. + * + * The data should be packed with bytes xx:xx:xx:xx:xx:xx + * + * @note The data must be packed in network byte order. + */ +typedef struct +{ + UINT8 macAddress[IX_IEEE803_MAC_ADDRESS_SIZE]; +} IxEthDBMacAddr; + +/** + * @ingroup IxEthDB + * + * @brief Definition of an IXP400 port. + */ +typedef UINT32 IxEthDBPortId; + +/** + * @ingroup IxEthDB + * + * @brief Port dependency map definition + */ +typedef UINT8 IxEthDBPortMap[32]; + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBInit(void) + * + * @brief Initializes the Ethernet learning/filtering database + * + * @note calling this function multiple times does not constitute an error; + * redundant calls will be ignored, returning IX_ETH_DB_SUCCESS + * + * @retval IX_ETH_DB_SUCCESS initialization was successful + * @retval IX_ETH_DB_FAIL initialization failed (OS error) + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBInit(void); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBUnload(void) + * + * @brief Stops and prepares the EthDB component for unloading. + * + * @retval IX_ETH_DB_SUCCESS de-initialization was successful + * @retval IX_ETH_DB_BUSY de-initialization failed, ports must be disabled first + * @retval IX_ETH_DB_FAIL de-initialization failed (OS error) + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBUnload(void); + +/** + * @ingroup IxEthDB + * + * @fn void ixEthDBPortInit(IxEthDBPortId portID) + * + * @brief Initializes a port + * + * This function is called automatically by the Ethernet Access + * ixEthAccPortInit() routine for Ethernet NPE ports and should be manually + * called for any user-defined port (any port that is not one of + * the two Ethernet NPEs). + * + * @param portID @ref IxEthDBPortId [in] - ID of the port to be initialized + * + * @see IxEthDBPortDefs.h for port definitions + * + * @note calling this function multiple times does not constitute an error; + * redundant calls will be ignored + */ +IX_ETH_DB_PUBLIC +void ixEthDBPortInit(IxEthDBPortId portID); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPortEnable(IxEthDBPortId portID) + * + * @brief Enables a port + * + * This function is called automatically from the Ethernet Access component + * ixEthAccPortEnable() routine for Ethernet NPE ports and should be manually + * called for any user-defined port (any port that is not one of + * the Ethernet NPEs). + * + * @param portID @ref IxEthDBPortId [in] - ID of the port to enable processing on + * + * @retval IX_ETH_DB_SUCCESS if enabling is successful + * @retval IX_ETH_DB_FAIL if the enabling was not successful due to + * a message handler error + * @retval IX_ETH_DB_MAC_UNINITIALIZED the MAC address of this port was + * not initialized (only for Ethernet NPEs) + * @retval IX_ETH_DB_INVALID_PORT if portID is invalid + * + * @pre ixEthDBPortAddressSet needs to be called prior to enabling the port events + * for Ethernet NPEs + * + * @see ixEthDBPortAddressSet + * + * @see IxEthDBPortDefs.h for port definitions + * + * @note calling this function multiple times does not constitute an error; + * redundant calls will be ignored + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortEnable(IxEthDBPortId portID); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPortDisable(IxEthDBPortId portID) + * + * @brief Disables processing on a port + * + * This function is called automatically from the Ethernet Access component + * ixEthAccPortDisable() routine for Ethernet NPE ports and should be manually + * called for any user-defined port (any port that is not one of + * the Ethernet NPEs). + * + * @note Calling ixEthAccPortDisable() will disable the respective Ethernet NPE. + * After Ethernet NPEs are disabled they are stopped therefore + * when re-enabled they need to be reset, downloaded with microcode and started. + * For learning to restart working the user needs to call again + * ixEthAccPortUnicastMacAddressSet or ixEthDBUnicastAddressSet + * with the respective port MAC address. + * Residual MAC addresses learnt before the port was disabled are deleted as soon + * as the port is disabled. This only applies to dynamic (learnt) entries, static + * entries do not dissapear when the port is disabled. + * + * @param portID @ref IxEthDBPortId [in] - ID of the port to disable processing on + * + * @retval IX_ETH_DB_SUCCESS if disabling is successful + * @retval IX_ETH_DB_FAIL if the disabling was not successful due to + * a message handler error + * @retval IX_ETH_DB_INVALID_PORT if portID is invalid + * + * @note calling this function multiple times after the first time completed successfully + * does not constitute an error; redundant calls will be ignored and return IX_ETH_DB_SUCCESS +*/ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortDisable(IxEthDBPortId portID); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPortAddressSet(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) + * + * @brief Sets the port MAC address + * + * This function is to be called from the Ethernet Access component top-level + * ixEthDBUnicastAddressSet(). Event processing cannot be enabled for a port + * until its MAC address has been set. + * + * @param portID @ref IxEthDBPortId [in] - ID of the port whose MAC address is set + * @param macAddr @ref IxEthDBMacAddr [in] - port MAC address + * + * @retval IX_ETH_DB_SUCCESS MAC address was set successfully + * @retval IX_ETH_DB_FAIL MAC address was not set due to a message handler failure + * @retval IX_ETH_DB_INVALID_PORT if the port is not an Ethernet NPE + * + * @see IxEthDBPortDefs.h for port definitions + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortAddressSet(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFilteringPortMaximumFrameSizeSet(IxEthDBPortId portID, UINT32 maximumFrameSize) + * + * @brief Set the maximum frame size supported on the given port ID + * + * This functions set the maximum frame size supported on a specific port ID + * + * - Reentrant - yes + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - port ID to configure + * @param maximumFrameSize UINT32 [in] - maximum frame size to configure + * + * @retval IX_ETH_DB_SUCCESS the port is configured + * @retval IX_ETH_DB_PORT_UNINITIALIZED the port has not been initialized + * @retval IX_ETH_DB_INVALID_PORT portID is invalid + * @retval IX_ETH_DB_INVALID_ARG size parameter is out of range + * @retval IX_ETH_DB_NO_PERMISSION selected port is not an Ethernet NPE + * @retval IX_FAIL unknown OS or NPE communication error + * + * @note + * This maximum frame size is used to filter the frames based on their + * destination addresses and the capabilities of the destination port. + * The mximum value that can be set for a NPE port is 16320. + * (IX_ETHNPE_ACC_FRAME_LENGTH_MAX) + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFilteringPortMaximumFrameSizeSet(IxEthDBPortId portID, UINT32 maximumFrameSize); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFilteringStaticEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) + * + * @brief Populate the Ethernet learning/filtering database with a static MAC address + * + * Populates the Ethernet learning/filtering database with a static MAC address. The entry will not be subject to aging. + * If there is an entry (static or dynamic) with the corresponding MAC address on any port this entry will take precedence. + * Any other entry with the same MAC address will be removed. + * + * - Reentrant - yes + * - ISR Callable - yes + * + * @param portID @ref IxEthDBPortId [in] - port ID to add the static address to + * @param macAddr @ref IxEthDBMacAddr [in] - static MAC address to add + * + * @retval IX_ETH_DB_SUCCESS the add was successful + * @retval IX_ETH_DB_FAIL failed to populate the database entry + * @retval IX_ETH_DB_BUSY failed due to a temporary busy condition (i.e. lack of CPU cycles), try again later + * @retval IX_ETH_DB_INVALID_PORT portID is invalid + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE learning feature is disabled + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFilteringStaticEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFilteringDynamicEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) + * + * @brief Populate the Ethernet learning/filtering database with a dynamic MAC address + * + * Populates the Ethernet learning/filtering database with a dynamic MAC address. This entry will be subject to normal + * aging function, if aging is enabled on its port. + * If there is an entry (static or dynamic) with the same MAC address on any port this entry will take precedence. + * Any other entry with the same MAC address will be removed. + * + * - Reentrant - yes + * - ISR Callable - yes + * + * @param portID @ref IxEthDBPortId [in] - port ID to add the dynamic address to + * @param macAddr @ref IxEthDBMacAddr [in] - static MAC address to add + * + * @retval IX_ETH_DB_SUCCESS the add was successful + * @retval IX_ETH_DB_FAIL failed to populate the database entry + * @retval IX_ETH_DB_BUSY failed due to a temporary busy condition (i.e. lack of CPU cycles), try again later + * @retval IX_ETH_DB_INVALID_PORT portID is invalid + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE learning feature is disabled + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFilteringDynamicEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFilteringEntryDelete(IxEthDBMacAddr *macAddr) + * + * @brief Removes a MAC address entry from the Ethernet learning/filtering database + * + * @param macAddr IxEthDBMacAddr [in] - MAC address to remove + * + * - Reentrant - yes + * - ISR Callable - no + * + * @retval IX_ETH_DB_SUCCESS the removal was successful + * @retval IX_ETH_DB_NO_SUCH_ADDR failed to remove the address (not in the database) + * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument + * @retval IX_ETH_DB_BUSY failed due to a temporary busy condition (i.e. lack of CPU cycles), try again later + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFilteringEntryDelete(IxEthDBMacAddr *macAddr); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFilteringPortSearch(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) + * + * @brief Search the Ethernet learning/filtering database for the given MAC address and port ID + * + * This functions searches the database for a specific port ID and MAC address. Both the port ID + * and the MAC address have to match in order for the record to be reported as found. + * + * - Reentrant - yes + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - port ID to search for + * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to search for + * + * @retval IX_ETH_DB_SUCCESS the record exists in the database + * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument + * @retval IX_ETH_DB_NO_SUCH_ADDR the record was not found in the database + * @retval IX_ETH_DB_INVALID_PORT portID is invalid + * @retval IX_ETH_DB_PORT_UNINITIALIZED port ID is not initialized + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE learning feature is disabled + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFilteringPortSearch(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFilteringDatabaseSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr) + * + * @brief Search the Ethernet learning/filtering database for a MAC address and return the port ID + * + * Searches the database for a MAC address. The function returns the portID for the + * MAC address record, if found. If no match is found the function returns IX_ETH_DB_NO_SUCH_ADDR. + * The portID is only valid if the function finds a match. + * + * - Reentrant - yes + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - port ID the address belongs to (populated only on a successful search) + * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to search for + * + * @retval IX_ETH_DB_SUCCESS the record exists in the database + * @retval IX_ETH_DB_NO_SUCH_ADDR the record was not found in the database + * @retval IX_ETH_DB_INVALID_ARG invalid macAddr or portID pointer argument(s) + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFilteringDatabaseSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFilteringPortUpdatingSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr) + * + * @brief Search the filtering database for a MAC address, return the port ID and reset the record age + * + * Searches the database for a MAC address. The function returns the portID for the + * MAC address record and resets the entry age to 0, if found. + * If no match is found the function returns IX_ETH_DB_NO_SUCH_ADDR. + * The portID is only valid if the function finds a match. + * + * - Reentrant - yes + * - ISR Callable - no + * + * @retval IX_ETH_DB_SUCCESS the MAC address was found + * @retval IX_ETH_DB_NO_SUCH_ADDR the MAC address was not found + * @retval IX_ETH_DB_INVALID_ARG invalid macAddr or portID pointer argument(s) + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFilteringPortUpdatingSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr); + +/** + * @ingroup IxEthDB + * + * @def IX_ETH_DB_MAINTENANCE_TIME + * + * @brief The @ref ixEthDBDatabaseMaintenance must be called by the user at a frequency of + * IX_ETH_DB_MAINTENANCE_TIME + * + */ +#define IX_ETH_DB_MAINTENANCE_TIME (1 * 60) /* 1 Minute */ + +/** + * @ingroup IxEthDB + * + * @def IX_ETH_DB_LEARNING_ENTRY_AGE_TIME + * + * @brief The define specifies the filtering database age entry time. Static entries older than + * IX_ETH_DB_LEARNING_ENTRY_AGE_TIME +/- IX_ETH_DB_MAINTENANCE_TIME shall be removed. + * + */ +#define IX_ETH_DB_LEARNING_ENTRY_AGE_TIME (15 * 60 ) /* 15 Mins */ + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPortAgingDisable(IxEthDBPortId portID) + * + * @brief Disable the aging function for a specific port + * + * @param portID @ref IxEthDBPortId [in] - port ID to disable aging on + * + * - Reentrant - yes + * - ISR Callable - no + * + * @retval IX_ETH_DB_SUCCESS aging disabled successfully + * @retval IX_ETH_DB_INVALID_PORT portID is invalid + * @retval IX_ETH_DB_PORT_UNINITIALIZED port ID is not initialized + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE learning feature is disabled + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortAgingDisable(IxEthDBPortId portID); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPortAgingEnable(IxEthDBPortId portID) + * + * @brief Enable the aging function for a specific port + * + * Enables the aging of dynamic MAC address entries stored in the learning/filtering database + * + * @note The aging function relies on the @ref ixEthDBDatabaseMaintenance being called with a period of + * @ref IX_ETH_DB_MAINTENANCE_TIME seconds. + * + * - Reentrant - yes + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - port ID to enable aging on + * + * @retval IX_ETH_DB_SUCCESS aging enabled successfully + * @retval IX_ETH_DB_INVALID_PORT portID is invalid + * @retval IX_ETH_DB_PORT_UNINITIALIZED port ID is not initialized + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE learning feature is disabled + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortAgingEnable(IxEthDBPortId portID); + +/** + * @ingroup IxEthDB + * + * @fn void ixEthDBDatabaseMaintenance(void) + * + * @brief Performs a maintenance operation on the Ethernet learning/filtering database + * + * In order to perform a database maintenance this function must be called every + * @ref IX_ETH_DB_MAINTENANCE_TIME seconds. It should be called regardless of whether learning is + * enabled or not. + * + * - Reentrant - no + * - ISR Callable - no + * + * @note this function call will be ignored if the learning feature is disabled + */ +IX_ETH_DB_PUBLIC +void ixEthDBDatabaseMaintenance(void); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFilteringDatabaseShow(IxEthDBPortId portID) + * + * @brief This function displays the Mac Ethernet MAC address filtering tables. + * + * It displays the MAC address, port ID, entry type (dynamic/static),and age for + * the given port ID. + * + * - Reentrant - no + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - port ID to display the MAC address entries + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is invalid + * @retval IX_ETH_DB_PORT_UNINITIALIZED port ID is not initialized + * @retval IX_ETH_DB_FAIL record browser failed due to an internal busy or lock condition + * + * @note this function is deprecated and kept for compatibility reasons; use @ref ixEthDBFilteringDatabaseShowRecords instead + * + * @see ixEthDBFilteringDatabaseShowRecords + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFilteringDatabaseShow(IxEthDBPortId portID); + +/** + * @ingroup IxEthDB + * + * @fn void ixEthDBFilteringDatabaseShowAll(void) + * + * @brief Displays the MAC address recorded in the filtering database for all registered + * ports (see IxEthDBPortDefs.h), grouped by port ID. + * + * - Reentrant - no + * - ISR Callable - no + * + * @retval void + * + * @note this function is deprecated and kept for compatibility reasons; use @ref ixEthDBFilteringDatabaseShowRecords instead + * + * @see ixEthDBFilteringDatabaseShowRecords + */ +IX_ETH_DB_PUBLIC +void ixEthDBFilteringDatabaseShowAll(void); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFilteringDatabaseShowRecords(IxEthDBPortId portID, IxEthDBRecordType recordFilter) + * + * @brief This function displays per port database records, given a record type filter + * + * The supported record type filters are: + * + * - IX_ETH_DB_FILTERING_RECORD - displays the non-VLAN filtering records (MAC address, age, static/dynamic) + * - IX_ETH_DB_FILTERING_VLAN_RECORD - displays the VLAN filtering records (MAC address, age, static/dynamic, VLAN ID, CFI, QoS class) + * - IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD - displays the previous two types of records + * - IX_ETH_DB_WIFI_RECORD - displays the WiFi header conversion records (MAC address, optional gateway MAC address) and WiFi header conversion parameters (BBSID, Duration/ID) + * - IX_ETH_DB_FIREWALL_RECORD - displays the firewall MAC address table and firewall operating mode (white list/black list) + * - IX_ETH_DB_ALL_RECORD_TYPES - displays all the record types + * - IX_ETH_DB_NO_RECORD_TYPE - displays only the port status (no records are displayed) + * + * Additionally, the status of each port will be displayed, containg the following information: type, capabilities, enabled status, + * aging enabled status, group membership and maximum frame size. + * + * The port ID can either be an actual port or IX_ETH_DB_ALL_PORTS, in which case the requested information + * will be displayed for all the ports (grouped by port) + * + * - Reentrant - no + * - ISR Callable - no + * + * @param portID ID of the port to display information on (use IX_ETH_DB_ALL_PORTS for all the ports) + * @param recordFilter record type filter + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is invalid + * @retval IX_ETH_DB_PORT_UNINITIALIZED port ID is not initialized + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFilteringDatabaseShowRecords(IxEthDBPortId portID, IxEthDBRecordType recordFilter); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPortDependencyMapSet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap) + * + * @brief Sets the dependency port map for a port + * + * @param portID ID of the port to set the dependency map to + * @param dependencyPortMap new dependency map (as bitmap, each bit set indicates a port being included) + * + * This function is used to share filtering information between ports. + * By adding a port into another port's dependency map the target port + * filtering data will import the filtering data from the port it depends on. + * Any changes to filtering data for a port - such as adding, updating or removing records - + * will trigger updates in the filtering information for all the ports depending on + * on the updated port. + * + * For example, if ports 2 and 3 are set in the port 0 dependency map the filtering + * information for port 0 will also include the filtering information from ports 2 and 3. + * Adding a record to port 2 will also trigger an update not only on port 2 but also on + * port 0. + * + * The dependency map is a 256 bit array where each bit corresponds to a port corresponding to the + * bit offset (bit 0 - port 0, bit 1 - port 1 etc). Setting a bit to 1 indicates that the corresponding + * port is the port map. For example, a dependency port map of 0x14 consists in the ports with IDs 2 and 4. + * Note that the last bit (offset 255) is reserved and should never be set (it will be automatically + * cleared by the function). + * + * By default, each port has a dependency port map consisting only of itself, i.e. + * + * @verbatim + IxEthDBPortMap portMap; + + // clear all ports from port map + memset(portMap, 0, sizeof (portMap)); + + // include portID in port map + portMap[portID / 8] = 1 << (portID % 8); + @endverbatim + * + * - Reentrant - no + * - ISR Callable - no + * + * @note Setting dependency maps is useful for NPE ports, which benefit from automatic updates + * of filtering information. Setting dependency maps for user-defined ports is not an error + * but will have no actual effect. + * + * @note Including a port in its own dependency map is not compulsory, however note that + * in this case updating the port will not trigger an update on the port itself, which + * might not be the intended behavior + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid dependencyPortMap pointer + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Filtering is not available or not enabled for the port + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortDependencyMapSet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPortDependencyMapGet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap) + * + * @brief Retrieves the dependency port map for a port + * + * @param portID ID of the port to set the dependency map to + * @param dependencyPortMap location where the port dependency map is to be copied + * + * This function will copy the port dependency map to a user specified location. + * + * - Reentrant - no + * - ISR Callable - no + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid dependencyPortMap pointer + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Filtering is not available or not enabled for the port + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortDependencyMapGet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPortVlanTagSet(IxEthDBPortId portID, IxEthDBVlanTag vlanTag) + * + * @brief Sets the default 802.1Q VLAN tag for a given port + * + * @param portID @ref IxEthDBPortId [in] - ID of the port to set the default VLAN tag to + * @param vlanTag @ref IxEthDBVlanTag [in] - default 802.1Q VLAN tag + * + * The tag format has 16 bits and it is defined in the IEEE802.1Q specification. + * This tag will be used for tagging untagged frames (if enabled) and classifying + * unexpedited traffic into an internal traffic class (using the user priority field). + * + * + *
802.1Q tag format
3 bits 1 bit 12 bits + *
user priority CFI VID + *
+ * + * User Priority : Defines user priority, giving eight (2^3) priority levels. IEEE 802.1P defines + * the operation for these 3 user priority bits + * + * CFI : Canonical Format Indicator is always set to zero for Ethernet switches. CFI is used for + * compatibility reason between Ethernet type network and Token Ring type network. If a frame received + * at an Ethernet port has a CFI set to 1, then that frame should not be forwarded as it is to an untagged port. + * + * VID : VLAN ID is the identification of the VLAN, which is basically used by the standard 802.1Q. + * It has 12 bits and allow the id entification of 4096 (2^12) VLANs. Of the 4096 possible VIDs, a VID of 0 + * is used to identify priority frames and value 4095 (FFF) is reserved, so the maximum possible VLAN + * configurations are 4,094. + * + * - Reentrant - no + * - ISR Callable - no + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + * @retval IX_ETH_DB_INVALID_VLAN vlanTag argument does not parse to a valid 802.1Q VLAN tag + * + * @note a VLAN ID value of 0 indicates that the port is not part of any VLAN + * @note the value of the cannonical frame indicator (CFI) field is ignored, the + * field being used only in frame tagging operations + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortVlanTagSet(IxEthDBPortId portID, IxEthDBVlanTag vlanTag); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPortVlanTagGet(IxEthDBPortId portID, IxEthDBVlanTag *vlanTag) + * + * @brief Retrieves the default 802.1Q port VLAN tag for a given port (see also @ref ixEthDBPortVlanTagSet) + * + * @param portID @ref IxEthDBPortId [in] - ID of the port to retrieve the default VLAN tag from + * @param vlanTag @ref IxEthDBVlanTag [out] - location to write the default port 802.1Q VLAN tag to + * + * - Reentrant - no + * - ISR Callable - no + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid vlanTag pointer + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortVlanTagGet(IxEthDBPortId portID, IxEthDBVlanTag *vlanTag); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBVlanTagSet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag vlanTag) + * + * @brief Sets the 802.1Q VLAN tag for a database record + * + * @param macAddr MAC address + * @param vlanTag 802.1Q VLAN tag + * + * This function is used together with @ref ixEthDBVlanTagGet to provide MAC-based VLAN classification support. + * Please note that the bridging application must contain specific code to make use of this feature (see below). + * + * VLAN tags can be set only in IX_ETH_DB_FILTERING_RECORD or IX_ETH_DB_FILTERING_VLAN_RECORD type records. + * If to an IX_ETH_DB_FILTERING_RECORD type record is added a VLAN tag the record type is automatically + * changed to IX_ETH_DB_FILTERING_VLAN_RECORD. Once this has occurred the record type will never + * revert to a non-VLAN type (unless deleted and re-added). + * + * Record types used for different purposes (such as IX_ETH_DB_WIFI_RECORD) will be ignored by + * this function. + * + * After using this function to associate a VLAN ID with a MAC address the VLAN ID can be extracted knowing the + * MAC address using @ref ixEthDBVlanTagGet. This mechanism can be used to implement MAC-based VLAN classification + * if a bridging application searches for the VLAN tag when receiving a frame based on the source MAC address + * (contained in the ixp_ne_src_mac field of the buffer header). + * If found in the database, the application can instruct the NPE to tag the frame by writing the VLAN tag + * in the ixp_ne_vlan_tci field of the buffer header. This way the NPE will inspect the Egress tagging + * rule associated with the given VLAN ID on the Tx port and tag the frame if Egress tagging on the VLAN is + * allowed. Additionally, Egress tagging can be forced by setting the ixp_ne_tx_flags.tag_over and + * ixp_ne_tx_flags.tag_mode flags in the buffer header. + * + * - Reentrant - no + * - ISR Callable - no + * + * @note this function will not add a filtering record, it can only be used to update an existing one + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer + * @retval IX_ETH_DB_NO_SUCH_ADDR a filtering record with the specified MAC address was not found + * @retval IX_ETH_DB_INVALID_VLAN vlanTag argument does not parse to a valid 802.1Q VLAN tag + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBVlanTagSet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag vlanTag); + +/** + * @ingroup IxEthDB + * + * @fn ixEthDBVlanTagGet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag *vlanTag) + * + * @brief Retrieves the 802.1Q VLAN tag from a database record given the record MAC address + * + * @param macAddr MAC address + * @param vlanTag location to write the record 802.1Q VLAN tag to + * + * @note VLAN tags can be retrieved only from IX_ETH_DB_FILTERING_VLAN_RECORD type records + * + * This function is used together with ixEthDBVlanTagSet to provide MAC-based VLAN classification support. + * Please note that the bridging application must contain specific code to make use of this feature (see @ref ixEthDBVlanTagSet). + * + * - Reentrant - no + * - ISR Callable - no + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_ARG invalid macAddr or vlanTag pointer + * @retval IX_ETH_DB_NO_SUCH_ADDR a filtering record with the specified MAC address was not found + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBVlanTagGet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag *vlanTag); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPortVlanMembershipAdd(IxEthDBPortId portID, IxEthDBVlanId vlanID) + * + * @brief Adds a VLAN ID to a port's VLAN membership table + * + * Adding a VLAN ID to a port's VLAN membership table will cause frames tagged with the specified + * VLAN ID to be accepted by the frame filter, if Ingress VLAN membership filtering is enabled. + * + * - Reentrant - no + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - ID of the port to add the VLAN ID membership to + * @param vlanID @ref IxEthDBVlanId [in] - VLAN ID to be added to the port membership table + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_VLAN vlanID is not a valid VLAN ID + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + * @retval IX_FAIL unknown OS or NPE communication error + * + * @note A port's default VLAN ID is always in its own membership table, hence there + * is no need to explicitly add it using this function (although it is not an error + * to do so) + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortVlanMembershipAdd(IxEthDBPortId portID, IxEthDBVlanId vlanID); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPortVlanMembershipRangeAdd(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax) + * + * @brief Adds a VLAN ID range to a port's VLAN membership table + * + * All the VLAN IDs in the specified range will be added to the port VLAN + * membership table, including the range start and end VLAN IDs. Tagged frames with + * VLAN IDs in the specified range will be accepted by the frame filter, if Ingress VLAN + * membership filtering is enabled. + * + * - Reentrant - no + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - port ID to add the VLAN membership range into + * @param vlanIDMin @ref IxEthDBVlanId [in] - start of the VLAN ID range + * @param vlanIDMax @ref IxEthDBVlanId [in] - end of the VLAN ID range + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_VLAN the specified VLAN IDs are invalid or do not constitute a range + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + * @retval IX_FAIL unknown OS or NPE communication error + * + * @note Is is valid to use the same VLAN ID for both vlanIDMin and vlanIDMax, in which case this + * function will behave as @ref ixEthDBPortVlanMembershipAdd + * + * @note A port's default VLAN ID is always in its own membership table, hence there is no need + * to explicitly add it using this function (although it is not an error to do so) + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortVlanMembershipRangeAdd(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPortVlanMembershipRemove(IxEthDBPortId portID, IxEthDBVlanId vlanID) + * + * @brief Removes a VLAN ID from a port's VLAN membership table + * + * Frames tagged with a VLAN ID which is not in a port's VLAN membership table + * will be discarded by the frame filter, if Ingress membership filtering is enabled. + * + * - Reentrant - no + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - ID of the port to remove the VLAN ID membership from + * @param vlanID @ref IxEthDBVlanId [in] - VLAN ID to be removed from the port membership table + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_INVALID_VLAN vlanID is not a valid VLAN ID + * @retval IX_ETH_DB_NO_PERMISSION attempted to remove the default VLAN ID + * from the port membership table (vlanID was set to the default port VLAN ID) + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + * @retval IX_FAIL unknown OS or NPE communication error + * + * @note A port's default VLAN ID cannot be removed from the port's membership + * table; attempting it will return IX_ETH_DB_NO_PERMISSION + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortVlanMembershipRemove(IxEthDBPortId portID, IxEthDBVlanId vlanID); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPortVlanMembershipRangeRemove(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax) + * + * @brief Removes a VLAN ID range from a port's VLAN membership table + * + * All the VLAN IDs in the specified range will be removed from the port VLAN + * membership table, including the range start and end VLAN IDs. Tagged frames + * with VLAN IDs in the range will be discarded by the frame filter, if Ingress + * membership filtering is enabled. + * + * - Reentrant - no + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - ID of the port to remove the VLAN membership range from + * @param vlanIDMin @ref IxEthDBVlanId [in] - start of the VLAN ID range + * @param vlanIDMax @ref IxEthDBVlanId [in] - end of the VLAN ID range + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_VLAN the specified VLAN IDs are invalid or do not constitute a range + * @retval IX_ETH_DB_NO_PERMISSION attempted to remove the default VLAN ID + * from the port membership table (both vlanIDMin and vlanIDMax were set to the default port VLAN ID) + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + * @retval IX_FAIL unknown OS or NPE communication error + * + * @note Is is valid to use the same VLAN ID for both vlanIDMin and vlanIDMax, in which case + * function will behave as @ref ixEthDBPortVlanMembershipRemove + * + * @note If the given range overlaps the default port VLAN ID this function + * will remove all the VLAN IDs in the range except for the port VLAN ID from its + * own membership table. This situation will be silently dealt with (no error message + * will be returned) as long as the range contains more than one value (i.e. at least + * one other value, apart from the default port VLAN ID). If the function is called + * with the vlanIDMin and vlanIDMax parameters both set to the port default VLAN ID, the + * function will infer that an attempt was specifically made to remove the default port + * VLAN ID from the port membership table, in which case the return value will be + * IX_ETH_DB_NO_PERMISSION. + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortVlanMembershipRangeRemove(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPortVlanMembershipSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet) + * + * @brief Sets a port's VLAN membership table + * + * Sets a port's VLAN membership table from a complete VLAN table containing all the possible + * 4096 VLAN IDs. The table format is an array containing 4096 bits (512 bytes), where each bit + * indicates whether the VLAN at that bit index is in the port's membership list (if set) or + * not (unset). + * + * The bit at index 0, indicating VLAN ID 0, indicates no VLAN membership and therefore no + * other bit must be set if bit 0 is set. + * + * The bit at index 4095 is reserved and should never be set (it will be ignored if set). + * + * The bit referencing the same VLAN ID as the default port VLAN ID should always be set, as + * the membership list must contain at least the default port VLAN ID. + * + * - Reentrant - no + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - port ID to set the VLAN membership table to + * @param vlanSet @ref IxEthDBVlanSet [in] - pointer to the VLAN membership table + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid vlanSet pointer + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + * @retval IX_FAIL unknown OS or NPE communication error + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortVlanMembershipSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPortVlanMembershipGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet) + * + * @brief Retrieves a port's VLAN membership table + * + * Retrieves the complete VLAN membership table from a port, containing all the possible + * 4096 VLAN IDs. The table format is an array containing 4096 bits (512 bytes), where each bit + * indicates whether the VLAN at that bit index is in the port's membership list (if set) or + * not (unset). + * + * The bit at index 0, indicating VLAN ID 0, indicates no VLAN membership and therefore no + * other bit will be set if bit 0 is set. + * + * The bit at index 4095 is reserved and will not be set (it will be ignored if set). + * + * The bit referencing the same VLAN ID as the default port VLAN ID will always be set, as + * the membership list must contain at least the default port VLAN ID. + * + * - Reentrant - no + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - port ID to retrieve the VLAN membership table from + * @param vlanSet @ref IxEthDBVlanSet [out] - pointer a location where the VLAN membership table will be + * written to + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid vlanSet pointer + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortVlanMembershipGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBAcceptableFrameTypeSet(IxEthDBPortId portID, IxEthDBFrameFilter frameFilter) + * + * @brief Sets a port's acceptable frame type filter + * + * The acceptable frame type is one (or a combination) of the following values: + * - IX_ETH_DB_ACCEPT_ALL_FRAMES - accepts all the frames + * - IX_ETH_DB_UNTAGGED_FRAMES - accepts untagged frames + * - IX_ETH_DB_VLAN_TAGGED_FRAMES - accepts tagged frames + * - IX_ETH_DB_PRIORITY_TAGGED_FRAMES - accepts tagged frames with VLAN ID set to 0 (no VLAN membership) + * + * Except for using the exact values given above only the following combinations are valid: + * - IX_ETH_DB_UNTAGGED_FRAMES | IX_ETH_DB_VLAN_TAGGED_FRAMES + * - IX_ETH_DB_UNTAGGED_FRAMES | IX_ETH_DB_PRIORITY_TAGGED_FRAMES + * + * Please note that IX_ETH_DB_UNTAGGED_FRAMES | IX_ETH_DB_VLAN_TAGGED_FRAMES is equivalent + * to IX_ETH_DB_ACCEPT_ALL_FRAMES. + * + * - Reentrant - no + * - ISR Callable - no + * + * @note by default the acceptable frame type filter is set to IX_ETH_DB_ACCEPT_ALL_FRAMES + * + * @note setting the acceptable frame type to PRIORITY_TAGGED_FRAMES is internally + * accomplished by changing the frame filter to VLAN_TAGGED_FRAMES and setting the + * VLAN membership list to include only VLAN ID 0; the membership list will need + * to be restored manually to an appropriate value if the acceptable frame type + * filter is changed back to ACCEPT_ALL_FRAMES or VLAN_TAGGED_FRAMES; failure to do so + * will filter all VLAN traffic bar frames tagged with VLAN ID 0 + * + * @param portID @ref IxEthDBPortId [in] - port ID to set the acceptable frame type filter to + * @param frameFilter @ref IxEthDBFrameFilter [in] - acceptable frame type filter + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid frame type filter + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + * @retval IX_FAIL unknown OS or NPE communication error + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBAcceptableFrameTypeSet(IxEthDBPortId portID, IxEthDBFrameFilter frameFilter); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBAcceptableFrameTypeGet(IxEthDBPortId portID, IxEthDBFrameFilter *frameFilter) + * + * @brief Retrieves a port's acceptable frame type filter + * + * For a description of the acceptable frame types see @ref ixEthDBAcceptableFrameTypeSet + * + * - Reentrant - no + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - port ID to retrieve the acceptable frame type filter from + * @param frameFilter @ref IxEthDBFrameFilter [out] - location to store the acceptable frame type filter + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid frameFilter pointer argument + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBAcceptableFrameTypeGet(IxEthDBPortId portID, IxEthDBFrameFilter *frameFilter); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPriorityMappingTableSet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable) + * + * @brief Sets a port's priority mapping table + * + * The priority mapping table is an 8x2 table mapping a QoS (user) priority into an internal + * traffic class. There are 8 valid QoS priorities (0..7, 0 being the lowest) which can be + * mapped into one of the 4 available traffic classes (0..3, 0 being the lowest). + * If a custom priority mapping table is not specified using this function the following + * default priority table will be used (as per IEEE 802.1Q and IEEE 802.1D): + * + * + *
QoS traffic classes
QoS priority Default traffic class Traffic type + *
0 1 Best effort, default class for unexpedited traffic + *
1 0 Background traffic + *
2 0 Spare bandwidth + *
3 1 Excellent effort + *
4 2 Controlled load + *
5 2 Video traffic + *
6 3 Voice traffic + *
7 3 Network control + *
+ * + * - Reentrant - no + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - port ID of the port to set the priority mapping table to + * @param priorityTable @ref IxEthDBPriorityTable [in] - location of the user priority table + * + * @note The provided table will be copied into internal data structures in EthDB and + * can be deallocated by the called after this function has completed its execution, if + * so desired + * + * @warning The number of available traffic classes differs depending on the NPE images + * and queue configuration. Check IxEthDBQoS.h for up-to-date information on the availability of + * traffic classes. Note that specifiying a traffic class in the priority map which exceeds + * the system availability will produce an IX_ETH_DB_INVALID_PRIORITY return error code and no + * priority will be remapped. + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid priorityTable pointer + * @retval IX_ETH_DB_INVALID_PRIORITY at least one priority value exceeds + * the current number of available traffic classes + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + * @retval IX_FAIL unknown OS or NPE communication error + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPriorityMappingTableSet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPriorityMappingTableGet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable) + * + * @brief Retrieves a port's priority mapping table + * + * The priority mapping table for the given port will be copied in the location + * specified by the caller using "priorityTable" + * + * - Reentrant - no + * - ISR Callable - no + * + * @param portID ID @ref IxEthDBPortId [in] - of the port to retrieve the priority mapping table from + * @param priorityTable @ref IxEthDBPriorityTable [out] - pointer to a user specified location where the table will be copied to + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid priorityTable pointer + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPriorityMappingTableGet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPriorityMappingClassSet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority trafficClass) + * + * @brief Sets one QoS/user priority => traffic class mapping in a port's priority mapping table + * + * This function establishes a mapping between a user (QoS) priority and an internal traffic class. + * The mapping will be saved in the port's priority mapping table. Use this function when not all + * the QoS priorities need remapping (see also @ref ixEthDBPriorityMappingTableSet) + * + * - Reentrant - no + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - ID of the port to set the mapping to + * @param userPriority @ref IxEthDBPriority [in] - user (QoS) priority, between 0 and 7 (0 being the lowest) + * @param trafficClass @ref IxEthDBPriority [in] - internal traffic class, between 0 and 3 (0 being the lowest) + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_PRIORITY userPriority out of range or + * trafficClass is beyond the number of currently available traffic classes + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + * @retval IX_FAIL unknown OS or NPE communication error + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPriorityMappingClassSet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority trafficClass); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPriorityMappingClassGet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority *trafficClass) + * + * @brief Retrieves one QoS/user priority => traffic class mapping in a port's priority mapping table + * + * This function retrieves the internal traffic class associated with a QoS (user) priority from a given + * port's priority mapping table. Use this function when not all the QoS priority mappings are + * required (see also @ref ixEthDBPriorityMappingTableGet) + * + * - Reentrant - no + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - ID of the port to set the mapping to + * @param userPriority @ref IxEthDBPriority [in] - user (QoS) priority, between 0 and 7 (0 being the lowest) + * @param trafficClass @ref IxEthDBPriority [out] - location to write the corresponding internal traffic class to + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_PRIORITY invalid userPriority value (out of range) + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + * @retval IX_ETH_DB_INVALID_ARG invalid trafficClass pointer argument + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPriorityMappingClassGet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority *trafficClass); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL enabled) + * + * @brief Enables or disables Egress VLAN tagging for a port and a given VLAN + * + * This function enables or disables Egress VLAN tagging for the given port and VLAN ID. + * If the VLAN tagging for a certain VLAN ID is enabled then all the frames to be + * transmitted on the given port tagged with the same VLAN ID will be transmitted in a tagged format. + * If tagging is not enabled for the given VLAN ID, the VLAN tag from the frames matching + * this VLAN ID will be removed (the frames will be untagged). + * + * VLAN ID 4095 is reserved and should never be used with this function. + * VLAN ID 0 has the special meaning of "No VLAN membership" and it is used in this + * context to allow the port to send priority-tagged frames or not. + * + * By default, no Egress VLAN tagging is enabled on any port. + * + * - Reentrant - no + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - ID of the port to enable or disable the VLAN ID Egress tagging on + * @param vlanID @ref IxEthDBVlanId [in] - VLAN ID to be matched against outgoing frames + * @param enabled BOOL [in] - TRUE to enable Egress VLAN tagging on the port and given VLAN, and + * FALSE to disable Egress VLAN tagging + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_VLAN invalid VLAN ID (out of range) + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + * @retval IX_FAIL unknown OS or NPE communication error + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL enabled); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL *enabled) + * + * @brief Retrieves the Egress VLAN tagging enabling status for a port and VLAN ID + * + * @param portID [in] - ID of the port to extract the Egress VLAN ID tagging status from + * @param vlanID VLAN [in] - ID whose tagging status is to be extracted + * @param enabled [in] - user-specifed location where the status is copied to; following + * the successfull execution of this function the value will be TRUE if Egress VLAN + * tagging is enabled for the given port and VLAN ID, and FALSE otherwise + * + * - Reentrant - no + * - ISR Callable - no + * + * @see ixEthDBEgressVlanEntryTaggingEnabledGet + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_VLAN invalid VLAN ID (out of range) + * @retval IX_ETH_DB_INVALID_ARG invalid enabled argument pointer + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL *enabled); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBEgressVlanRangeTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax, BOOL enabled) + * + * @brief Enables or disables Egress VLAN tagging for a port and given VLAN range + * + * This function is very similar to @ref ixEthDBEgressVlanEntryTaggingEnabledSet with the + * difference that it can manipulate the Egress tagging status on multiple VLAN IDs, + * defined by a contiguous range. Note that both limits in the range are explicitly + * included in the execution of this function. + * + * - Reentrant - no + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - ID of the port to enable or disable the VLAN ID Egress tagging on + * @param vlanIDMin @ref IxEthDBVlanId [in] - start of the VLAN range to be matched against outgoing frames + * @param vlanIDMax @ref IxEthDBVlanId [in] - end of the VLAN range to be matched against outgoing frames + * @param enabled BOOL [in] - TRUE to enable Egress VLAN tagging on the port and given VLAN range, + * and FALSE to disable Egress VLAN tagging + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_VLAN invalid VLAN ID (out of range), or do not constitute a range + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + * @retval IX_ETH_DB_NO_PERMISSION attempted to explicitly remove the default port VLAN ID from the tagging table + * @retval IX_FAIL unknown OS or NPE communication error + * + * @note Specifically removing the default port VLAN ID from the Egress tagging table by setting both vlanIDMin and vlanIDMax + * to the VLAN ID portion of the PVID is not allowed by this function and will return IX_ETH_DB_NO_PERMISSION. + * However, this can be circumvented, should the user specifically desire this, by either using a + * larger range (vlanIDMin < vlanIDMax) or by using ixEthDBEgressVlanEntryTaggingEnabledSet. + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBEgressVlanRangeTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax, BOOL enabled); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBEgressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet) + * + * @brief Sets the complete Egress VLAN tagging table for a port + * + * This function is used to set the VLAN tagging/untagging per VLAN ID for a given port + * covering the entire VLAN ID range (0..4094). The vlanSet parameter is a 4096 + * bit array, each bit indicating the Egress behavior for the corresponding VLAN ID. + * If a bit is set then outgoing frames with the corresponding VLAN ID will be transmitted + * with the VLAN tag, otherwise the frame will be transmitted without the VLAN tag. + * + * Bit 0 has a special significance, indicating tagging or tag removal for priority-tagged + * frames. + * + * Bit 4095 is reserved and should never be set (it will be ignored if set). + * + * - Reentrant - no + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - ID of the port whose Egress VLAN tagging behavior is set + * @param vlanSet @ref IxEthDBVlanSet [in] - 4096 bit array controlling per-VLAN tagging and untagging + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid vlanSet pointer + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + * @retval IX_FAIL unknown OS or NPE communication error + * + * @warning This function will automatically add the default port VLAN ID to the Egress tagging table + * every time it is called. The user should manually call ixEthDBEgressVlanEntryTaggingEnabledSet to + * prevent tagging on the default port VLAN ID if the default behavior is not intended. + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBEgressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBEgressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet) + * + * @brief Retrieves the complete Egress VLAN tagging table from a port + * + * This function copies the 4096 bit table controlling the Egress VLAN tagging into a user specified + * area. Each bit in the array indicates whether tagging for the corresponding VLAN (the bit position + * in the array) is enabled (the bit is set) or not (the bit is unset). + * + * Bit 4095 is reserved and should not be set (it will be ignored if set). + * + * @see ixEthDBEgressVlanTaggingEnabledSet + * + * @param portID @ref IxEthDBPortId [in] - ID of the port whose Egress VLAN tagging behavior is retrieved + * @param vlanSet @ref IxEthDBVlanSet [out] - user location to copy the Egress tagging table into; should have + * room to store 4096 bits (512 bytes) + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid vlanSet pointer + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBEgressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBIngressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBTaggingAction taggingAction) + * + * @brief Sets the Ingress VLAN tagging behavior for a port + * + * A port's Ingress tagging behavior is controlled by the taggingAction parameter, + * which can take one of the following values: + * + * - IX_ETH_DB_PASS_THROUGH - leaves the frame unchanged (does not add or remove the VLAN tag) + * - IX_ETH_DB_ADD_TAG - adds the VLAN tag if not present, using the default port VID + * - IX_ETH_DB_REMOVE_TAG - removes the VLAN tag if present + * + * @param portID @ref IxEthDBPortId [in] - ID of the port whose Ingress VLAN tagging behavior is set + * @param taggingAction @ref IxEthDBTaggingAction [in] - tagging behavior for the port + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid taggingAction argument + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + * @retval IX_FAIL unknown OS or NPE communication error + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBIngressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBTaggingAction taggingAction); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBIngressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBTaggingAction *taggingAction) + * + * @brief Retrieves the Ingress VLAN tagging behavior from a port (see @ref ixEthDBIngressVlanTaggingEnabledSet) + * + * @param portID @ref IxEthDBPortId [in] - ID of the port whose Ingress VLAN tagging behavior is set + * @param taggingAction @ref IxEthDBTaggingAction [out] - location where the tagging behavior for the port is written to + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid taggingAction pointer argument + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBIngressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBTaggingAction *taggingAction); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBVlanPortExtractionEnable(IxEthDBPortId portID, BOOL enable) + * + * @brief Enables or disables port ID extraction + * + * This feature can be used in the situation when a multi-port device (e.g. a switch) + * is connected to an IXP4xx port and the device can provide incoming frame port + * identification by tagging the TPID field in the Ethernet frame. Enabling + * port extraction will instruct the NPE to copy the TPID field from the frame and + * place it in the ixp_ne_src_port of the ixp_buf header. In addition, + * the NPE restores the TPID field to 0. + * + * If the frame is not tagged the NPE will fill the ixp_ne_src_port with the + * port ID of the MII interface the frame was received from. + * + * The TPID field is the least significant byte of the type/length field, which is + * normally set to 0x8100 for 802.1Q-tagged frames. + * + * This feature is disabled by default. + * + * @param portID ID of the port to configure port ID extraction on + * @param enable TRUE to enable port ID extraction and FALSE to disable it + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + * @retval IX_FAIL unknown OS or NPE communication error + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBVlanPortExtractionEnable(IxEthDBPortId portID, BOOL enable); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFeatureCapabilityGet(IxEthDBPortId portID, IxEthDBFeature *featureSet) + * + * @brief Retrieves the feature capability set for a port + * + * This function retrieves the feature capability set for a port or the common capabilities shared between all + * the ports, writing the feature capability set in a user specified location. + * + * The feature capability set will consist of a set formed by OR-ing one or more of the following values: + * - IX_ETH_DB_LEARNING - Learning feature; enables EthDB to learn MAC address (filtering) records, including 802.1Q enabled records + * - IX_ETH_DB_FILTERING - Filtering feature; enables EthDB to communicate with the NPEs for downloading filtering information in the NPEs; depends on the learning feature + * - IX_ETH_DB_VLAN_QOS - VLAN/QoS feature; enables EthDB to configure NPEs to operate in VLAN/QoS aware modes + * - IX_ETH_DB_FIREWALL - Firewall feature; enables EthDB to configure NPEs to operate in firewall mode, using white/black address lists + * - IX_ETH_DB_SPANNING_TREE_PROTOCOL - Spanning tree protocol feature; enables EthDB to configure the NPEs as STP nodes + * - IX_ETH_DB_WIFI_HEADER_CONVERSION - WiFi 802.3 to 802.11 header conversion feature; enables EthDB to handle WiFi conversion data + * + * Note that EthDB provides only the LEARNING feature for non-NPE ports. + * + * @param portID @ref IxEthDBPortId [in] - ID of the port to retrieve the capability set for + * (use IX_ETH_DB_ALL_PORTS to retrieve the common capabilities shared between all the ports) + * @param featureSet @ref IxEthDBFeature [out] - location where the capability set will be written to + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid featureSet pointer + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFeatureCapabilityGet(IxEthDBPortId portID, IxEthDBFeature *featureSet); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFeatureEnable(IxEthDBPortId portID, IxEthDBFeature feature, BOOL enabled) + * + * @brief Enables or disables one or more EthDB features + * + * Selects one or more features (see @ref ixEthDBFeatureCapabilityGet for a description of the supported + * features) to be enabled or disabled on the selected port (or all the ports). + * + * Note that some features are mutually incompatible: + * - IX_ETH_DB_FILTERING is incompatible with IX_ETH_DB_WIFI_HEADER_CONVERSION + * + * Also note that some features require other features to be enabled: + * - IX_ETH_DB_FILTERING requires IX_ETH_DB_LEARNING + * + * This function will either enable the entire selected feature set for the selected port (or all the ports), + * in which case it will return IX_ETH_DB_SUCCESS, or in case of error it will not enable any feature at all + * and return an appropriate error message. + * + * The following features are enabled by default (for ports with the respective capability), + * for compatibility reasons with previous versions of CSR: + * - IX_ETH_DB_LEARNING + * - IX_ETH_DB_FILTERING + * + * All other features are disabled by default and require manual enabling using ixEthDBFeatureEnable. + * + * Default settings for VLAN, QoS, Firewall and WiFi header conversion features: + * + * VLAN + * + * When the VLAN/QoS feature is enabled for a port for the first time the default VLAN behavior + * of the port is set to be as permissive (it will accept all the frames) and + * non-interferential (it will not change any frames) as possible: + * - the port VLAN ID (VID) is set to 0 + * - the Ingress acceptable frame filter is set to accept all frames + * - the VLAN port membership is set to the complete VLAN range (0 - 4094) + * - the Ingress tagging mode is set to pass-through (will not change frames) + * - the Egress tagging mode is to send tagged frames in the entire VLAN range (0 - 4094) + * + * Note that further disabling and re-enabling the VLAN feature for a given port will not reset the port VLAN behavior + * to the settings listed above. Any VLAN settings made by the user are kept. + * + * QoS + * + * The following default priority mapping table will be used (as per IEEE 802.1Q and IEEE 802.1D): + * + * + *
QoS traffic classes
QoS priority Default traffic class Traffic type + *
0 1 Best effort, default class for unexpedited traffic + *
1 0 Background traffic + *
2 0 Spare bandwidth + *
3 1 Excellent effort + *
4 2 Controlled load + *
5 2 Video traffic + *
6 3 Voice traffic + *
7 3 Network control + *
+ * + * Firewall + * + * The port firewall is configured by default in black-list mode, and the firewall address table is empty. + * This means the firewall will not filter any frames until the feature is configured and the firewall table is + * downloaded to the NPE. + * + * Spanning Tree + * + * The port is set to STP unblocked mode, therefore it will accept all frames until re-configured. + * + * WiFi header conversion + * + * The WiFi header conversion database is empty, therefore no actual header conversion will take place until this + * feature is configured and the conversion table downloaded to the NPE. + * + * @param portID @ref IxEthDBPortId [in] - ID of the port to enable or disable the features on (use IX_ETH_DB_ALL_PORTS for all the ports) + * @param feature @ref IxEthDBFeature [in] - feature or feature set to enable or disable + * @param enabled BOOL [in] - TRUE to enable the feature and FALSE to disable it + * + * @note Certain features, from a functional point of view, cannot be disabled as such at NPE level; + * when such features are set to disabled using the EthDB API they will be configured in such + * a way to determine a behavior equivalent to the feature being disabled. As well as this, disabled + * features cannot be configured or accessed via the EthDB API (except for getting their status). + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_NO_PERMISSION attempted to enable mutually exclusive features, + * or a feature that depends on another feature which is not present or enabled + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE at least one of the features selected is unavailable + * @retval IX_FAIL unknown OS or NPE communication error + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFeatureEnable(IxEthDBPortId portID, IxEthDBFeature feature, BOOL enabled); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFeatureStatusGet(IxEthDBPortId portID, IxEthDBFeature feature, BOOL *present, BOOL *enabled) + * + * @brief Retrieves the availability and status of a feature set + * + * This function returns the availability and status for a feature set. + * Note that if more than one feature is selected (e.g. IX_ETH_DB_LEARNING | IX_ETH_DB_FILTERING) + * the "present" and "enabled" return values will be set to TRUE only if all the features in the + * feature set are present and enabled (not only some). + * + * @param portID @ref IxEthDBPortId [in] - ID of the port + * @param feature @ref IxEthDBFeature [in] - identifier of the feature to retrieve the status for + * @param present BOOL [out] - location where a boolean flag indicating whether this feature is present will be written to + * @param enabled BOOL [out] - location where a boolean flag indicating whether this feature is enabled will be written to + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG either present or enabled pointer argument is invalid + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFeatureStatusGet(IxEthDBPortId portID, IxEthDBFeature feature, BOOL *present, BOOL *enabled); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFeaturePropertyGet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, IxEthDBPropertyType *type, void *value) + * + * @brief Retrieves the value of a feature property + * + * The EthDB features usually contain feature-specific properties describing or + * controlling how the feature operates. While essential properties (e.g. the + * firewall operating mode) have their own API, secondary properties can be + * retrieved using this function. + * + * Properties can be read-only or read-write. ixEthDBFeaturePropertyGet operates with + * both types of features. + * + * Properties have types associated with them. A descriptor indicating the property + * type is returned in the type argument for convenience. + * + * The currently supported properties and their corresponding features are as follows: + * + * + *
Properties for IX_ETH_DB_VLAN_QOS
Property identifier Property type Property value Read-Only + *
IX_ETH_DB_QOS_TRAFFIC_CLASS_COUNT_PROPERTY IX_ETH_DB_INTEGER_PROPERTY number of internal traffic classes Yes + *
IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY IX_ETH_DB_INTEGER_PROPERTY queue assignment for traffic class 0 Yes + *
IX_ETH_DB_QOS_TRAFFIC_CLASS_1_RX_QUEUE_PROPERTY IX_ETH_DB_INTEGER_PROPERTY queue assignment for traffic class 1 Yes + *
IX_ETH_DB_QOS_TRAFFIC_CLASS_2_RX_QUEUE_PROPERTY IX_ETH_DB_INTEGER_PROPERTY queue assignment for traffic class 2 Yes + *
IX_ETH_DB_QOS_TRAFFIC_CLASS_3_RX_QUEUE_PROPERTY IX_ETH_DB_INTEGER_PROPERTY queue assignment for traffic class 3 Yes + *
IX_ETH_DB_QOS_TRAFFIC_CLASS_4_RX_QUEUE_PROPERTY IX_ETH_DB_INTEGER_PROPERTY queue assignment for traffic class 4 Yes + *
IX_ETH_DB_QOS_TRAFFIC_CLASS_5_RX_QUEUE_PROPERTY IX_ETH_DB_INTEGER_PROPERTY queue assignment for traffic class 5 Yes + *
IX_ETH_DB_QOS_TRAFFIC_CLASS_6_RX_QUEUE_PROPERTY IX_ETH_DB_INTEGER_PROPERTY queue assignment for traffic class 6 Yes + *
IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY IX_ETH_DB_INTEGER_PROPERTY queue assignment for traffic class 7 Yes + *
+ * + * @see ixEthDBFeaturePropertySet + * + * @param portID @ref IxEthDBPortId [in] - ID of the port + * @param feature @ref IxEthDBFeature [in] - EthDB feature for which the property is retrieved + * @param property @ref IxEthDBProperty [in] - property identifier + * @param type @ref IxEthDBPropertyType [out] - location where the property type will be stored + * @param value void [out] - location where the property value will be stored + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_INVALID_ARG invalid property identifier, type or value pointer arguments + * @retval IX_ETH_DB_FAIL incorrect property value or unknown error + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFeaturePropertyGet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, IxEthDBPropertyType *type, void *value); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFeaturePropertySet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, void *value) + * + * @brief Sets the value of a feature property + * + * Unlike @ref ixEthDBFeaturePropertyGet, this function operates only with read-write properties + * + * The currently supported properties and their corresponding features are as follows: + * + * - IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE (for IX_ETH_DB_VLAN_QOS): freezes the availability of traffic classes + * to the number of traffic classes currently in use + * + * Note that this function creates deep copies of the property values; once the function is invoked the client + * can free or reuse the memory area containing the original property value. + * + * Copy behavior for different property types is defined as follows: + * + * - IX_ETH_DB_INTEGER_PROPERTY - 4 bytes are copied from the source location + * - IX_ETH_DB_STRING_PROPERTY - the source string will be copied up to the NULL '\0' string terminator, maximum of 255 characters + * - IX_ETH_DB_MAC_ADDR_PROPERTY - 6 bytes are copied from the source location + * - IX_ETH_DB_BOOL_PROPERTY - 4 bytes are copied from the source location; the only allowed values are TRUE (1L) and false (0L) + * + * @see ixEthDBFeaturePropertySet + * + * @warning IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE is provided for EthAcc internal use; + * do not attempt to set this property directly + * + * @param portID @ref IxEthDBPortId [in] - ID of the port + * @param feature @ref IxEthDBFeature [in] - EthDB feature for which the property is set + * @param property @ref IxEthDBProperty [in] - property identifier + * @param value void [in] - location where the property value is to be copied from + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_INVALID_ARG invalid property identifier, value pointer, or invalid property value + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFeaturePropertySet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, void *value); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBDatabaseClear(IxEthDBPortId portID, IxEthDBRecordType recordType) + * + * @brief Deletes a set of record types from the Ethernet Database + * + * This function deletes all the records of certain types (specified in the recordType filter) + * associated with a port. Additionally, the IX_ETH_DB_ALL_PORTS value can be used as port ID + * to indicate that the specified record types should be deleted for all the ports. + * + * The record type filter can be an ORed combination of the following types: + * + * Record types + * - IX_ETH_DB_FILTERING_RECORD + * + *
Filtering record
MAC address static/dynamic type age
+ * + * - IX_ETH_DB_FILTERING_VLAN_RECORD + * + *
VLAN-enabled filtering record
MAC address static/dynamic type age 802.1Q tag
+ * + * - IX_ETH_DB_WIFI_RECORD + * + *
WiFi header conversion record
MAC address optional gateway MAC address
+ * + * - IX_ETH_DB_FIREWALL_RECORD + * + *
Firewall record
MAC address
+ * - IX_ETH_DB_ALL_RECORD_TYPES + * + * Any combination of the above types is valid e.g. + * + * (IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD | IX_ETH_DB_FIREWALL_RECORD), + * + * although some might be redundant (it is not an error to do so) e.g. + * + * (IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_ALL_RECORD_TYPES) + * + * @param portID @ref IxEthDBPortId [in] - ID of the port + * @param recordType @ref IxEthDBRecordType [in] - record type filter + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_INVALID_ARG invalid recordType filter + * + * @note If the record type filter contains any unrecognized value (hence the + * IX_ETH_DB_INVALID_ARG error value is returned) no actual records will be deleted. + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBDatabaseClear(IxEthDBPortId portID, IxEthDBRecordType recordType); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBWiFiStationEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) + * + * @brief Adds an "Access Point to Station" record to the database, for 802.3 => 802.11 frame + * header conversion + * + * Frame header conversion is controlled by the set of MAC addresses + * added using @ref ixEthDBWiFiStationEntryAdd and @ref ixEthDBWiFiAccessPointEntryAdd. + * Conversion arguments are added using @ref ixEthDBWiFiFrameControlSet, + * @ref ixEthDBWiFiDurationIDSet and @ref ixEthDBWiFiBBSIDSet. + * + * Note that adding the same MAC address twice will not return an error + * (but will not accomplish anything either), while re-adding a record previously added + * as an "Access Point to Access Point" will migrate the record to the "Access Point + * to Station" type. + * + * @param portID @ref IxEthDBPortId [in] - ID of the port + * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to add + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_INVALID_ARG macAddr is an invalid pointer + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled + * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument + * @retval IX_ETH_DB_NOMEM maximum number of records reached + * @retval IX_ETH_DB_BUSY lock condition or transaction in progress, try again later + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBWiFiStationEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBWiFiAccessPointEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr, IxEthDBMacAddr *gatewayMacAddr) + * + * @brief Adds an "Access Point to Access Point" record to the database + * + * @see ixEthDBWiFiStationEntryAdd + * + * Note that adding the same MAC address twice will simply overwrite the previously + * defined gateway MAC address value in the same record, if the record was previously of the + * "Access Point to Access Point" type. + * + * Re-adding a MAC address as "Access Point to Access Point", which was previously added as + * "Access Point to Station" will migrate the record type to "Access Point to Access Point" and + * record the gateway MAC address. + * + * @param portID @ref IxEthDBPortId [in] - ID of the port + * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to add + * @param gatewayMacAddr @ref IxEthDBMacAddr [in] - MAC address of the gateway Access Point + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG macAddr is an invalid pointer + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled + * @retval IX_ETH_DB_INVALID_ARG invalid macAddr or gatewayMacAddr pointer argument + * @retval IX_ETH_DB_NOMEM maximum number of records reached + * @retval IX_ETH_DB_BUSY lock condition or transaction in progress, try again later + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBWiFiAccessPointEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr, IxEthDBMacAddr *gatewayMacAddr); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBWiFiEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) + * + * @brief Removes a WiFi station record + * + * This function removes both types of WiFi records ("Access Point to Station" and + * "Access Point to Access Point"). + * + * @param portID @ref IxEthDBPortId [in] - ID of the port + * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to remove + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument + * @retval IX_ETH_DB_NO_SUCH_ADDR specified address was not found in the database + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled + * @retval IX_ETH_DB_BUSY lock condition or transaction in progress, try again later + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBWiFiEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBWiFiConversionTableDownload(IxEthDBPortId portID) + * + * @brief Downloads the MAC address table for 802.3 => 802.11 frame header + * conversion to the NPE + * + * Note that the frame conversion MAC address table must be individually downloaded + * to each NPE for which the frame header conversion feature is enabled (i.e. it + * is not possible to specify IX_ETH_DB_ALL_PORTS). + * + * @param portID @ref IxEthDBPortId [in] - ID of the port + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled + * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBWiFiConversionTableDownload(IxEthDBPortId portID); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBWiFiFrameControlSet(IxEthDBPortId portID, UINT16 frameControl) + * + * @brief Sets the GlobalFrameControl field + * + * The GlobalFrameControl field is a 2-byte value inserted in the Frame Control + * field for all 802.3 to 802.11 frame header conversions + * + * @param portID @ref IxEthDBPortId [in] - ID of the port + * @param frameControl UINT16 [in] - GlobalFrameControl value + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled + * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBWiFiFrameControlSet(IxEthDBPortId portID, UINT16 frameControl); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBWiFiDurationIDSet(IxEthDBPortId portID, UINT16 durationID) + * + * @brief Sets the GlobalDurationID field + * + * The GlobalDurationID field is a 2-byte value inserted in the Duration/ID + * field for all 802.3 to 802.11 frame header conversions + * + * @param portID @ref IxEthDBPortId [in] - ID of the port + * @param durationID UINT16 [in] - GlobalDurationID field + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled + * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBWiFiDurationIDSet(IxEthDBPortId portID, UINT16 durationID); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBWiFiBBSIDSet(IxEthDBPortId portID, IxEthDBMacAddr *bbsid) + * + * @brief Sets the BBSID field + * + * The BBSID field is a 6-byte value which + * identifies the infrastructure of the service set managed + * by the Access Point having the IXP400 as its processor. The value + * is written in the BBSID field of the 802.11 frame header. + * The BBSID value is the MAC address of the Access Point. + * + * @param portID @ref IxEthDBPortId [in] - ID of the port + * @param bbsid @ref IxEthDBMacAddr [in] - pointer to 6 bytes containing the BSSID + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid bbsid pointer argument + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled + * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBWiFiBBSIDSet(IxEthDBPortId portID, IxEthDBMacAddr *bbsid); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBSpanningTreeBlockingStateSet(IxEthDBPortId portID, BOOL blocked) + * + * @brief Sets the STP blocked/unblocked state for a port + * + * @param portID @ref IxEthDBPortId [in] - ID of the port + * @param blocked BOOL [in] - TRUE to set the port as STP blocked, FALSE to set it as unblocked + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Spanning Tree Protocol feature not enabled + * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBSpanningTreeBlockingStateSet(IxEthDBPortId portID, BOOL blocked); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBSpanningTreeBlockingStateGet(IxEthDBPortId portID, BOOL *blocked) + * + * @brief Retrieves the STP blocked/unblocked state for a port + * + * @param portID @ref IxEthDBPortId [in] - ID of the port + * @param blocked BOOL * [in] - set to TRUE if the port is STP blocked, FALSE otherwise + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid blocked pointer argument + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Spanning Tree Protocol feature not enabled + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBSpanningTreeBlockingStateGet(IxEthDBPortId portID, BOOL *blocked); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFirewallModeSet(IxEthDBPortId portID, IxEthDBFirewallMode mode) + * + * @brief Sets the firewall mode to use white or black listing + * + * When enabled, the NPE MAC address based firewall support operates in two modes: + * + * - white-list mode (MAC address based admission) + * - mode set to IX_ETH_DB_FIREWALL_WHITE_LIST + * - only packets originating from MAC addresses contained in the firewall address list + * are allowed on the Rx path + * - black-list mode (MAC address based blocking) + * - mode set to IX_ETH_DB_FIREWALL_BLACK_LIST + * - packets originating from MAC addresses contained in the firewall address list + * are discarded + * + * @param portID @ref IxEthDBPortId [in] - ID of the port + * @param mode @ref IxEthDBFirewallMode [in] - firewall mode (IX_ETH_DB_FIREWALL_WHITE_LIST or IX_ETH_DB_FIREWALL_BLACK_LIST) + * + * @note by default the firewall operates in black-list mode with an empty address + * list, hence it doesn't filter any packets + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Firewall feature not enabled + * @retval IX_ETH_DB_INVALID_ARGUMENT mode argument is not a valid firewall configuration mode + * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error +*/ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFirewallModeSet(IxEthDBPortId portID, IxEthDBFirewallMode mode); + +/** + * @ingroup IxEthDB + * + * @fn ixEthDBFirewallInvalidAddressFilterEnable(IxEthDBPortId portID, BOOL enable) + * + * @brief Enables or disables invalid MAC address filtering + * + * According to IEEE802 it is illegal for a source address to be a multicast + * or broadcast address. If this feature is enabled the NPE inspects the source + * MAC addresses of incoming frames and discards them if invalid addresses are + * detected. + * + * By default this service is enabled, if the firewall feature is supported by the + * NPE image. + * + * @param portID ID of the port + * @param enable TRUE to enable invalid MAC address filtering and FALSE to disable it + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Firewall feature not enabled + * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFirewallInvalidAddressFilterEnable(IxEthDBPortId portID, BOOL enable); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFirewallEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) + * + * @brief Adds a MAC address to the firewall address list + * + * Note that adding the same MAC address twice will not return an error + * but will not actually accomplish anything. + * + * The firewall MAC address list has a limited number of entries; once + * the maximum number of entries has been reached this function will failed + * to add more addresses, returning IX_ETH_DB_NOMEM. + * + * @param portID @ref IxEthDBPortId [in] - ID of the port + * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to be added + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument + * @retval IX_ETH_DB_NOMEM maximum number of records reached + * @retval IX_ETH_DB_BUSY lock condition or transaction in progress, try again later + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Firewall feature not enabled + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFirewallEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFirewallEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) + * + * @brief Removes a MAC address from the firewall address list + * + * @param portID @ref IxEthDBPortId [in] - ID of the port + * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to be removed + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument + * @retval IX_ETH_DB_NO_SUCH_ADDR address not found + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Firewall feature not enabled + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFirewallEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFirewallTableDownload(IxEthDBPortId portID) + * + * @brief Downloads the MAC firewall table to a port + * + * @param portID ID of the port + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Firewall feature not enabled + * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFirewallTableDownload(IxEthDBPortId portID); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBUserFieldSet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void *field) + * + * @brief Adds a user-defined field to a database record + * + * This function associates a user-defined field to a database record. + * The user-defined field is passed as a (void *) parameter, hence it can be used + * for any purpose (such as identifying a structure). Retrieving the user-defined field from + * a record is done using @ref ixEthDBUserFieldGet. Note that EthDB never uses the user-defined + * field for any internal operation and it is not aware of the significance of its contents. The + * field is only stored as a pointer. + * + * The database record is identified using a combination of the given parameters, depending on the record type. + * All the record types require the record MAC address. + * + * - IX_ETH_DB_FILTERING_RECORD requires only the MAC address + * - IX_ETH_DB_VLAN_FILTERING_RECORD requires the MAC address and the VLAN ID + * - IX_ETH_DB_WIFI_RECORD requires the MAC address and the portID + * - IX_ETH_DB_FIREWALL_RECORD requires the MAC address and the portID + * + * Please note that if a parameter is not required it is completely ignored (it does not undergo parameter checking). + * The user-defined field can be cleared using a NULL field parameter. + * + * @param recordType @ref IxEthDBRecordType [in] - type of record (can be IX_ETH_DB_FILTERING_RECORD, + * IX_ETH_DB_FILTERING_VLAN_RECORD, IX_ETH_DB_WIFI_RECORD or IX_ETH_DB_FIREWALL_RECORD) + * @param portID @ref IxEthDBPortId [in] - ID of the port (required only for WIFI and FIREWALL records) + * @param macAddr @ref IxEthDBMacAddr * [in] - MAC address of the record + * @param vlanID @ref IxEthDBVlanId [in] - VLAN ID of the record (required only for FILTERING_VLAN records) + * @param field void * [in] - user defined field + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID was required but it is not a valid port identifier + * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument + * @retval IX_ETH_DB_NO_SUCH_ADDR record not found + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBUserFieldSet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void *field); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBUserFieldGet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void **field) + * + * @brief Retrieves a user-defined field from a database record + * + * The database record is identified using a combination of the given parameters, depending on the record type. + * All the record types require the record MAC address. + * + * - IX_ETH_DB_FILTERING_RECORD requires only the MAC address + * - IX_ETH_DB_VLAN_FILTERING_RECORD requires the MAC address and the VLAN ID + * - IX_ETH_DB_WIFI_RECORD requires the MAC address and the portID + * - IX_ETH_DB_FIREWALL_RECORD requires the MAC address and the portID + * + * Please note that if a parameter is not required it is completely ignored (it does not undergo parameter checking). + * + * If no user-defined field was registered with the specified record then NULL will be written + * at the location specified by field. + * + * @param recordType type of record (can be IX_ETH_DB_FILTERING_RECORD, IX_ETH_DB_FILTERING_VLAN_RECORD, IX_ETH_DB_WIFI_RECORD + * or IX_ETH_DB_FIREWALL_RECORD) + * @param portID ID of the port (required only for WIFI and FIREWALL records) + * @param macAddr MAC address of the record + * @param vlanID VLAN ID of the record (required only for FILTERING_VLAN records) + * @param field location to write the user defined field into + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID was required but it is not a valid port identifier + * @retval IX_ETH_DB_INVALID_ARG invalid macAddr or field pointer arguments + * @retval IX_ETH_DB_NO_SUCH_ADDR record not found + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBUserFieldGet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portId, IxEthDBVlanId vlanID, void **field); + +/** + * @} + */ + +#endif /* IxEthDB_H */ diff --git a/arch/arm/cpu/ixp/npe/include/IxEthDBLocks_p.h b/arch/arm/cpu/ixp/npe/include/IxEthDBLocks_p.h new file mode 100644 index 0000000000..1d8b24fdf6 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/IxEthDBLocks_p.h @@ -0,0 +1,122 @@ +/** + * @file IxEthAccDBLocks_p.h + * + * @brief Definition of transaction lock stacks and lock utility macros + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#ifndef IxEthAccDBLocks_p_H +#define IxEthAccDBLocks_p_H + +#include "IxOsPrintf.h" + +/* Lock and lock stacks */ +typedef struct +{ + IxOsalFastMutex* locks[MAX_LOCKS]; + UINT32 stackPointer, basePointer; +} LockStack; + +#define TRY_LOCK(mutex) \ + { \ + if (ixOsalFastMutexTryLock(mutex) != IX_SUCCESS) \ + { \ + return IX_ETH_DB_BUSY; \ + } \ + } + + +#define UNLOCK(mutex) { ixOsalFastMutexUnlock(mutex); } + +#define INIT_STACK(stack) \ + { \ + (stack)->basePointer = 0; \ + (stack)->stackPointer = 0; \ + } + +#define PUSH_LOCK(stack, lock) \ + { \ + if ((stack)->stackPointer == MAX_LOCKS) \ + { \ + ERROR_LOG("Ethernet DB: maximum number of elements in a lock stack has been exceeded on push, heavy chaining?\n"); \ + UNROLL_STACK(stack); \ + \ + return IX_ETH_DB_NOMEM; \ + } \ + \ + if (ixOsalFastMutexTryLock(lock) == IX_SUCCESS) \ + { \ + (stack)->locks[(stack)->stackPointer++] = (lock); \ + } \ + else \ + { \ + UNROLL_STACK(stack); \ + \ + return IX_ETH_DB_BUSY; \ + } \ + } + +#define POP_LOCK(stack) \ + { \ + ixOsalFastMutexUnlock((stack)->locks[--(stack)->stackPointer]); \ + } + +#define UNROLL_STACK(stack) \ + { \ + while ((stack)->stackPointer > (stack)->basePointer) \ + { \ + POP_LOCK(stack); \ + } \ + } + +#define SHIFT_STACK(stack) \ + { \ + if ((stack)->basePointer == MAX_LOCKS - 1) \ + { \ + ERROR_LOG("Ethernet DB: maximum number of elements in a lock stack has been exceeded on shift, heavy chaining?\n"); \ + UNROLL_STACK(stack); \ + \ + return IX_ETH_DB_BUSY; \ + } \ + \ + ixOsalFastMutexUnlock((stack)->locks[(stack)->basePointer++]); \ + } + +#endif /* IxEthAccDBLocks_p_H */ diff --git a/arch/arm/cpu/ixp/npe/include/IxEthDBLog_p.h b/arch/arm/cpu/ixp/npe/include/IxEthDBLog_p.h new file mode 100644 index 0000000000..1d6b0bb20d --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/IxEthDBLog_p.h @@ -0,0 +1,227 @@ +/** + * @file IxEthDBLog_p.h + * + * @brief definitions of log macros and log configuration + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#include + +#ifdef IX_UNIT_TEST +#define NULL_PRINT_ROUTINE(format, arg...) /* nothing */ +#else +#define NULL_PRINT_ROUTINE if(0) printf +#endif + +/*************************************************** + * Globals * + ***************************************************/ +/* safe to permanently leave these on */ +#define HAS_ERROR_LOG +#define HAS_ERROR_IRQ_LOG +#define HAS_WARNING_LOG + +/*************************************************** + * Log Configuration * + ***************************************************/ + +/* debug output can be turned on unless specifically + declared as a non-debug build */ +#ifndef NDEBUG + +#undef HAS_EVENTS_TRACE +#undef HAS_EVENTS_VERBOSE_TRACE + +#undef HAS_SUPPORT_TRACE +#undef HAS_SUPPORT_VERBOSE_TRACE + +#undef HAS_NPE_TRACE +#undef HAS_NPE_VERBOSE_TRACE +#undef HAS_DUMP_NPE_TREE + +#undef HAS_UPDATE_TRACE +#undef HAS_UPDATE_VERBOSE_TRACE + +#endif /* NDEBUG */ + + +/*************************************************** + * Log Macros * + ***************************************************/ + +/************** Globals ******************/ + +#ifdef HAS_ERROR_LOG + + #define ERROR_LOG printf + +#else + + #define ERROR_LOG NULL_PRINT_ROUTINE + +#endif + +#ifdef HAS_ERROR_IRQ_LOG + + #define ERROR_IRQ_LOG(format, arg1, arg2, arg3, arg4, arg5, arg6) ixOsalLog(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, format, arg1, arg2, arg3, arg4, arg5, arg6) + +#else + + #define ERROR_IRQ_LOG(format, arg1, arg2, arg3, arg4, arg5, arg6) /* nothing */ + +#endif + +#ifdef HAS_WARNING_LOG + + #define WARNING_LOG printf + +#else + + #define WARNING_LOG NULL_PRINT_ROUTINE + +#endif + +/************** Events *******************/ + +#ifdef HAS_EVENTS_TRACE + + #define IX_ETH_DB_EVENTS_TRACE printf + #define IX_ETH_DB_IRQ_EVENTS_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, format, arg1, arg2, arg3, arg4, arg5, arg6) + + #ifdef HAS_EVENTS_VERBOSE_TRACE + + #define IX_ETH_DB_EVENTS_VERBOSE_TRACE printf + + #else + + #define IX_ETH_DB_EVENTS_VERBOSE_TRACE NULL_PRINT_ROUTINE + + #endif /* HAS_EVENTS_VERBOSE_TRACE */ + +#else + + #define IX_ETH_DB_EVENTS_TRACE NULL_PRINT_ROUTINE + #define IX_ETH_DB_EVENTS_VERBOSE_TRACE NULL_PRINT_ROUTINE + #define IX_ETH_DB_IRQ_EVENTS_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) /* nothing */ + +#endif /* HAS_EVENTS_TRACE */ + +/************** Support *******************/ + +#ifdef HAS_SUPPORT_TRACE + + #define IX_ETH_DB_SUPPORT_TRACE printf + #define IX_ETH_DB_SUPPORT_IRQ_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, format, arg1, arg2, arg3, arg4, arg5, arg6) + + #ifdef HAS_SUPPORT_VERBOSE_TRACE + + #define IX_ETH_DB_SUPPORT_VERBOSE_TRACE printf + + #else + + #define IX_ETH_DB_SUPPORT_VERBOSE_TRACE NULL_PRINT_ROUTINE + + #endif /* HAS_SUPPORT_VERBOSE_TRACE */ + +#else + + #define IX_ETH_DB_SUPPORT_TRACE NULL_PRINT_ROUTINE + #define IX_ETH_DB_SUPPORT_VERBOSE_TRACE NULL_PRINT_ROUTINE + #define IX_ETH_DB_SUPPORT_IRQ_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) /* nothing */ + +#endif /* HAS_SUPPORT_TRACE */ + +/************** NPE Adaptor *******************/ + +#ifdef HAS_NPE_TRACE + + #define IX_ETH_DB_NPE_TRACE printf + #define IX_ETH_DB_NPE_IRQ_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, format, arg1, arg2, arg3, arg4, arg5, arg6) + + #ifdef HAS_NPE_VERBOSE_TRACE + + #define IX_ETH_DB_NPE_VERBOSE_TRACE printf + + #else + + #define IX_ETH_DB_NPE_VERBOSE_TRACE NULL_PRINT_ROUTINE + + #endif /* HAS_NPE_VERBOSE_TRACE */ + +#else + + #define IX_ETH_DB_NPE_TRACE NULL_PRINT_ROUTINE + #define IX_ETH_DB_NPE_VERBOSE_TRACE NULL_PRINT_ROUTINE + #define IX_ETH_DB_NPE_IRQ_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) /* nothing */ + +#endif /* HAS_NPE_TRACE */ + +#ifdef HAS_DUMP_NPE_TREE + +#define IX_ETH_DB_NPE_DUMP_ELT(eltBaseAddress, eltSize) ixEthELTDumpTree(eltBaseAddress, eltSize) + +#else + +#define IX_ETH_DB_NPE_DUMP_ELT(eltBaseAddress, eltSize) /* nothing */ + +#endif /* HAS_DUMP_NPE_TREE */ + +/************** Port Update *******************/ + +#ifdef HAS_UPDATE_TRACE + + #define IX_ETH_DB_UPDATE_TRACE printf + + #ifdef HAS_UPDATE_VERBOSE_TRACE + + #define IX_ETH_DB_UPDATE_VERBOSE_TRACE printf + + #else + + #define IX_ETH_DB_UPDATE_VERBOSE_TRACE NULL_PRINT_ROUTINE + + #endif + +#else /* HAS_UPDATE_VERBOSE_TRACE */ + + #define IX_ETH_DB_UPDATE_TRACE NULL_PRINT_ROUTINE + #define IX_ETH_DB_UPDATE_VERBOSE_TRACE NULL_PRINT_ROUTINE + +#endif /* HAS_UPDATE_TRACE */ diff --git a/arch/arm/cpu/ixp/npe/include/IxEthDBMessages_p.h b/arch/arm/cpu/ixp/npe/include/IxEthDBMessages_p.h new file mode 100644 index 0000000000..ff18160c1f --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/IxEthDBMessages_p.h @@ -0,0 +1,258 @@ +/** + * @file IxEthDBMessages_p.h + * + * @brief Definitions of NPE messages + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#ifndef IxEthDBMessages_p_H +#define IxEthDBMessages_p_H + +#include +#include +#include "IxEthDB_p.h" + +/* events watched by the Eth event processor */ +#define IX_ETH_DB_MIN_EVENT_ID (IX_ETHNPE_EDB_GETMACADDRESSDATABASE) +#define IX_ETH_DB_MAX_EVENT_ID (IX_ETHNPE_PC_SETAPMACTABLE) + +/* macros to fill and extract data from NPE messages - place any endian conversions here */ +#define RESET_ELT_MESSAGE(message) { memset((void *) &(message), 0, sizeof((message))); } +#define NPE_MSG_ID(msg) ((msg).data[0] >> 24) + +#define FILL_SETPORTVLANTABLEENTRY_MSG(message, portID, setOffset, vlanMembershipSet, ttiSet) \ + do { \ + message.data[0] = (IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY << 24) | (portID << 16) | (setOffset * 2); \ + message.data[1] = (vlanMembershipSet << 8) | ttiSet; \ + } while (0); + +#define FILL_SETPORTVLANTABLERANGE_MSG(message, portID, offset, length, zone) \ + do { \ + message.data[0] = IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE << 24 | portID << 16 | offset << 9 | length << 1; \ + message.data[1] = (UINT32) zone; \ + } while (0); + +#define FILL_SETDEFAULTRXVID_MSG(message, portID, tpid, vlanTag) \ + do { \ + message.data[0] = (IX_ETHNPE_VLAN_SETDEFAULTRXVID << 24) \ + | (portID << 16); \ + \ + message.data[1] = (tpid << 16) | vlanTag; \ + } while (0); + +#define FILL_SETRXTAGMODE_MSG(message, portID, filterMode, tagMode) \ + do { \ + message.data[0] = IX_ETHNPE_VLAN_SETRXTAGMODE << 24 \ + | portID << 16 \ + | filterMode << 2 \ + | tagMode; \ + \ + message.data[1] = 0; \ + } while (0); + +#define FILL_SETRXQOSENTRY(message, portID, classIndex, trafficClass, aqmQueue) \ + do { \ + message.data[0] = IX_ETHNPE_VLAN_SETRXQOSENTRY << 24 \ + | portID << 16 \ + | classIndex; \ + \ + message.data[1] = trafficClass << 24 \ + | 0x1 << 23 \ + | aqmQueue << 16 \ + | aqmQueue << 4; \ + } while (0); + +#define FILL_SETPORTIDEXTRACTIONMODE(message, portID, enable) \ + do { \ + message.data[0] = IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE << 24 \ + | portID << 16 \ + | (enable ? 0x1 : 0x0); \ + \ + message.data[1] = 0; \ + } while (0); + + +#define FILL_SETBLOCKINGSTATE_MSG(message, portID, blocked) \ + do { \ + message.data[0] = IX_ETHNPE_STP_SETBLOCKINGSTATE << 24 \ + | portID << 16 \ + | (blocked ? 0x1 : 0x0); \ + \ + message.data[1] = 0; \ + } while (0); + +#define FILL_SETBBSID_MSG(message, portID, bbsid) \ + do { \ + message.data[0] = IX_ETHNPE_PC_SETBBSID << 24 \ + | portID << 16 \ + | bbsid->macAddress[0] << 8 \ + | bbsid->macAddress[1]; \ + \ + message.data[1] = bbsid->macAddress[2] << 24 \ + | bbsid->macAddress[3] << 16 \ + | bbsid->macAddress[4] << 8 \ + | bbsid->macAddress[5]; \ + } while (0); + +#define FILL_SETFRAMECONTROLDURATIONID(message, portID, frameControlDurationID) \ + do { \ + message.data[0] = (IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID << 24) | (portID << 16); \ + message.data[1] = frameControlDurationID; \ + } while (0); + +#define FILL_SETAPMACTABLE_MSG(message, zone) \ + do { \ + message.data[0] = IX_ETHNPE_PC_SETAPMACTABLE << 24 \ + | 0 << 8 /* always use index 0 */ \ + | 64; /* 32 entries, 8 bytes each, 4 bytes in a word */ \ + message.data[1] = (UINT32) zone; \ + } while (0); + +#define FILL_SETFIREWALLMODE_MSG(message, portID, epDelta, mode, address) \ + do { \ + message.data[0] = IX_ETHNPE_FW_SETFIREWALLMODE << 24 \ + | portID << 16 \ + | (epDelta & 0xFF) << 8 \ + | mode; \ + \ + message.data[1] = (UINT32) address; \ + } while (0); + +#define FILL_SETMACADDRESSDATABASE_MSG(message, portID, epDelta, blockCount, address) \ + do { \ + message.data[0] = IX_ETHNPE_EDB_SETMACADDRESSSDATABASE << 24 \ + | (epDelta & 0xFF) << 8 \ + | (blockCount & 0xFF); \ + \ + message.data[1] = (UINT32) address; \ + } while (0); + +#define FILL_GETMACADDRESSDATABASE(message, npeId, zone) \ + do { \ + message.data[0] = IX_ETHNPE_EDB_GETMACADDRESSDATABASE << 24; \ + message.data[1] = (UINT32) zone; \ + } while (0); + +#define FILL_SETMAXFRAMELENGTHS_MSG(message, portID, maxRxFrameSize, maxTxFrameSize) \ + do { \ + message.data[0] = IX_ETHNPE_SETMAXFRAMELENGTHS << 24 \ + | portID << 16 \ + | ((maxRxFrameSize + 63) / 64) << 8 /* max Rx 64-byte blocks */ \ + | (maxTxFrameSize + 63) / 64; /* max Tx 64-byte blocks */ \ + \ + message.data[1] = maxRxFrameSize << 16 | maxTxFrameSize; \ + } while (0); + +#define FILL_SETPORTADDRESS_MSG(message, portID, macAddress) \ + do { \ + message.data[0] = IX_ETHNPE_EDB_SETPORTADDRESS << 24 \ + | portID << 16 \ + | macAddress[0] << 8 \ + | macAddress[1]; \ + \ + message.data[1] = macAddress[2] << 24 \ + | macAddress[3] << 16 \ + | macAddress[4] << 8 \ + | macAddress[5]; \ + } while (0); + +/* access to a MAC node in the NPE tree */ +#define NPE_NODE_BYTE(eltNodeAddr, offset) (((UINT8 *) (eltNodeAddr))[offset]) + +/* browsing of the implicit linear binary tree structure of the NPE tree */ +#define LEFT_CHILD_OFFSET(offset) ((offset) << 1) +#define RIGHT_CHILD_OFFSET(offset) (((offset) << 1) + 1) + +#define IX_EDB_FLAGS_ACTIVE (0x2) +#define IX_EDB_FLAGS_VALID (0x1) +#define IX_EDB_FLAGS_RESERVED (0xfc) +#define IX_EDB_FLAGS_INACTIVE_VALID (0x1) + +#define IX_EDB_NPE_NODE_ELT_PORT_ID_OFFSET (6) +#define IX_EDB_NPE_NODE_ELT_FLAGS_OFFSET (7) +#define IX_EDB_NPE_NODE_WIFI_INDEX_OFFSET (6) +#define IX_EDB_NPE_NODE_WIFI_FLAGS_OFFSET (7) +#define IX_EDB_NPE_NODE_FW_FLAGS_OFFSET (1) +#define IX_EDB_NPE_NODE_FW_RESERVED_OFFSET (6) +#define IX_EDB_NPE_NODE_FW_ADDR_OFFSET (2) + +#define IX_EDB_NPE_NODE_VALID(address) ((NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_FLAGS_OFFSET) & IX_EDB_FLAGS_VALID) != 0) +#define IX_EDB_NPE_NODE_ACTIVE(address) ((NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_FLAGS_OFFSET) & IX_EDB_FLAGS_ACTIVE) != 0) +#define IX_EDB_NPE_NODE_PORT_ID(address) (NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_PORT_ID_OFFSET)) + +/* macros to send messages to the NPEs */ +#define IX_ETHDB_ASYNC_SEND_NPE_MSG(npeId, msg, result) \ + do { \ + result = ixNpeMhMessageSend(npeId, msg, IX_NPEMH_SEND_RETRIES_DEFAULT); \ + \ + if (result != IX_SUCCESS) \ + { \ + ERROR_LOG("DB: Failed to send NPE message\n"); \ + } \ + } while (0); + +#define IX_ETHDB_SYNC_SEND_NPE_MSG(npeId, msg, result) \ + do { \ + result = ixNpeMhMessageWithResponseSend(npeId, msg, msg.data[0] >> 24, ixEthDBNpeMsgAck, IX_NPEMH_SEND_RETRIES_DEFAULT); \ + \ + if (result == IX_SUCCESS) \ + { \ + result = ixOsalMutexLock(&ixEthDBPortInfo[IX_ETH_DB_NPE_TO_PORT_ID(npeId)].npeAckLock, IX_ETH_DB_NPE_TIMEOUT); \ + \ + if (result != IX_SUCCESS) \ + { \ + ERROR_LOG("DB: NPE failed to respond within %dms\n", IX_ETH_DB_NPE_TIMEOUT); \ + } \ + } \ + else \ + { \ + ERROR_LOG("DB: Failed to send NPE message\n"); \ + } \ + } while (0); + +#ifndef IX_NDEBUG +#define IX_ETH_DB_NPE_MSG_HISTORY_DEPTH (100) +extern IX_ETH_DB_PUBLIC UINT32 npeMsgHistory[IX_ETH_DB_NPE_MSG_HISTORY_DEPTH][2]; +extern IX_ETH_DB_PUBLIC UINT32 npeMsgHistoryLen; +#endif + +#define IX_ETHDB_SEND_NPE_MSG(npeId, msg, result) { LOG_NPE_MSG(msg); IX_ETHDB_SYNC_SEND_NPE_MSG(npeId, msg, result); } + +#endif /* IxEthDBMessages_p_H */ diff --git a/arch/arm/cpu/ixp/npe/include/IxEthDBPortDefs.h b/arch/arm/cpu/ixp/npe/include/IxEthDBPortDefs.h new file mode 100644 index 0000000000..c3acbdddef --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/IxEthDBPortDefs.h @@ -0,0 +1,163 @@ +/** + * @file IxEthDBPortDefs.h + * + * @brief Public definition of the ports and port capabilities + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +/** + * @defgroup IxEthDBPortDefs IXP400 Ethernet Database Port Definitions (IxEthDBPortDefs) + * + * @brief IXP400 Public definition of the ports and port capabilities + * + * @{ + */ + +#ifndef IxEthDBPortDefs_H +#define IxEthDBPortDefs_H + +/** + * @brief Port types - currently only Ethernet NPEs are recognized as specific types + * All other (user-defined) ports must be specified as IX_ETH_GENERIC + */ +typedef enum +{ + IX_ETH_GENERIC = 0, /**< generic ethernet port */ + IX_ETH_NPE /**< specific Ethernet NPE */ +} IxEthDBPortType; + +/** + * @brief Port capabilities - used by ixEthAccDatabaseMaintenance to decide whether it + * should manually age entries or not depending on the port capabilities. + * + * Ethernet NPEs have aging capabilities, meaning that they will age the entries + * automatically (by themselves).*/ +typedef enum +{ + IX_ETH_NO_CAPABILITIES = 0, /**< no aging capabilities */ + IX_ETH_ENTRY_AGING = 0x1 /**< aging capabilities present */ +} IxEthDBPortCapability; + +/** + * @brief Port Definition - a structure contains the Port type and capabilities + */ +typedef struct +{ + IxEthDBPortType type; + IxEthDBPortCapability capabilities; +} IxEthDBPortDefinition; + +/** + * @brief Port definitions structure, indexed on the port ID + * @warning Ports 0 and 1 are used by the Ethernet access component therefore + * it is essential to be left untouched. Port 2 here (WAN) is given as + * an example port. The NPE firmware also assumes the NPE B to be + * the port 0 and NPE C to be the port 1. + * + * @note that only 32 ports (0..31) are supported by EthDB + */ +static const IxEthDBPortDefinition ixEthDBPortDefinitions[] = +{ + /* id type capabilities */ + { /* 0 */ IX_ETH_NPE, IX_ETH_NO_CAPABILITIES }, /* Ethernet NPE B */ + { /* 1 */ IX_ETH_NPE, IX_ETH_NO_CAPABILITIES }, /* Ethernet NPE C */ + { /* 2 */ IX_ETH_NPE, IX_ETH_NO_CAPABILITIES }, /* Ethernet NPE A */ + { /* 3 */ IX_ETH_GENERIC, IX_ETH_NO_CAPABILITIES }, /* WAN port */ +}; + +/** + * @def IX_ETH_DB_NUMBER_OF_PORTS + * @brief number of supported ports + */ +#define IX_ETH_DB_NUMBER_OF_PORTS (sizeof (ixEthDBPortDefinitions) / sizeof (ixEthDBPortDefinitions[0])) + +/** + * @def IX_ETH_DB_UNKNOWN_PORT + * @brief definition of an unknown port + */ +#define IX_ETH_DB_UNKNOWN_PORT (0xff) + +/** + * @def IX_ETH_DB_ALL_PORTS + * @brief Special port ID indicating all the ports + * @note This port ID can be used only by a subset of the EthDB API; each + * function specifically mentions whether this is a valid parameter as the port ID + */ +#define IX_ETH_DB_ALL_PORTS (IX_ETH_DB_NUMBER_OF_PORTS + 1) + +/** + * @def IX_ETH_DB_PORTS_ASSERTION + * @brief catch invalid port definitions (<2) with a + * compile-time assertion resulting in a duplicate case error. + */ +#define IX_ETH_DB_PORTS_ASSERTION { switch(0) { case 0 : ; case 1 : ; case IX_ETH_DB_NUMBER_OF_PORTS : ; }} + +/** + * @def IX_ETH_DB_CHECK_PORT(portID) + * @brief safety checks to verify whether the port is invalid or uninitialized + */ +#define IX_ETH_DB_CHECK_PORT(portID) \ +{ \ + if ((portID) >= IX_ETH_DB_NUMBER_OF_PORTS) \ + { \ + return IX_ETH_DB_INVALID_PORT; \ + } \ + \ + if (!ixEthDBPortInfo[(portID)].enabled) \ + { \ + return IX_ETH_DB_PORT_UNINITIALIZED; \ + } \ +} + +/** + * @def IX_ETH_DB_CHECK_PORT_ALL(portID) + * @brief safety checks to verify whether the port is invalid or uninitialized; + * tolerates the use of IX_ETH_DB_ALL_PORTS + */ +#define IX_ETH_DB_CHECK_PORT_ALL(portID) \ +{ \ + if ((portID) != IX_ETH_DB_ALL_PORTS) \ + IX_ETH_DB_CHECK_PORT(portID) \ +} + +#endif /* IxEthDBPortDefs_H */ +/** + *@} + */ diff --git a/arch/arm/cpu/ixp/npe/include/IxEthDBQoS.h b/arch/arm/cpu/ixp/npe/include/IxEthDBQoS.h new file mode 100644 index 0000000000..6d34889452 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/IxEthDBQoS.h @@ -0,0 +1,154 @@ +/** + * @file IxEthDBQoS.h + * + * @brief Public definitions for QoS traffic classes + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +/** + * @defgroup IxEthDBPortDefs IXP400 Ethernet QoS definitions + * + * @brief IXP00 Public definitions for QoS traffic classes + * + * @{ + */ + +#ifndef IxEthDBQoS_H +#define IxEthDBQoS_H + +/** + * @def IX_ETH_DB_QUEUE_UNAVAILABLE + * @brief alias to indicate a queue (traffic class) is not available + */ +#define IX_ETH_DB_QUEUE_UNAVAILABLE (0) + +#ifndef IX_IEEE802_1Q_QOS_PRIORITY_COUNT +/** + * @def IX_IEEE802_1Q_QOS_PRIORITY_COUNT + * @brief number of QoS priorities, according to IEEE 802.1Q + */ +#define IX_IEEE802_1Q_QOS_PRIORITY_COUNT (8) +#endif + +/** + * @brief array containing all the supported traffic class configurations + */ +static const +UINT8 ixEthDBQueueAssignments[][IX_IEEE802_1Q_QOS_PRIORITY_COUNT] = +{ + { 4, 5, 6, 7, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE }, + { 15, 16, 17, 18, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE }, + { 11, 23, 26, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE }, + { 4, 5, 6, 7, 8, 9, 10, 11 } + /* add here all other cases of queue configuration structures and update ixEthDBTrafficClassDefinitions to use them */ +}; + +/** + * @brief value used to index the NPE A functionality ID in the traffic class definition table + */ +#define IX_ETH_DB_NPE_A_FUNCTIONALITY_ID_INDEX (0) + +/** + * @brief value used to index the traffic class count in the traffic class definition table + */ +#define IX_ETH_DB_TRAFFIC_CLASS_COUNT_INDEX (1) + +/** + * @brief value used to index the queue assignment index in the traffic class definition table + */ +#define IX_ETH_DB_QUEUE_ASSIGNMENT_INDEX (2) + +/** + * @brief traffic class definitions + * + * This array contains the default traffic class definition configuration, + * as well as any special cases dictated by the functionality ID of NPE A. + * + * The default case should not be removed (otherwise the Ethernet + * components will assert a fatal failure on initialization). + */ +static const +UINT8 ixEthDBTrafficClassDefinitions[][3] = +{ + /* NPE A functionality ID | traffic class count | queue assignment index (points to the queue enumeration in ixEthDBQueueAssignments) */ + { 0x00, 4, 0 }, /* default case - DO NOT REMOVE */ + { 0x04, 4, 1 }, /* NPE A image ID 0.4.0.0 */ + { 0x09, 3, 2 }, /* NPE A image ID 0.9.0.0 */ + { 0x80, 8, 3 }, /* NPE A image ID 10.80.02.0 */ + { 0x81, 8, 3 }, /* NPE A image ID 10.81.02.0 */ + { 0x82, 8, 3 } /* NPE A image ID 10.82.02.0 */ +}; + +/** + * @brief IEEE 802.1Q recommended QoS Priority => traffic class maps + * + * @verbatim + Number of available traffic classes + 1 2 3 4 5 6 7 8 + QoS Priority + 0 0 0 0 1 1 1 1 2 + 1 0 0 0 0 0 0 0 0 + 2 0 0 0 0 0 0 0 1 + 3 0 0 0 1 1 2 2 3 + 4 0 1 1 2 2 3 3 4 + 5 0 1 1 2 3 4 4 5 + 6 0 1 2 3 4 5 5 6 + 7 0 1 2 3 4 5 6 7 + + @endverbatim + */ +static const +UINT8 ixEthIEEE802_1QUserPriorityToTrafficClassMapping[IX_IEEE802_1Q_QOS_PRIORITY_COUNT][IX_IEEE802_1Q_QOS_PRIORITY_COUNT] = + { + { 0, 0, 0, 0, 0, 0, 0, 0 }, /* 1 traffic class available */ + { 0, 0, 0, 0, 1, 1, 1, 1 }, /* 2 traffic classes available */ + { 0, 0, 0, 0, 1, 1, 2, 2 }, /* 3 traffic classes available */ + { 1, 0, 0, 1, 2, 2, 3, 3 }, /* 4 traffic classes available */ + { 1, 0, 0, 1, 2, 3, 4, 4 }, /* 5 traffic classes available */ + { 1, 0, 0, 2, 3, 4, 5, 5 }, /* 6 traffic classes available */ + { 1, 0, 0, 2, 3, 4, 5, 6 }, /* 7 traffic classes available */ + { 2, 0, 1, 3, 4, 5, 6, 7 } /* 8 traffic classes available */ + }; + +#endif /* IxEthDBQoS_H */ + +/** + *@} + */ diff --git a/arch/arm/cpu/ixp/npe/include/IxEthDB_p.h b/arch/arm/cpu/ixp/npe/include/IxEthDB_p.h new file mode 100644 index 0000000000..ccec7ea7be --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/IxEthDB_p.h @@ -0,0 +1,710 @@ +/** + * @file IxEthDB_p.h + * + * @brief Private MAC learning API + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#ifndef IxEthDB_p_H +#define IxEthDB_p_H + +#include +#include +#include +#include +#include + +#include "IxEthDBMessages_p.h" +#include "IxEthDBLog_p.h" + +#if (CPU==SIMSPARCSOLARIS) + +/* when running unit tests intLock() won't protect the event queue so we lock it manually */ +#define TEST_FIXTURE_LOCK_EVENT_QUEUE { ixOsalMutexLock(&eventQueueLock, IX_OSAL_WAIT_FOREVER); } +#define TEST_FIXTURE_UNLOCK_EVENT_QUEUE { ixOsalMutexUnlock(&eventQueueLock); } + +#else + +#define TEST_FIXTURE_LOCK_EVENT_QUEUE /* nothing */ +#define TEST_FIXTURE_UNLOCK_EVENT_QUEUE /* nothing */ + +#endif /* #if(CPU==SIMSPARCSOLARIS) */ + +#ifndef IX_UNIT_TEST + +#define TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER /* nothing */ +#define TEST_FIXTURE_MARK_OVERFLOW_EVENT /* nothing */ + +#else + +extern int dbAccessCounter; +extern int overflowEvent; + +#define TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER { dbAccessCounter++; } +#define TEST_FIXTURE_MARK_OVERFLOW_EVENT { overflowEvent = 1; } + +#endif + +/* code readability markers */ +#define __mempool__ /* memory pool marker */ +#define __lock__ /* hash write locking marker */ +#define __smartpointer__ /* smart pointer marker - warning: use only clone() when duplicating! */ +#define __alignment__ /* marker for data used only as alignment zones */ + +/* constants */ +#define IX_ETH_DB_NPE_TIMEOUT (100) /* NPE response timeout, in ms */ + +/** + * number of hash table buckets + * it should be at least 8x the predicted number of entries for performance + * each bucket needs 8 bytes + */ +#define NUM_BUCKETS (8192) + +/** + * number of hash table buckets to preload when incrementing bucket iterator + * = two cache lines + */ +#define IX_ETHDB_CACHE_LINE_AHEAD (2) + +#define IX_ETHDB_BUCKETPTR_AHEAD ((IX_ETHDB_CACHE_LINE_AHEAD * IX_OSAL_CACHE_LINE_SIZE)/sizeof(void *)) + +#define IX_ETHDB_BUCKET_INDEX_MASK (((IX_OSAL_CACHE_LINE_SIZE)/sizeof(void *)) - 1) + +/* locks */ +#define MAX_LOCKS (20) /**< maximum number of locks used simultaneously, do not tamper with */ + +/* learning tree constants */ +#define INITIAL_ELT_SIZE (8) /**< initial byte size of tree (empty unused root size) */ +#define MAX_ELT_SIZE (512) /**< maximum number of entries (includes unused root) */ +#define MAX_GW_SIZE (32) /**< maximum number of gateway entries (including unused root) */ +#define MAX_FW_SIZE (32) /**< maximum number of firewall entries (including unused root) */ +#define ELT_ENTRY_SIZE (8) /**< entry size, in bytes */ +#define ELT_ROOT_OFFSET (ELT_ENTRY_SIZE) /**< tree root offset, in bytes - node preceeding root is unused */ +#define FULL_ELT_BYTE_SIZE (MAX_ELT_SIZE * ELT_ENTRY_SIZE) /**< full size of tree, in bytes, including unused root */ +#define FULL_GW_BYTE_SIZE (MAX_GW_SIZE * ELT_ENTRY_SIZE) /**< full size of gateway list, in bytes, including unused root */ +#define FULL_FW_BYTE_SIZE (MAX_FW_SIZE * ELT_ENTRY_SIZE) /**< full size of firewall table, in bytes, including unused root */ + +/* maximum size of the VLAN table: + * 4096 bits (one per VLAN) + * 8 bits in one byte + * interleaved VLAN membership and VLAN TTI (*2) */ +#define FULL_VLAN_BYTE_SIZE (4096 / 8 * 2) + +/* upper 9 bits used as set index, lower 3 bits as byte index */ +#define VLAN_SET_OFFSET(vlanID) ((vlanID) >> 3) +#define VLAN_SET_MASK(vlanID) (0x7 - ((vlanID) & 0x7)) + +/* Update zone definitions */ +#define NPE_TREE_MEM_SIZE (4096) /* ((511 entries + 1 unused root) * 8 bytes/entry) */ + +/* check the above value, we rely on 4k */ +#if NPE_TREE_MEM_SIZE != 4096 + #error NPE_TREE_MEM_SIZE is not defined to 4096 bytes! +#endif + +/* Size Filtering limits (Jumbo frame filtering) */ +#define IX_ETHDB_MAX_FRAME_SIZE 65535 /* other ports than NPE ports */ +#define IX_ETHDB_MIN_FRAME_SIZE 1 /* other ports than NPE ports */ +#define IX_ETHDB_MAX_NPE_FRAME_SIZE 16320 /* NPE ports firmware limit */ +#define IX_ETHDB_MIN_NPE_FRAME_SIZE 1 /* NPE ports firmware limit */ +#define IX_ETHDB_DEFAULT_FRAME_SIZE 1522 + +/* memory management pool sizes */ + +/* + * Note: + * + * NODE_POOL_SIZE controls the maximum number of elements in the database at any one time. + * It should be large enough to cover all the search trees of all the ports simultaneously. + * + * MAC_POOL_SIZE should be higher than NODE_POOL_SIZE by at least the total number of MAC addresses + * possible to be held at any time in all the ports. + * + * TREE_POOL_SIZE should follow the same guideline as for MAC_POOL_SIZE. + * + * The database structure described here (2000/4000/4000) is enough for two NPEs holding at most 511 + * entries each plus one PCI NIC holding at most 900 entries. + */ + +#define NODE_POOL_SIZE (2000) /**< number of HashNode objects - also master number of elements in the database; each entry has 16 bytes */ +#define MAC_POOL_SIZE (4000) /**< number of MacDescriptor objects; each entry has 28 bytes */ +#define TREE_POOL_SIZE (4000) /**< number of MacTreeNode objects; each entry has 16 bytes */ + +/* retry policies */ +#define BUSY_RETRY_ENABLED (TRUE) /**< if set to TRUE the API will retry automatically calls returning BUSY */ +#define FOREVER_RETRY (TRUE) /**< if set to TRUE the API will retry forever BUSY calls */ +#define MAX_RETRIES (400) /**< upper retry limit - used only when FOREVER_RETRY is FALSE */ +#define BUSY_RETRY_YIELD (5) /**< ticks to yield for every failed retry */ + +/* event management */ +#define EVENT_QUEUE_SIZE (500) /**< size of the sink collecting events from the Message Handler FIFO */ +#define EVENT_PROCESSING_LIMIT (100) /**< batch processing control size (how many events are extracted from the queue at once) */ + +/* MAC descriptors */ +#define STATIC_ENTRY (TRUE) +#define DYNAMIC_ENTRY (FALSE) + +/* age reset on next maintenance - incrementing by 1 will reset to 0 */ +#define AGE_RESET (0xFFFFFFFF) + +/* dependency maps */ +#define EMPTY_DEPENDENCY_MAP (0) + +/* trees */ +#define RIGHT (1) +#define LEFT (-1) + +/* macros */ +#define IX_ETH_DB_CHECK_PORT_EXISTS(portID) \ +{ \ + if ((portID) >= IX_ETH_DB_NUMBER_OF_PORTS) \ + { \ + return IX_ETH_DB_INVALID_PORT; \ + } \ +} + +#define IX_ETH_DB_CHECK_PORT_INITIALIZED(portID) \ +{ \ + if ((portID) >= IX_ETH_DB_NUMBER_OF_PORTS) \ + { \ + return IX_ETH_DB_INVALID_PORT; \ + } \ + else \ + { \ + if (!ixEthDBPortInfo[portID].initialized) \ + { \ + return IX_ETH_DB_PORT_UNINITIALIZED; \ + } \ + } \ +} + +/* single NPE check */ +#define IX_ETH_DB_CHECK_SINGLE_NPE(portID) \ + if (ixEthDBSingleEthNpeCheck(portID) != IX_ETH_DB_SUCCESS) \ + { \ + WARNING_LOG("EthDB: port ID %d is unavailable\n",(UINT32) portID); \ + \ + return IX_ETH_DB_INVALID_PORT; \ + } + +/* feature check */ +#define IX_ETH_DB_CHECK_FEATURE(portID, feature) \ + if ((ixEthDBPortInfo[portID].featureStatus & feature) == 0) \ + { \ + return IX_ETH_DB_FEATURE_UNAVAILABLE; \ + } + +/* busy retrying */ +#define BUSY_RETRY(functionCall) \ + { \ + UINT32 retries = 0; \ + IxEthDBStatus br_result; \ + \ + while ((br_result = functionCall) == IX_ETH_DB_BUSY \ + && BUSY_RETRY_ENABLED && (FOREVER_RETRY || ++retries < MAX_RETRIES)) { ixOsalSleep(BUSY_RETRY_YIELD); }; \ + \ + if ((!FOREVER_RETRY && retries == MAX_RETRIES) || (br_result == IX_ETH_DB_FAIL)) \ + {\ + ERROR_LOG("Ethernet Learning Database Error: BUSY_RETRY failed at %s:%d\n", __FILE__, __LINE__); \ + }\ + } + +#define BUSY_RETRY_WITH_RESULT(functionCall, brwr_result) \ + { \ + UINT32 retries = 0; \ + \ + while ((brwr_result = functionCall) == IX_ETH_DB_BUSY \ + && BUSY_RETRY_ENABLED && (FOREVER_RETRY || ++retries < MAX_RETRIES)) { ixOsalSleep(BUSY_RETRY_YIELD); }; \ + \ + if ((!FOREVER_RETRY && retries == MAX_RETRIES) || (brwr_result == IX_ETH_DB_FAIL)) \ + {\ + ERROR_LOG("Ethernet Learning Database Error: BUSY_RETRY_WITH_RESULT failed at %s:%d\n", __FILE__, __LINE__); \ + }\ + } + +/* iterators */ +#define IS_ITERATOR_VALID(iteratorPtr) ((iteratorPtr)->node != NULL) + +/* dependency port maps */ + +/* Warning: if port indexing starts from 1 replace (portID) with (portID - 1) in DEPENDENCY_MAP (and make sure IX_ETH_DB_NUMBER_OF_PORTS is big enough) */ + +/* gives an empty dependency map */ +#define SET_EMPTY_DEPENDENCY_MAP(map) { int i = 0; for (; i < 32 ; i++) map[i] = 0; } + +#define IS_EMPTY_DEPENDENCY_MAP(result, map) { int i = 0 ; result = TRUE; for (; i < 32 ; i++) if (map[i] != 0) { result = FALSE; break; }} + +/** + * gives a map consisting only of 'portID' + */ +#define SET_DEPENDENCY_MAP(map, portID) {SET_EMPTY_DEPENDENCY_MAP(map); map[portID >> 3] = 1 << (portID & 0x7);} + +/** + * gives a map resulting from joining map1 and map2 + */ +#define JOIN_MAPS(map, map1, map2) { int i = 0; for (; i < 32 ; i++) map[i] = map1[i] | map2[i]; } + +/** + * gives the map resulting from joining portID and map + */ +#define JOIN_PORT_TO_MAP(map, portID) { map[portID >> 3] |= 1 << (portID & 0x7); } + +/** + * gives the map resulting from excluding portID from map + */ +#define EXCLUDE_PORT_FROM_MAP(map, portID) { map[portID >> 3] &= ~(1 << (portID & 0x7); } + +/** + * returns TRUE if map1 is a subset of map2 and FALSE otherwise + */ +#define IS_MAP_SUBSET(result, map1, map2) { int i = 0; result = TRUE; for (; i < 32 ; i++) if ((map1[i] | map2[i]) != map2[i]) result = FALSE; } + +/** + * returns TRUE is portID is part of map and FALSE otherwise + */ +#define IS_PORT_INCLUDED(portID, map) ((map[portID >> 3] & (1 << (portID & 0x7))) != 0) + +/** + * returns the difference between map1 and map2 (ports included in map1 and not included in map2) + */ +#define DIFF_MAPS(map, map1, map2) { int i = 0; for (; i < 32 ; i++) map[i] = map1[i] ^ (map1[i] & map2[i]); } + +/** + * returns TRUE if the maps collide (have at least one port in common) and FALSE otherwise + */ +#define MAPS_COLLIDE(result, map1, map2) { int i = 0; result = FALSE; for (; i < 32 ; i++) if ((map1[i] & map2[i]) != 0) result = TRUE; } + +/* size (number of ports) of a dependency map */ +#define GET_MAP_SIZE(map, size) { int i = 0, b = 0; size = 0; for (; i < 32 ; i++) { char y = map[i]; for (; b < 8 && (y >>= 1); b++) size += (y & 1); }} + +/* copy map2 into map1 */ +#define COPY_DEPENDENCY_MAP(map1, map2) { memcpy (map1, map2, sizeof (map1)); } + +/* definition of a port map size/port number which cannot be reached (we support at most 32 ports) */ +#define MAX_PORT_SIZE (0xFF) +#define MAX_PORT_NUMBER (0xFF) + +#define IX_ETH_DB_CHECK_REFERENCE(ptr) { if ((ptr) == NULL) { return IX_ETH_DB_INVALID_ARG; } } +#define IX_ETH_DB_CHECK_MAP(portID, map) { if (!IS_PORT_INCLUDED(portID, map)) { return IX_ETH_DB_INVALID_ARG; } } + +/* event queue macros */ +#define EVENT_QUEUE_WRAP(offset) ((offset) >= EVENT_QUEUE_SIZE ? (offset) - EVENT_QUEUE_SIZE : (offset)) + +#define CAN_ENQUEUE(eventQueuePtr) ((eventQueuePtr)->length < EVENT_QUEUE_SIZE) + +#define QUEUE_HEAD(eventQueuePtr) (&(eventQueuePtr)->queue[EVENT_QUEUE_WRAP((eventQueuePtr)->base + (eventQueuePtr)->length)]) + +#define QUEUE_TAIL(eventQueuePtr) (&(eventQueuePtr)->queue[(eventQueuePtr)->base]) + +#define PUSH_UPDATE_QUEUE(eventQueuePtr) { (eventQueuePtr)->length++; } + +#define SHIFT_UPDATE_QUEUE(eventQueuePtr) \ + { \ + (eventQueuePtr)->base = EVENT_QUEUE_WRAP((eventQueuePtr)->base + 1); \ + (eventQueuePtr)->length--; \ + } + +#define RESET_QUEUE(eventQueuePtr) \ + { \ + (eventQueuePtr)->base = 0; \ + (eventQueuePtr)->length = 0; \ + } + +/* node stack macros - used to browse a tree without using a recursive function */ +#define NODE_STACK_INIT(stack) { (stack)->nodeCount = 0; } +#define NODE_STACK_PUSH(stack, node, offset) { (stack)->nodes[(stack)->nodeCount] = (node); (stack)->offsets[(stack)->nodeCount++] = (offset); } +#define NODE_STACK_POP(stack, node, offset) { (node) = (stack)->nodes[--(stack)->nodeCount]; offset = (stack)->offsets[(stack)->nodeCount]; } +#define NODE_STACK_NONEMPTY(stack) ((stack)->nodeCount != 0) + +#ifndef IX_NDEBUG +#define IX_ETH_DB_NPE_MSG_HISTORY_DEPTH (100) +#define LOG_NPE_MSG(msg) \ + do { \ + UINT32 npeMsgHistoryIndex = (npeMsgHistoryLen++) % IX_ETH_DB_NPE_MSG_HISTORY_DEPTH; \ + npeMsgHistory[npeMsgHistoryIndex][0] = msg.data[0]; \ + npeMsgHistory[npeMsgHistoryIndex][1] = msg.data[1]; \ + } while (0); +#else +#define LOG_NPE_MSG() /* nothing */ +#endif + +/* ----------- Data -------------- */ + +/* typedefs */ + +typedef UINT32 (*HashFunction)(void *entity); +typedef BOOL (*MatchFunction)(void *reference, void *entry); +typedef void (*FreeFunction)(void *entry); + +/** + * basic component of a hash table + */ +typedef struct HashNode_t +{ + void *data; /**< specific data */ + struct HashNode_t *next; /**< used for bucket chaining */ + + __mempool__ struct HashNode_t *nextFree; /**< memory pool management */ + + __lock__ IxOsalFastMutex lock; /**< node lock */ +} HashNode; + +/** + * @brief hash table iterator definition + * + * an iterator is an object which can be used + * to browse a hash table + */ +typedef struct +{ + UINT32 bucketIndex; /**< index of the currently iterated bucket */ + HashNode *previousNode; /**< reference to the previously iterated node within the current bucket */ + HashNode *node; /**< reference to the currently iterated node */ +} HashIterator; + +/** + * definition of a MAC descriptor (a database record) + */ + +typedef enum +{ + IX_ETH_DB_WIFI_AP_TO_STA = 0x0, + IX_ETH_DB_WIFI_AP_TO_AP = 0x1 +} IxEthDBWiFiRecordType; + +typedef union +{ + struct + { + UINT32 age; + BOOL staticEntry; /**< TRUE if this address is static (doesn't age) */ + } filteringData; + + struct + { + UINT32 age; + BOOL staticEntry; + UINT32 ieee802_1qTag; + } filteringVlanData; + + struct + { + IxEthDBWiFiRecordType type; /**< AP_TO_AP (0x1) or AP_TO_STA (0x0) */ + UINT32 gwAddressIndex; /**< used only when linearizing the entries for NPE usage */ + UINT8 gwMacAddress[IX_IEEE803_MAC_ADDRESS_SIZE]; + + __alignment__ UINT8 reserved2[2]; + } wifiData; +} IxEthDBRecordData; + +typedef struct MacDescriptor_t +{ + UINT8 macAddress[IX_IEEE803_MAC_ADDRESS_SIZE]; + + __alignment__ UINT8 reserved1[2]; + + UINT32 portID; + IxEthDBRecordType type; + IxEthDBRecordData recordData; + + /* used for internal operations, such as NPE linearization */ + void *internal; + + /* custom user data */ + void *user; + + __mempool__ struct MacDescriptor_t *nextFree; /**< memory pool management */ + __smartpointer__ UINT32 refCount; /**< smart pointer reference counter */ +} MacDescriptor; + +/** + * hash table definition + */ +typedef struct +{ + HashNode *hashBuckets[NUM_BUCKETS]; + UINT32 numBuckets; + + __lock__ IxOsalFastMutex bucketLocks[NUM_BUCKETS]; + + HashFunction entryHashFunction; + MatchFunction *matchFunctions; + FreeFunction freeFunction; +} HashTable; + +typedef enum +{ + IX_ETH_DB_MAC_KEY = 1, + IX_ETH_DB_MAC_PORT_KEY = 2, + IX_ETH_DB_MAC_VLAN_KEY = 3, + IX_ETH_DB_MAX_KEY_INDEX = 3 +} IxEthDBSearchKeyType; + +typedef struct MacTreeNode_t +{ + __smartpointer__ MacDescriptor *descriptor; + struct MacTreeNode_t *left, *right; + + __mempool__ struct MacTreeNode_t *nextFree; +} MacTreeNode; + +typedef IxEthDBStatus (*IxEthDBPortUpdateHandler)(IxEthDBPortId portID, IxEthDBRecordType type); + +typedef void (*IxEthDBNoteWriteFn)(void *address, MacTreeNode *node); + +typedef struct +{ + BOOL updateEnabled; /**< TRUE if updates are enabled for port */ + BOOL userControlled; /**< TRUE if the user has manually used ixEthDBPortUpdateEnableSet */ + BOOL treeInitialized; /**< TRUE if the NPE has received an initial tree */ + IxEthDBPortUpdateHandler updateHandler; /**< port update handler routine */ + void *npeUpdateZone; /**< port update memory zone */ + void *npeGwUpdateZone; /**< port update memory zone for gateways */ + void *vlanUpdateZone; /**< port update memory zone for VLAN tables */ + MacTreeNode *searchTree; /**< internal search tree, in MacTreeNode representation */ + BOOL searchTreePendingWrite; /**< TRUE if searchTree holds a tree pending write to the port */ +} PortUpdateMethod; + +typedef struct +{ + IxEthDBPortId portID; /**< port ID */ + BOOL enabled; /**< TRUE if the port is enabled */ + BOOL agingEnabled; /**< TRUE if aging on this port is enabled */ + BOOL initialized; + IxEthDBPortMap dependencyPortMap; /**< dependency port map for this port */ + PortUpdateMethod updateMethod; /**< update method structure */ + BOOL macAddressUploaded; /**< TRUE if the MAC address was uploaded into the port */ + UINT32 maxRxFrameSize; /**< maximum Rx frame size for this port */ + UINT32 maxTxFrameSize; /**< maximum Rx frame size for this port */ + + UINT8 bbsid[6]; + __alignment__ UINT8 reserved[2]; + UINT32 frameControlDurationID; /**< Frame Control - Duration/ID WiFi control */ + + IxEthDBVlanTag vlanTag; /**< default VLAN tag for port */ + IxEthDBPriorityTable priorityTable; /**< QoS <=> internal priority mapping */ + IxEthDBVlanSet vlanMembership; + IxEthDBVlanSet transmitTaggingInfo; + IxEthDBFrameFilter frameFilter; + IxEthDBTaggingAction taggingAction; + + UINT32 npeFrameFilter; + UINT32 npeTaggingAction; + + IxEthDBFirewallMode firewallMode; + BOOL srcAddressFilterEnabled; + + BOOL stpBlocked; + + IxEthDBFeature featureCapability; + IxEthDBFeature featureStatus; + + UINT32 ixEthDBTrafficClassAQMAssignments[IX_IEEE802_1Q_QOS_PRIORITY_COUNT]; + + UINT32 ixEthDBTrafficClassCount; + + UINT32 ixEthDBTrafficClassAvailable; + + + + __lock__ IxOsalMutex npeAckLock; +} PortInfo; + +/* list of port information structures indexed on port Ids */ +extern IX_ETH_DB_PUBLIC PortInfo ixEthDBPortInfo[IX_ETH_DB_NUMBER_OF_PORTS]; + +typedef enum +{ + IX_ETH_DB_ADD_FILTERING_RECORD = 0xFF0001, + IX_ETH_DB_REMOVE_FILTERING_RECORD = 0xFF0002 +} PortEventType; + +typedef struct +{ + UINT32 eventType; + IxEthDBPortId portID; + IxEthDBMacAddr macAddr; + BOOL staticEntry; +} PortEvent; + +typedef struct +{ + PortEvent queue[EVENT_QUEUE_SIZE]; + UINT32 base; + UINT32 length; +} PortEventQueue; + +typedef struct +{ + IxEthDBPortId portID; /**< originating port */ + MacDescriptor *macDescriptors[MAX_ELT_SIZE]; /**< addresses to be synced into db */ + UINT32 addressCount; /**< number of addresses */ +} TreeSyncInfo; + +typedef struct +{ + MacTreeNode *nodes[MAX_ELT_SIZE]; + UINT32 offsets[MAX_ELT_SIZE]; + UINT32 nodeCount; +} MacTreeNodeStack; + +/* Prototypes */ + +/* ----------- Memory management -------------- */ + +IX_ETH_DB_PUBLIC void ixEthDBInitMemoryPools(void); + +IX_ETH_DB_PUBLIC HashNode* ixEthDBAllocHashNode(void); +IX_ETH_DB_PUBLIC void ixEthDBFreeHashNode(HashNode *); + +IX_ETH_DB_PUBLIC __smartpointer__ MacDescriptor* ixEthDBAllocMacDescriptor(void); +IX_ETH_DB_PUBLIC __smartpointer__ MacDescriptor* ixEthDBCloneMacDescriptor(MacDescriptor *macDescriptor); +IX_ETH_DB_PUBLIC __smartpointer__ void ixEthDBFreeMacDescriptor(MacDescriptor *); + +IX_ETH_DB_PUBLIC __smartpointer__ MacTreeNode* ixEthDBAllocMacTreeNode(void); +IX_ETH_DB_PUBLIC __smartpointer__ MacTreeNode* ixEthDBCloneMacTreeNode(MacTreeNode *); +IX_ETH_DB_PUBLIC __smartpointer__ void ixEthDBFreeMacTreeNode(MacTreeNode *); + +IX_ETH_DB_PUBLIC void ixEthDBPoolFreeMacTreeNode(MacTreeNode *); +IX_ETH_DB_PUBLIC UINT32 ixEthDBSearchTreeUsageGet(MacTreeNode *tree); +IX_ETH_DB_PUBLIC int ixEthDBShowMemoryStatus(void); + +/* Hash Table */ +IX_ETH_DB_PUBLIC void ixEthDBInitHash(HashTable *hashTable, UINT32 numBuckets, HashFunction entryHashFunction, MatchFunction *matchFunctions, FreeFunction freeFunction); + +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBAddHashEntry(HashTable *hashTable, void *entry); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBRemoveHashEntry(HashTable *hashTable, int keyType, void *reference); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBSearchHashEntry(HashTable *hashTable, int keyType, void *reference, HashNode **searchResult); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPeekHashEntry(HashTable *hashTable, int keyType, void *reference); +IX_ETH_DB_PUBLIC void ixEthDBReleaseHashNode(HashNode *node); + +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBInitHashIterator(HashTable *hashTable, HashIterator *iterator); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBIncrementHashIterator(HashTable *hashTable, HashIterator *iterator); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBRemoveEntryAtHashIterator(HashTable *hashTable, HashIterator *iterator); +IX_ETH_DB_PUBLIC void ixEthDBReleaseHashIterator(HashIterator *iterator); + +/* API Support */ +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortAddressSet(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); +IX_ETH_DB_PUBLIC void ixEthDBMaximumFrameSizeAckCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg); + +/* DB Core functions */ +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBInit(void); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBAdd(MacDescriptor *newRecordTemplate, IxEthDBPortMap updateTrigger); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBRemove(MacDescriptor *templateRecord, IxEthDBPortMap updateTrigger); +IX_ETH_DB_PUBLIC HashNode* ixEthDBSearch(IxEthDBMacAddr *macAddress, IxEthDBRecordType typeFilter); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPeek(IxEthDBMacAddr *macAddress, IxEthDBRecordType typeFilter); + +/* Learning support */ +IX_ETH_DB_PUBLIC UINT32 ixEthDBAddressCompare(UINT8 *mac1, UINT8 *mac2); +IX_ETH_DB_PUBLIC BOOL ixEthDBAddressMatch(void *reference, void *entry); +IX_ETH_DB_PUBLIC UINT32 ixEthDBEntryXORHash(void *macDescriptor); +IX_ETH_DB_PUBLIC UINT32 ixEthDBKeyXORHash(void *macAddress); + +/* Port updates */ +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBNPEUpdateHandler(IxEthDBPortId portID, IxEthDBRecordType type); +IX_ETH_DB_PUBLIC void ixEthDBUpdatePortLearningTrees(IxEthDBPortMap triggerPorts); +IX_ETH_DB_PUBLIC void ixEthDBNPEAccessRequest(IxEthDBPortId portID); +IX_ETH_DB_PUBLIC void ixEthDBUpdateLock(void); +IX_ETH_DB_PUBLIC void ixEthDBUpdateUnlock(void); +IX_ETH_DB_PUBLIC MacTreeNode* ixEthDBQuery(MacTreeNode *searchTree, IxEthDBPortMap query, IxEthDBRecordType recordFilter, UINT32 maximumEntries); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBFirewallUpdate(IxEthDBPortId portID, void *address, UINT32 epDelta); + +/* Init/unload */ +IX_ETH_DB_PUBLIC void ixEthDBPortSetAckCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBEventProcessorInit(void); +IX_ETH_DB_PUBLIC void ixEthDBPortInit(IxEthDBPortId portID); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortEnable(IxEthDBPortId portID); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortDisable(IxEthDBPortId portID); +IX_ETH_DB_PUBLIC void ixEthDBNPEUpdateAreasInit(void); +IX_ETH_DB_PUBLIC UINT32 ixEthDBMatchMethodsRegister(MatchFunction *matchFunctions); +IX_ETH_DB_PUBLIC UINT32 ixEthDBRecordSerializeMethodsRegister(void); +IX_ETH_DB_PUBLIC UINT32 ixEthDBUpdateTypeRegister(BOOL *typeArray); +IX_ETH_DB_PUBLIC void ixEthDBNPEUpdateAreasUnload(void); +IX_ETH_DB_PUBLIC void ixEthDBFeatureCapabilityScan(void); +IX_ETH_DB_PUBLIC UINT32 ixEthDBKeyTypeRegister(UINT32 *keyType); + +/* Event processing */ +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBDefaultEventCallbackEnable(IxEthDBPortId portID, BOOL enable); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBTriggerAddPortUpdate(IxEthDBMacAddr *macAddr, IxEthDBPortId portID, BOOL staticEntry); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBTriggerRemovePortUpdate(IxEthDBMacAddr *macAddr, IxEthDBPortId portID); +IX_ETH_DB_PUBLIC void ixEthDBNPEEventCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg); + +/* NPE adaptor */ +IX_ETH_DB_PUBLIC void ixEthDBGetMacDatabaseCbk(IxNpeMhNpeId npeID, IxNpeMhMessage msg); +IX_ETH_DB_PUBLIC void ixEthDBNpeMsgAck(IxNpeMhNpeId npeID, IxNpeMhMessage msg); +IX_ETH_DB_PUBLIC void ixEthDBNPESyncScan(IxEthDBPortId portID, void *eltBaseAddress, UINT32 eltSize); +IX_ETH_DB_PUBLIC void ixEthDBNPETreeWrite(IxEthDBRecordType type, UINT32 totalSize, void *baseAddress, MacTreeNode *tree, UINT32 *blocks, UINT32 *startIndex); +IX_ETH_DB_PUBLIC void ixEthDBNPEGatewayNodeWrite(void *address, MacTreeNode *node); + +/* Other public API functions */ +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBStartLearningFunction(void); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBStopLearningFunction(void); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortUpdateEnableSet(IxEthDBPortId portID, BOOL enableUpdate); + +/* Maximum Tx/Rx public functions */ +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBFilteringPortMaximumRxFrameSizeSet(IxEthDBPortId portID, UINT32 maximumRxFrameSize); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBFilteringPortMaximumTxFrameSizeSet(IxEthDBPortId portID, UINT32 maximumTxFrameSize); + +/* VLAN-related */ +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortVlanTableSet(IxEthDBPortId portID, IxEthDBVlanSet portVlanTable, IxEthDBVlanSet vlanSet); + +/* Record search */ +IX_ETH_DB_PUBLIC BOOL ixEthDBAddressRecordMatch(void *untypedReference, void *untypedEntry); +IX_ETH_DB_PUBLIC BOOL ixEthDBVlanRecordMatch(void *untypedReference, void *untypedEntry); +IX_ETH_DB_PUBLIC BOOL ixEthDBPortRecordMatch(void *untypedReference, void *untypedEntry); +IX_ETH_DB_PUBLIC BOOL ixEthDBNullMatch(void *reference, void *entry); +IX_ETH_DB_PUBLIC HashNode* ixEthDBPortSearch(IxEthDBMacAddr *macAddress, IxEthDBPortId portID, IxEthDBRecordType typeFilter); +IX_ETH_DB_PUBLIC HashNode* ixEthDBVlanSearch(IxEthDBMacAddr *macAddress, IxEthDBVlanId vlanID, IxEthDBRecordType typeFilter); + +/* Utilities */ +IX_ETH_DB_PUBLIC const char* mac2string(const unsigned char *mac); +IX_ETH_DB_PUBLIC void showHashInfo(void); +IX_ETH_DB_PUBLIC int ixEthDBAnalyzeHash(void); +IX_ETH_DB_PUBLIC const char* errorString(IxEthDBStatus error); +IX_ETH_DB_PUBLIC int numHashElements(void); +IX_ETH_DB_PUBLIC void zapHashtable(void); +IX_ETH_DB_PUBLIC BOOL ixEthDBCheckSingleBitValue(UINT32 value); + +/* Single Eth NPE Check */ +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBSingleEthNpeCheck(IxEthDBPortId portId); + +#endif /* IxEthDB_p_H */ + diff --git a/arch/arm/cpu/ixp/npe/include/IxEthMii.h b/arch/arm/cpu/ixp/npe/include/IxEthMii.h new file mode 100644 index 0000000000..397253a947 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/IxEthMii.h @@ -0,0 +1,270 @@ +/** + * @file IxEthMii.h + * + * @brief this file contains the public API of @ref IxEthMii component + * + * Design notes : + * The main intent of this API is to inplement MII high level fonctionalitoes + * to support the codelets provided with the IXP400 software releases. It + * superceedes previous interfaces provided with @ref IxEThAcc component. + * + * This API has been tested with the PHYs provided with the + * IXP400 development platforms. It may not work for specific Ethernet PHYs + * used on specific boards. + * + * This source code detects and interface the LXT972, LXT973 and KS6995 + * Ethernet PHYs. + * + * This source code should be considered as an example which may need + * to be adapted for different hardware implementations. + * + * It is strongly recommended to use public domain and GPL utilities + * like libmii, mii-diag for MII interface support. + * + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#ifndef IxEthMii_H +#define IxEthMii_H + +#include + +/** + * @defgroup IxEthMii IXP400 Ethernet Phy Access (IxEthMii) API + * + * @brief ethMii is a library that does provides access to the + * Ethernet PHYs + * + *@{ + */ + +/** + * @ingroup IxEthMii + * + * @fn ixEthMiiPhyScan(BOOL phyPresent[], UINT32 maxPhyCount) + * + * @brief Scan the MDIO bus for PHYs + * This function scans PHY addresses 0 through 31, and sets phyPresent[n] to + * TRUE if a phy is discovered at address n. + * + * - Reentrant - no + * - ISR Callable - no + * + * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock. + * + * @param phyPresent BOOL [in] - boolean array of IXP425_ETH_ACC_MII_MAX_ADDR entries + * @param maxPhyCount UINT32 [in] - number of PHYs to search for (the scan will stop when + * the indicated number of PHYs is found). + * + * @return IX_STATUS + * - IX_ETH_ACC_SUCCESS + * - IX_ETH_ACC_FAIL : invalid arguments. + * + *
+ */ +PUBLIC IX_STATUS ixEthMiiPhyScan(BOOL phyPresent[], UINT32 maxPhyCount); + +/** + * @ingroup IxEthMii + * + * @fn ixEthMiiPhyConfig(UINT32 phyAddr, + BOOL speed100, + BOOL fullDuplex, + BOOL autonegotiate) + * + * + * @brief Configure a PHY + * Configure a PHY's speed, duplex and autonegotiation status + * + * - Reentrant - no + * - ISR Callable - no + * + * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock. + * + * @param phyAddr UINT32 [in] + * @param speed100 BOOL [in] - set to TRUE for 100Mbit/s operation, FALSE for 10Mbit/s + * @param fullDuplex BOOL [in] - set to TRUE for Full Duplex, FALSE for Half Duplex + * @param autonegotiate BOOL [in] - set to TRUE to enable autonegotiation + * + * @return IX_STATUS + * - IX_SUCCESS + * - IX_FAIL : invalid arguments. + * + *
+ */ +PUBLIC IX_STATUS ixEthMiiPhyConfig(UINT32 phyAddr, + BOOL speed100, + BOOL fullDuplex, + BOOL autonegotiate); + +/** + * @ingroup IxEthMii + * + * @fn ixEthMiiPhyLoopbackEnable(UINT32 phyAddr) + * + * + * @brief Enable PHY Loopback in a specific Eth MII port + * + * @note When PHY Loopback is enabled, frames sent out to the PHY from the + * IXP400 will be looped back to the IXP400. They will not be transmitted out + * on the wire. + * + * - Reentrant - no + * - ISR Callable - no + * + * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31) + * + * @return IX_STATUS + * - IX_SUCCESS + * - IX_FAIL : invalid arguments. + *
+ */ +PUBLIC IX_STATUS +ixEthMiiPhyLoopbackEnable (UINT32 phyAddr); + +/** + * @ingroup IxEthMii + * + * @fn ixEthMiiPhyLoopbackDisable(UINT32 phyAddr) + * + * + * @brief Disable PHY Loopback in a specific Eth MII port + * + * - Reentrant - no + * - ISR Callable - no + * + * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31) + * + * @return IX_STATUS + * - IX_SUCCESS + * - IX_FAIL : invalid arguments. + *
+ */ +PUBLIC IX_STATUS +ixEthMiiPhyLoopbackDisable (UINT32 phyAddr); + +/** + * @ingroup IxEthMii + * + * @fn ixEthMiiPhyReset(UINT32 phyAddr) + * + * @brief Reset a PHY + * Reset a PHY + * + * - Reentrant - no + * - ISR Callable - no + * + * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock. + * + * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31) + * + * @return IX_STATUS + * - IX_SUCCESS + * - IX_FAIL : invalid arguments. + * + *
+ */ +PUBLIC IX_STATUS ixEthMiiPhyReset(UINT32 phyAddr); + + +/** + * @ingroup IxEthMii + * + * @fn ixEthMiiLinkStatus(UINT32 phyAddr, + BOOL *linkUp, + BOOL *speed100, + BOOL *fullDuplex, + BOOL *autoneg) + * + * @brief Retrieve the current status of a PHY + * Retrieve the link, speed, duplex and autonegotiation status of a PHY + * + * - Reentrant - no + * - ISR Callable - no + * + * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock. + * + * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31) + * @param linkUp BOOL [out] - set to TRUE if the link is up + * @param speed100 BOOL [out] - set to TRUE indicates 100Mbit/s, FALSE indicates 10Mbit/s + * @param fullDuplex BOOL [out] - set to TRUE indicates Full Duplex, FALSE indicates Half Duplex + * @param autoneg BOOL [out] - set to TRUE indicates autonegotiation is enabled, FALSE indicates autonegotiation is disabled + * + * @return IX_STATUS + * - IX_SUCCESS + * - IX_FAIL : invalid arguments. + * + *
+ */ +PUBLIC IX_STATUS ixEthMiiLinkStatus(UINT32 phyAddr, + BOOL *linkUp, + BOOL *speed100, + BOOL *fullDuplex, + BOOL *autoneg); + +/** + * @ingroup IxEthMii + * + * @fn ixEthMiiPhyShow (UINT32 phyAddr) + * + * + * @brief Display information on a specified PHY + * Display link status, speed, duplex and Auto Negotiation status + * + * - Reentrant - no + * - ISR Callable - no + * + * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock. + * + * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31) + * + * @return IX_STATUS + * - IX_SUCCESS + * - IX_FAIL : invalid arguments. + * + *
+ */ +PUBLIC IX_STATUS ixEthMiiPhyShow (UINT32 phyAddr); + +#endif /* ndef IxEthMii_H */ +/** + *@} + */ diff --git a/arch/arm/cpu/ixp/npe/include/IxEthMii_p.h b/arch/arm/cpu/ixp/npe/include/IxEthMii_p.h new file mode 100644 index 0000000000..104b65c1f0 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/IxEthMii_p.h @@ -0,0 +1,185 @@ +/** + * @file IxEthMii_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 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#ifndef IxEthMii_p_H +#define IxEthMii_p_H + + +/* MII definitions - these have been verified against the LXT971 and + LXT972 PHYs*/ + +#define IX_ETH_MII_MAX_REG_NUM 0x20 /* max number of registers */ + +#define IX_ETH_MII_CTRL_REG 0x0 /* Control Register */ +#define IX_ETH_MII_STAT_REG 0x1 /* Status Register */ +#define IX_ETH_MII_PHY_ID1_REG 0x2 /* PHY identifier 1 Register */ +#define IX_ETH_MII_PHY_ID2_REG 0x3 /* PHY identifier 2 Register */ +#define IX_ETH_MII_AN_ADS_REG 0x4 /* Auto-Negotiation */ + /* Advertisement Register */ +#define IX_ETH_MII_AN_PRTN_REG 0x5 /* Auto-Negotiation */ + /* partner ability Register */ +#define IX_ETH_MII_AN_EXP_REG 0x6 /* Auto-Negotiation */ + /* Expansion Register */ +#define IX_ETH_MII_AN_NEXT_REG 0x7 /* Auto-Negotiation */ + /* next-page transmit Register */ + +#define IX_ETH_MII_STAT2_REG 0x11 /* Status Register 2*/ + + +/* MII control register bit */ + +#define IX_ETH_MII_CR_COLL_TEST 0x0080 /* collision test */ +#define IX_ETH_MII_CR_FDX 0x0100 /* FDX =1, half duplex =0 */ +#define IX_ETH_MII_CR_RESTART 0x0200 /* restart auto negotiation */ +#define IX_ETH_MII_CR_ISOLATE 0x0400 /* isolate PHY from MII */ +#define IX_ETH_MII_CR_POWER_DOWN 0x0800 /* power down */ +#define IX_ETH_MII_CR_AUTO_EN 0x1000 /* auto-negotiation enable */ +#define IX_ETH_MII_CR_100 0x2000 /* 0 = 10mb, 1 = 100mb */ +#define IX_ETH_MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */ +#define IX_ETH_MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */ +#define IX_ETH_MII_CR_NORM_EN 0x0000 /* just enable the PHY */ +#define IX_ETH_MII_CR_DEF_0_MASK 0xca7f /* they must return zero */ +#define IX_ETH_MII_CR_RES_MASK 0x007f /* reserved bits, return zero */ + +/* MII Status register bit definitions */ + +#define IX_ETH_MII_SR_LINK_STATUS 0x0004 /* link Status -- 1 = link */ +#define IX_ETH_MII_SR_AUTO_SEL 0x0008 /* auto speed select capable */ +#define IX_ETH_MII_SR_REMOTE_FAULT 0x0010 /* Remote fault detect */ +#define IX_ETH_MII_SR_AUTO_NEG 0x0020 /* auto negotiation complete */ +#define IX_ETH_MII_SR_10T_HALF_DPX 0x0800 /* 10BaseT HD capable */ +#define IX_ETH_MII_SR_10T_FULL_DPX 0x1000 /* 10BaseT FD capable */ +#define IX_ETH_MII_SR_TX_HALF_DPX 0x2000 /* TX HD capable */ +#define IX_ETH_MII_SR_TX_FULL_DPX 0x4000 /* TX FD capable */ +#define IX_ETH_MII_SR_T4 0x8000 /* T4 capable */ +#define IX_ETH_MII_SR_ABIL_MASK 0xff80 /* abilities mask */ +#define IX_ETH_MII_SR_EXT_CAP 0x0001 /* extended capabilities */ + + +/* LXT971/2 Status 2 register bit definitions */ +#define IX_ETH_MII_SR2_100 0x4000 +#define IX_ETH_MII_SR2_TX 0x2000 +#define IX_ETH_MII_SR2_RX 0x1000 +#define IX_ETH_MII_SR2_COL 0x0800 +#define IX_ETH_MII_SR2_LINK 0x0400 +#define IX_ETH_MII_SR2_FD 0x0200 +#define IX_ETH_MII_SR2_AUTO 0x0100 +#define IX_ETH_MII_SR2_AUTO_CMPLT 0x0080 +#define IX_ETH_MII_SR2_POLARITY 0x0020 +#define IX_ETH_MII_SR2_PAUSE 0x0010 +#define IX_ETH_MII_SR2_ERROR 0x0008 + +/* MII Link Code word bit definitions */ + +#define IX_ETH_MII_BP_FAULT 0x2000 /* remote fault */ +#define IX_ETH_MII_BP_ACK 0x4000 /* acknowledge */ +#define IX_ETH_MII_BP_NP 0x8000 /* nexp page is supported */ + +/* MII Next Page bit definitions */ + +#define IX_ETH_MII_NP_TOGGLE 0x0800 /* toggle bit */ +#define IX_ETH_MII_NP_ACK2 0x1000 /* acknowledge two */ +#define IX_ETH_MII_NP_MSG 0x2000 /* message page */ +#define IX_ETH_MII_NP_ACK1 0x4000 /* acknowledge one */ +#define IX_ETH_MII_NP_NP 0x8000 /* nexp page will follow */ + +/* MII Expansion Register bit definitions */ + +#define IX_ETH_MII_EXP_FAULT 0x0010 /* parallel detection fault */ +#define IX_ETH_MII_EXP_PRTN_NP 0x0008 /* link partner next-page able */ +#define IX_ETH_MII_EXP_LOC_NP 0x0004 /* local PHY next-page able */ +#define IX_ETH_MII_EXP_PR 0x0002 /* full page received */ +#define IX_ETH_MII_EXP_PRT_AN 0x0001 /* link partner auto neg able */ + +/* technology ability field bit definitions */ + +#define IX_ETH_MII_TECH_10BASE_T 0x0020 /* 10Base-T */ +#define IX_ETH_MII_TECH_10BASE_FD 0x0040 /* 10Base-T Full Duplex */ +#define IX_ETH_MII_TECH_100BASE_TX 0x0080 /* 100Base-TX */ +#define IX_ETH_MII_TECH_100BASE_TX_FD 0x0100 /* 100Base-TX Full Duplex */ + +#define IX_ETH_MII_TECH_100BASE_T4 0x0200 /* 100Base-T4 */ +#define IX_ETH_MII_ADS_TECH_MASK 0x1fe0 /* technology abilities mask */ +#define IX_ETH_MII_TECH_MASK IX_ETH_MII_ADS_TECH_MASK +#define IX_ETH_MII_ADS_SEL_MASK 0x001f /* selector field mask */ + +#define IX_ETH_MII_AN_FAIL 0x10 /* auto-negotiation fail */ +#define IX_ETH_MII_STAT_FAIL 0x20 /* errors in the status register */ +#define IX_ETH_MII_PHY_NO_ABLE 0x40 /* the PHY lacks some abilities */ + +/* Definitions for MII access routines*/ + +#define IX_ETH_MII_GO BIT(31) +#define IX_ETH_MII_WRITE BIT(26) +#define IX_ETH_MII_TIMEOUT_10TH_SECS (5) +#define IX_ETH_MII_10TH_SEC_IN_MILLIS (100) +#define IX_ETH_MII_READ_FAIL BIT(31) + +/* When we reset the PHY we delay for 2 seconds to allow the reset to + complete*/ +#define IX_ETH_MII_RESET_DELAY_MS (2000) +#define IX_ETH_MII_RESET_POLL_MS (50) + +#define IX_ETH_MII_REG_SHL 16 +#define IX_ETH_MII_ADDR_SHL 21 + +/* supported PHYs */ +#define IX_ETH_MII_LXT971_PHY_ID 0x001378E0 +#define IX_ETH_MII_LXT972_PHY_ID 0x001378E2 +#define IX_ETH_MII_LXT973_PHY_ID 0x00137A10 +#define IX_ETH_MII_LXT973A3_PHY_ID 0x00137A11 +#define IX_ETH_MII_KS8995_PHY_ID 0x00221450 +#define IX_ETH_MII_LXT9785_PHY_ID 0x001378FF + + +#define IX_ETH_MII_INVALID_PHY_ID 0x00000000 +#define IX_ETH_MII_UNKNOWN_PHY_ID 0xffffffff + +#endif /*IxEthAccMii_p_H*/ diff --git a/arch/arm/cpu/ixp/npe/include/IxEthNpe.h b/arch/arm/cpu/ixp/npe/include/IxEthNpe.h new file mode 100644 index 0000000000..21bdedc5a7 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/IxEthNpe.h @@ -0,0 +1,695 @@ +#ifndef __doxygen_HIDE /* This file is not part of the API */ + +/** + * @file IxEthNpe.h + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- +*/ + +/** + * @defgroup IxEthNpe IXP400 Ethernet NPE (IxEthNpe) API + * + * @brief Contains the API for Ethernet NPE. + * + * All messages given to NPE, get back an acknowledgment. The acknowledgment + * is identical to the message sent to the NPE (except for NPE_GETSTATUS message). + * + * @{ + */ + + +/*-------------------------------------------------------------------------- + * APB Message IDs - XScale->NPE + *------------------------------------------------------------------------*/ + +/** + * @def IX_ETHNPE_NPE_GETSTATUS + * + * @brief Request from the XScale client for the NPE to return the firmware + * version of the currently executing image. + * + * Acknowledgment message id is same as the request message id. + * NPE returns the firmware version ID to XScale. + */ +#define IX_ETHNPE_NPE_GETSTATUS 0x00 + +/** + * @def IX_ETHNPE_EDB_SETPORTADDRESS + * + * @brief Request from the XScale client for the NPE to set the Ethernet + * port's port ID and MAC address. + */ +#define IX_ETHNPE_EDB_SETPORTADDRESS 0x01 + +/** + * @def IX_ETHNPE_EDB_GETMACADDRESSDATABASE + * + * @brief Request from XScale client to the NPE requesting upload of + * Ethernet Filtering Database or Header Conversion Database from NPE's + * data memory to XScale accessible SDRAM. + */ +#define IX_ETHNPE_EDB_GETMACADDRESSDATABASE 0x02 + +/** + * @def IX_ETHNPE_EDB_SETMACADDRESSSDATABASE + * + * @brief Request from XScale client to the NPE requesting download of + * Ethernet Filtering Database or Header Conversion Database from SDRAM + * to the NPE's datamemory. + */ +#define IX_ETHNPE_EDB_SETMACADDRESSSDATABASE 0x03 + +/** + * @def IX_ETHNPE_GETSTATS + * + * @brief Request from the XScale client for the current MAC port statistics + * data to be written to the (empty) statistics structure and the specified + * location in externa memory. + */ +#define IX_ETHNPE_GETSTATS 0x04 + +/** + * @def IX_ETHNPE_RESETSTATS + * + * @brief Request from the XScale client to the NPE to reset all of its internal + * MAC port statistics state variables. + * + * As a side effect, this message entails an implicit request that the NPE + * write the current MAC port statistics into the MAC statistics structure + * at the specified location in external memory. + */ +#define IX_ETHNPE_RESETSTATS 0x05 + +/** + * @def IX_ETHNPE_SETMAXFRAMELENGTHS + * + * @brief Request from the XScale client to the NPE to configure maximum framelengths + * and block sizes in receive and transmit direction. + */ +#define IX_ETHNPE_SETMAXFRAMELENGTHS 0x06 + +/** + * @def IX_ETHNPE_VLAN_SETRXTAGMODE + * + * @brief Request from the XScale client to the NPE to configure VLAN frame type + * filtering and VLAN the tagging mode for the receiver. + */ +#define IX_ETHNPE_VLAN_SETRXTAGMODE 0x07 + +/** + * @def IX_ETHNPE_VLAN_SETDEFAULTRXVID + * + * @brief Request from the XScale client to the NPE to set receiver's default + * VLAN tag (PVID)and internal traffic class. + */ +#define IX_ETHNPE_VLAN_SETDEFAULTRXVID 0x08 + +/** + * @def IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY + * + * @brief Request from the XScale client to the NPE to configure VLAN Port + * membership and Tx tagging for 8 consecutive VLANID's. + */ +#define IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY 0x09 + +/** + * @def IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE + * + * @brief Request from the XScale client to the NPE to configure VLAN Port + * membership and Tx tagging for a range of VLANID's. + */ +#define IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE 0x0A + +/** + * @def IX_ETHNPE_VLAN_SETRXQOSENTRY + * + * @brief Request from the XScale client to the NPE to map a user priority + * to QoS class and an AQM queue number. + */ +#define IX_ETHNPE_VLAN_SETRXQOSENTRY 0x0B + +/** + * @def IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE + * + * @brief Request from the XScale client to the NPE to enable or disable + * portID extraction from VLAN-tagged frames for the specified port. + */ +#define IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE 0x0C + +/** + * @def IX_ETHNPE_STP_SETBLOCKINGSTATE + * + * @brief Request from the XScale client to the NPE to block or unblock + * forwarding for spanning tree BPDUs. + */ +#define IX_ETHNPE_STP_SETBLOCKINGSTATE 0x0D + +/** + * @def IX_ETHNPE_FW_SETFIREWALLMODE + * + * @brief Request from the XScale client to the NPE to configure firewall + * services modes of operation and/or download Ethernet Firewall Database from + * SDRAM to NPE. + */ +#define IX_ETHNPE_FW_SETFIREWALLMODE 0x0E + +/** + * @def IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID + * + * @brief Request from the XScale client to the NPE to set global frame control + * and duration/ID field for the 802.3 to 802.11 protocol header conversion + * service. + */ +#define IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID 0x0F + +/** + * @def IX_ETHNPE_PC_SETBBSID + * + * @brief Request from the XScale client to the NPE to set global BBSID field + * value for the 802.3 to 802.11 protocol header conversion service. + */ +#define IX_ETHNPE_PC_SETBBSID 0x10 + +/** + * @def IX_ETHNPE_PC_SETAPMACTABLE + * + * @brief Request from the XScale client to the NPE to update a block/section/ + * range of the AP MAC Address Table. + */ +#define IX_ETHNPE_PC_SETAPMACTABLE 0x11 + +/** + * @def IX_ETHNPE_SETLOOPBACK_MODE + * + * @brief Turn on or off the NPE frame loopback. + */ +#define IX_ETHNPE_SETLOOPBACK_MODE (0x12) + +/*-------------------------------------------------------------------------- + * APB Message IDs - NPE->XScale + *------------------------------------------------------------------------*/ + +/** + * @def IX_ETHNPE_NPE_GETSTATUS_ACK + * + * @brief Acknowledgment to IX_ETHNPE_NPE_GETSTATUS message. NPE firmware version + * id is returned in the message. + */ +#define IX_ETHNPE_NPE_GETSTATUS_ACK 0x00 + +/** + * @def IX_ETHNPE_EDB_SETPORTADDRESS_ACK + * + * @brief Acknowledgment to IX_ETHNPE_EDB_SETPORTADDRESS message. + */ +#define IX_ETHNPE_EDB_SETPORTADDRESS_ACK 0x01 + +/** + * @def IX_ETHNPE_EDB_GETMACADDRESSDATABASE_ACK + * + * @brief Acknowledgment to IX_ETHNPE_EDB_GETMACADDRESSDATABASE message + */ +#define IX_ETHNPE_EDB_GETMACADDRESSDATABASE_ACK 0x02 + +/** + * @def IX_ETHNPE_EDB_SETMACADDRESSSDATABASE_ACK + * + * @brief Acknowledgment to IX_ETHNPE_EDB_SETMACADDRESSSDATABASE message. + */ +#define IX_ETHNPE_EDB_SETMACADDRESSSDATABASE_ACK 0x03 + +/** + * @def IX_ETHNPE_GETSTATS_ACK + * + * @brief Acknowledgment to IX_ETHNPE_GETSTATS message. + */ +#define IX_ETHNPE_GETSTATS_ACK 0x04 + +/** + * @def IX_ETHNPE_RESETSTATS_ACK + * + * @brief Acknowledgment to IX_ETHNPE_RESETSTATS message. + */ +#define IX_ETHNPE_RESETSTATS_ACK 0x05 + +/** + * @def IX_ETHNPE_SETMAXFRAMELENGTHS_ACK + * + * @brief Acknowledgment to IX_ETHNPE_SETMAXFRAMELENGTHS message. + */ +#define IX_ETHNPE_SETMAXFRAMELENGTHS_ACK 0x06 + +/** + * @def IX_ETHNPE_VLAN_SETRXTAGMODE_ACK + * + * @brief Acknowledgment to IX_ETHNPE_VLAN_SETRXTAGMODE message. + */ +#define IX_ETHNPE_VLAN_SETRXTAGMODE_ACK 0x07 + +/** + * @def IX_ETHNPE_VLAN_SETDEFAULTRXVID_ACK + * + * @brief Acknowledgment to IX_ETHNPE_VLAN_SETDEFAULTRXVID message. + */ +#define IX_ETHNPE_VLAN_SETDEFAULTRXVID_ACK 0x08 + +/** + * @def IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY_ACK + * + * @brief Acknowledgment to IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY message. + */ +#define IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY_ACK 0x09 + +/** + * @def IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE_ACK + * + * @brief Acknowledgment to IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE message. + */ +#define IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE_ACK 0x0A + +/** + * @def IX_ETHNPE_VLAN_SETRXQOSENTRY_ACK + * + * @brief Acknowledgment to IX_ETHNPE_VLAN_SETRXQOSENTRY message. + */ +#define IX_ETHNPE_VLAN_SETRXQOSENTRY_ACK 0x0B + +/** + * @def IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE_ACK + * + * @brief Acknowledgment to IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE message. + */ +#define IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE_ACK 0x0C + +/** + * @def IX_ETHNPE_STP_SETBLOCKINGSTATE_ACK + * + * @brief Acknowledgment to IX_ETHNPE_STP_SETBLOCKINGSTATE message. + */ +#define IX_ETHNPE_STP_SETBLOCKINGSTATE_ACK 0x0D + +/** + * @def IX_ETHNPE_FW_SETFIREWALLMODE_ACK + * + * @brief Acknowledgment to IX_ETHNPE_FW_SETFIREWALLMODE message. + */ +#define IX_ETHNPE_FW_SETFIREWALLMODE_ACK 0x0E + +/** + * @def IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID_ACK + * + * @brief Acknowledgment to IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID message. + */ +#define IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID_ACK 0x0F + +/** + * @def IX_ETHNPE_PC_SETBBSID_ACK + * + * @brief Acknowledgment to IX_ETHNPE_PC_SETBBSID message. + */ +#define IX_ETHNPE_PC_SETBBSID_ACK 0x10 + +/** + * @def IX_ETHNPE_PC_SETAPMACTABLE_ACK + * + * @brief Acknowledgment to IX_ETHNPE_PC_SETAPMACTABLE message. + */ +#define IX_ETHNPE_PC_SETAPMACTABLE_ACK 0x11 + +/** + * @def IX_ETHNPE_SETLOOPBACK_MODE_ACK + * + * @brief Acknowledgment to IX_ETHNPE_SETLOOPBACK_MODE message. + */ +#define IX_ETHNPE_SETLOOPBACK_MODE_ACK (0x12) + +/*-------------------------------------------------------------------------- + * Queue Manager Queue entry bit field boundary definitions + *------------------------------------------------------------------------*/ + +/** + * @def MASK(hi,lo) + * + * @brief Macro for mask + */ +#define MASK(hi,lo) (((1 << (1 + ((hi) - (lo)))) - 1) << (lo)) + +/** + * @def BITS(x,hi,lo) + * + * @brief Macro for bits + */ +#define BITS(x,hi,lo) (((x) & MASK(hi,lo)) >> (lo)) + +/** + * @def IX_ETHNPE_QM_Q_RXENET_LENGTH_MASK + * + * @brief QMgr Queue LENGTH field mask + */ +#define IX_ETHNPE_QM_Q_RXENET_LENGTH_MASK 0x3fff + +/** + * @def IX_ETHNPE_QM_Q_FIELD_FLAG_R + * + * @brief QMgr Queue FLAG field right boundary + */ +#define IX_ETHNPE_QM_Q_FIELD_FLAG_R 20 + +/** + * @def IX_ETHNPE_QM_Q_FIELD_FLAG_MASK + * + * @brief QMgr Queue FLAG field mask + * + * Multicast bit : BIT(4) + * Broadcast bit : BIT(5) + * IP bit : BIT(6) (linux only) + * + */ +#ifdef __vxworks +#define IX_ETHNPE_QM_Q_FIELD_FLAG_MASK 0x30 +#else +#define IX_ETHNPE_QM_Q_FIELD_FLAG_MASK 0x70 +#endif + + +/** + * @def IX_ETHNPE_QM_Q_FIELD_NPEID_L + * + * @brief QMgr Queue NPE ID field left boundary + */ +#define IX_ETHNPE_QM_Q_FIELD_NPEID_L 1 + +/** + * @def IX_ETHNPE_QM_Q_FIELD_NPEID_R + * + * @brief QMgr Queue NPE ID field right boundary + */ +#define IX_ETHNPE_QM_Q_FIELD_NPEID_R 0 + +/** + * @def IX_ETHNPE_QM_Q_FIELD_PRIOR_L + * + * @brief QMgr Queue Priority field left boundary + */ +#define IX_ETHNPE_QM_Q_FIELD_PRIOR_L 2 + +/** + * @def IX_ETHNPE_QM_Q_FIELD_PRIOR_R + * + * @brief QMgr Queue Priority field right boundary + */ +#define IX_ETHNPE_QM_Q_FIELD_PRIOR_R 0 + +/** + * @def IX_ETHNPE_QM_Q_FIELD_ADDR_L + * + * @brief QMgr Queue Address field left boundary + */ +#define IX_ETHNPE_QM_Q_FIELD_ADDR_L 31 + +/** + * @def IX_ETHNPE_QM_Q_FIELD_ADDR_R + * + * @brief QMgr Queue Address field right boundary + */ +#define IX_ETHNPE_QM_Q_FIELD_ADDR_R 5 + +/*-------------------------------------------------------------------------- + * Queue Manager Queue entry bit field masks + *------------------------------------------------------------------------*/ + +/** + * @def IX_ETHNPE_QM_Q_FREEENET_ADDR_MASK + * + * @brief Macro to mask the Address field of the FreeEnet Queue Manager Entry + */ +#define IX_ETHNPE_QM_Q_FREEENET_ADDR_MASK \ + MASK (IX_ETHNPE_QM_Q_FIELD_ADDR_L, \ + IX_ETHNPE_QM_Q_FIELD_ADDR_R) + +/** + * @def IX_ETHNPE_QM_Q_RXENET_NPEID_MASK + * + * @brief Macro to mask the NPE ID field of the RxEnet Queue Manager Entry + */ +#define IX_ETHNPE_QM_Q_RXENET_NPEID_MASK \ + MASK (IX_ETHNPE_QM_Q_FIELD_NPEID_L, \ + IX_ETHNPE_QM_Q_FIELD_NPEID_R) + +/** + * @def IX_ETHNPE_QM_Q_RXENET_ADDR_MASK + * + * @brief Macro to mask the Mbuf Address field of the RxEnet Queue Manager Entry + */ +#define IX_ETHNPE_QM_Q_RXENET_ADDR_MASK \ + MASK (IX_ETHNPE_QM_Q_FIELD_ADDR_L, \ + IX_ETHNPE_QM_Q_FIELD_ADDR_R) + +/** + * @def IX_ETHNPE_QM_Q_TXENET_PRIOR_MASK + * + * @brief Macro to mask the Priority field of the TxEnet Queue Manager Entry + */ +#define IX_ETHNPE_QM_Q_TXENET_PRIOR_MASK \ + MASK (IX_ETHNPE_QM_Q_FIELD_PRIOR_L, \ + IX_ETHNPE_QM_Q_FIELD_PRIOR_R) + +/** + * @def IX_ETHNPE_QM_Q_TXENET_ADDR_MASK + * + * @brief Macro to mask the Mbuf Address field of the TxEnet Queue Manager Entry + */ +#define IX_ETHNPE_QM_Q_TXENET_ADDR_MASK \ + MASK (IX_ETHNPE_QM_Q_FIELD_ADDR_L, \ + IX_ETHNPE_QM_Q_FIELD_ADDR_R) + +/** + * @def IX_ETHNPE_QM_Q_TXENETDONE_NPEID_MASK + * + * @brief Macro to mask the NPE ID field of the TxEnetDone Queue Manager Entry + */ +#define IX_ETHNPE_QM_Q_TXENETDONE_NPEID_MASK \ + MASK (IX_ETHNPE_QM_Q_FIELD_NPEID_L, \ + IX_ETHNPE_QM_Q_FIELD_NPEID_R) + +/** + * @def IX_ETHNPE_QM_Q_TXENETDONE_ADDR_MASK + * + * @brief Macro to mask the Mbuf Address field of the TxEnetDone Queue Manager + * Entry + */ +#define IX_ETHNPE_QM_Q_TXENETDONE_ADDR_MASK \ + MASK (IX_ETHNPE_QM_Q_FIELD_ADDR_L, \ + IX_ETHNPE_QM_Q_FIELD_ADDR_R) + +/*-------------------------------------------------------------------------- + * Queue Manager Queue entry bit field value extraction macros + *------------------------------------------------------------------------*/ + +/** + * @def IX_ETHNPE_QM_Q_FREEENET_ADDR_VAL(x) + * + * @brief Extraction macro for Address field of FreeNet Queue Manager Entry + * + * Pointer to an mbuf buffer descriptor + */ +#define IX_ETHNPE_QM_Q_FREEENET_ADDR_VAL(x) \ + ((x) & IX_ETHNPE_QM_Q_FREEENET_ADDR_MASK) + +/** + * @def IX_ETHNPE_QM_Q_RXENET_NPEID_VAL(x) + * + * @brief Extraction macro for NPE ID field of RxEnet Queue Manager Entry + * + * Set to 0 for entries originating from the Eth0 NPE; + * Set to 1 for entries originating from the Eth1 NPE. + */ +#define IX_ETHNPE_QM_Q_RXENET_NPEID_VAL(x) \ + BITS (x, IX_ETHNPE_QM_Q_FIELD_NPEID_L, \ + IX_ETHNPE_QM_Q_FIELD_NPEID_R) + +/** + * @def IX_ETHNPE_QM_Q_RXENET_PORTID_VAL(x) + * + * @brief Extraction macro for Port ID field of RxEnet Queue Manager Entry + * + * 0-5: Assignable (by the XScale client) to any of the physical ports. + * 6: It is reserved + * 7: Indication that the NPE did not find the associated frame's destination MAC address within + * its internal filtering database. + */ +#define IX_ETHNPE_QM_Q_RXENET_PORTID_VAL(x) \ + BITS (x, IX_ETHNPE_QM_Q_FIELD_PORTID_L, \ + IX_ETHNPE_QM_Q_Field_PortID_R) + +/** + * @def IX_ETHNPE_QM_Q_RXENET_ADDR_VAL(x) + * + * @brief Extraction macro for Address field of RxEnet Queue Manager Entry + * + * Pointer to an mbuf buffer descriptor + */ +#define IX_ETHNPE_QM_Q_RXENET_ADDR_VAL(x) \ + ((x) & IX_ETHNPE_QM_Q_RXENET_ADDR_MASK) + +/** + * @def IX_ETHNPE_QM_Q_TXENET_PRIOR_VAL(x) + * + * @brief Extraction macro for Priority field of TxEnet Queue Manager Entry + * + * Priority of the packet (as described in IEEE 802.1D). This field is + * cleared upon return from the Ethernet NPE to the TxEnetDone queue. + */ +#define IX_ETHNPE_QM_Q_TXENET_PRIOR_VAL(x) \ + BITS (x, IX_ETHNPE_QM_Q_FIELD_PRIOR_L, \ + IX_ETHNPE_QM_Q_FIELD_PRIOR_R) + +/** + * @def IX_ETHNPE_QM_Q_TXENET_ADDR_VAL(x) + * + * @brief Extraction macro for Address field of Queue Manager TxEnet Queue + * Manager Entry + * + * Pointer to an mbuf buffer descriptor + */ +#define IX_ETHNPE_QM_Q_TXENET_ADDR_VAL(x) \ + ((x) & IX_ETHNPE_QM_Q_TXENET_ADDR_MASK) + +/** + * @def IX_ETHNPE_QM_Q_TXENETDONE_NPEID_VAL(x) + * + * @brief Extraction macro for NPE ID field of TxEnetDone Queue Manager Entry + * + * Set to 0 for entries originating from the Eth0 NPE; set to 1 for en-tries + * originating from the Eth1 NPE. + */ +#define IX_ETHNPE_QM_Q_TXENETDONE_NPEID_VAL(x) \ + BITS (x, IX_ETHNPE_QM_Q_FIELD_NPEID_L, \ + IX_ETHNPE_QM_Q_FIELD_NPEID_R) + +/** + * @def IX_ETHNPE_QM_Q_TXENETDONE_ADDR_VAL(x) + * + * @brief Extraction macro for Address field of TxEnetDone Queue Manager Entry + * + * Pointer to an mbuf buffer descriptor + */ +#define IX_ETHNPE_QM_Q_TXENETDONE_ADDR_VAL(x) \ + ((x) & IX_ETHNPE_QM_Q_TXENETDONE_ADDR_MASK) + + +/*-------------------------------------------------------------------------- + * NPE limits + *------------------------------------------------------------------------*/ + +/** + * @def IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN + * + * @brief Macro to check the minimum length of a rx free buffer + */ +#define IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN (64) + +/** + * @def IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MASK + * + * @brief Mask to apply to the mbuf length before submitting it to the NPE + * (the NPE handles only rx free mbufs which are multiple of 64) + * + * @sa IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MASK + */ +#define IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MASK (~63) + +/** + * @def IX_ETHNPE_ACC_RXFREE_BUFFER_ROUND_UP(size) + * + * @brief Round up to get the size necessary to receive without chaining + * the frames which are (size) bytes (the NPE operates by multiple of 64) + * e.g. To receive 1514 bytes frames, the size of the buffers in replenish + * has to be at least (1514+63)&(~63) = 1536 bytes. + * + */ +#define IX_ETHNPE_ACC_RXFREE_BUFFER_ROUND_UP(size) (((size) + 63) & ~63) + +/** + * @def IX_ETHNPE_ACC_RXFREE_BUFFER_ROUND_DOWN(size) + * + * @brief Round down to apply to the mbuf length before submitting + * it to the NPE. (the NPE operates by multiple of 64) + * + */ +#define IX_ETHNPE_ACC_RXFREE_BUFFER_ROUND_DOWN(size) ((size) & ~63) + +/** + * @def IX_ETHNPE_ACC_FRAME_LENGTH_MAX + * + * @brief maximum mbuf length supported by the NPE + * + * @sa IX_ETHNPE_ACC_FRAME_LENGTH_MAX + */ +#define IX_ETHNPE_ACC_FRAME_LENGTH_MAX (16320) + +/** + * @def IX_ETHNPE_ACC_FRAME_LENGTH_DEFAULT + * + * @brief default mbuf length supported by the NPE + * + * @sa IX_ETHNPE_ACC_FRAME_LENGTH_DEFAULT + */ +#define IX_ETHNPE_ACC_FRAME_LENGTH_DEFAULT (1522) + +/** + * @def IX_ETHNPE_ACC_LENGTH_OFFSET + * + * @brief Offset of the cluster length field in the word shared with the NPEs + */ +#define IX_ETHNPE_ACC_LENGTH_OFFSET 16 + +/** + * @def IX_ETHNPE_ACC_PKTLENGTH_MASK + * + * @brief Mask of the cluster length field in the word shared with the NPEs + */ +#define IX_ETHNPE_ACC_PKTLENGTH_MASK 0x3fff + + +/** + *@} + */ + +#endif /* __doxygen_HIDE */ diff --git a/arch/arm/cpu/ixp/npe/include/IxFeatureCtrl.h b/arch/arm/cpu/ixp/npe/include/IxFeatureCtrl.h new file mode 100644 index 0000000000..dabc38e25e --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/IxFeatureCtrl.h @@ -0,0 +1,742 @@ +/** + * @file IxFeatureCtrl.h + * + * @date 30-Jan-2003 + + * @brief This file contains the public API of the IXP400 Feature Control + * component. + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- +*/ +/* ------------------------------------------------------ + Doxygen group definitions + ------------------------------------------------------ */ +/** + * @defgroup IxFeatureCtrlAPI IXP400 Feature Control (IxFeatureCtrl) API + * + * @brief The Public API for the IXP400 Feature Control. + * + * @{ + */ + +#ifndef IXFEATURECTRL_H +#define IXFEATURECTRL_H + +/* + * User defined include files + */ +#include "IxOsal.h" + +/* + * #defines and macros + */ + +/************************************************************* + * The following are IxFeatureCtrlComponentCheck return values. + ************************************************************/ + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURE_CTRL_COMPONENT_DISABLED + * + * @brief Hardware Component is disabled/unavailable. + * Return status by ixFeatureCtrlComponentCheck() + */ +#define IX_FEATURE_CTRL_COMPONENT_DISABLED 0 + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURE_CTRL_COMPONENT_ENABLED + * + * @brief Hardware Component is available. + * Return status by ixFeatureCtrlComponentCheck() + */ +#define IX_FEATURE_CTRL_COMPONENT_ENABLED 1 + +/*********************************************************************************** + * Product ID in XScale CP15 - Register 0 + * - It contains information on the maximum XScale Core Frequency and + * Silicon Stepping. + * - XScale Core Frequency Id indicates only the maximum XScale frequency + * achievable and not the running XScale frequency (maybe stepped down). + * - The register is read by using ixFeatureCtrlProductIdRead. + * - Usage example: + * productId = ixFeatureCtrlProductIdRead(); + * if( (productId & IX_FEATURE_CTRL_SILICON_STEPPING_MASK) == + * IX_FEATURE_CTRL_SILICON_TYPE_A0 ) + * if( (productId & IX_FEATURE_CTRL_XSCALE_FREQ_MASK) == + * IX_FEATURE_CTRL_XSCALE_FREQ_533 ) + * + * 31 28 27 24 23 20 19 16 15 12 11 9 8 4 3 0 + * -------------------------------------------------------------------------------- + * | 0x6 | 0x9 | 0x0 | 0x5 | 0x4 | Device ID | XScale Core Freq Id | Si Stepping Id | + * -------------------------------------------------------------------------------- + * + * Maximum Achievable XScale Core Frequency Id : 533MHz - 0x1C + * 400MHz - 0x1D + * 266MHz - 0x1F + * + * THE CORE FREQUENCY ID IS NOT APPLICABLE TO IXP46X <\b> + * + * The above is applicable to IXP42X only. CP15 in IXP46X does not contain any + * Frequency ID. + * + * Si Stepping Id : A - 0x0 + * B - 0x1 + * + * XScale Core freq Id - Device ID [11:9] : IXP42X - 0x0 + * IXP46X - 0x1 + *************************************************************************************/ + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURE_CTRL_SILICON_TYPE_A0 + * + * @brief This is the value of A0 Silicon in product ID. + */ +#define IX_FEATURE_CTRL_SILICON_TYPE_A0 0 + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURE_CTRL_SILICON_TYPE_B0 + * + * @brief This is the value of B0 Silicon in product ID. + */ +#define IX_FEATURE_CTRL_SILICON_TYPE_B0 1 + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURE_CTRL_SILICON_STEPPING_MASK + * + * @brief This is the mask of silicon stepping in product ID. + */ +#define IX_FEATURE_CTRL_SILICON_STEPPING_MASK 0xF + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURE_CTRL_DEVICE_TYPE_MASK + * + * @brief This is the mask of silicon stepping in product ID. + */ +#define IX_FEATURE_CTRL_DEVICE_TYPE_MASK (0x7) + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURE_CTRL_DEVICE_TYPE_OFFSET + * + * @brief This is the mask of silicon stepping in product ID. + */ +#define IX_FEATURE_CTRL_DEVICE_TYPE_OFFSET 9 + + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURE_CTRL_XSCALE_FREQ_533 + * + * @brief This is the value of 533MHz XScale Core in product ID. + */ +#define IX_FEATURE_CTRL_XSCALE_FREQ_533 ((0x1C)<<4) + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURE_CTRL_XSCALE_FREQ_400 + * + * @brief This is the value of 400MHz XScale Core in product ID. + */ +#define IX_FEATURE_CTRL_XSCALE_FREQ_400 ((0x1D)<<4) + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURE_CTRL_XSCALE_FREQ_266 + * + * @brief This is the value of 266MHz XScale Core in product ID. + */ +#define IX_FEATURE_CTRL_XSCALE_FREQ_266 ((0x1F)<<4) + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURE_CTRL_XSCALE_FREQ_MASK + * + * @brief This is the mask of XScale Core in product ID. + */ +#define IX_FEATURE_CTRL_XSCALE_FREQ_MASK ((0xFF)<<4) + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURECTRL_REG_UTOPIA_32PHY + * + * @brief Maximum UTOPIA PHY available is 32. + * + */ +#define IX_FEATURECTRL_REG_UTOPIA_32PHY 0x0 + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURECTRL_REG_UTOPIA_16PHY + * + * @brief Maximum UTOPIA PHY available is 16. + * + */ +#define IX_FEATURECTRL_REG_UTOPIA_16PHY 0x1 + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURECTRL_REG_UTOPIA_8PHY + * + * @brief Maximum UTOPIA PHY available to is 8. + * + */ +#define IX_FEATURECTRL_REG_UTOPIA_8PHY 0x2 + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURECTRL_REG_UTOPIA_4PHY + * + * @brief Maximum UTOPIA PHY available to is 4. + * + */ +#define IX_FEATURECTRL_REG_UTOPIA_4PHY 0x3 + +#ifdef __ixp46X + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURECTRL_REG_XSCALE_533FREQ + * + * @brief Maximum frequency available to IXP46x is 533 MHz. + * + */ +#define IX_FEATURECTRL_REG_XSCALE_533FREQ 0x0 + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURECTRL_REG_XSCALE_667FREQ + * + * @brief Maximum frequency available to IXP46x is 667 MHz. + * + */ +#define IX_FEATURECTRL_REG_XSCALE_667FREQ 0x1 + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURECTRL_REG_XSCALE_400FREQ + * + * @brief Maximum frequency available to IXP46x is 400 MHz. + * + */ +#define IX_FEATURECTRL_REG_XSCALE_400FREQ 0x2 + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURECTRL_REG_XSCALE_266FREQ + * + * @brief Maximum frequency available to IXP46x is 266 MHz. + * + */ +#define IX_FEATURECTRL_REG_XSCALE_266FREQ 0x3 + +#endif /* __ixp46X */ + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE + * + * @brief Component selected is not available for device + * + */ +#define IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE 0x0000 + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURECTRL_COMPONENT_ALWAYS_AVAILABLE + * + * @brief Component selected is not available for device + * + */ +#define IX_FEATURECTRL_COMPONENT_ALWAYS_AVAILABLE 0xffff + +/** + * @defgroup IxFeatureCtrlSwConfig Software Configuration for Access Component + * + * @ingroup IxFeatureCtrlAPI + * + * @brief This section describes software configuration in access component. The + * configuration can be changed at run-time. ixFeatureCtrlSwConfigurationCheck( ) + * will be used across applicable access component to check the configuration. + * ixFeatureCtrlSwConfigurationWrite( ) is used to write the software configuration. + * + * @note All software configurations are default to be enabled. + * + * @{ + */ +/** + * @ingroup IxFeatureCtrlSwConfig + * + * @def IX_FEATURE_CTRL_SWCONFIG_DISABLED + * + * @brief Software configuration is disabled. + * + */ +#define IX_FEATURE_CTRL_SWCONFIG_DISABLED 0 + +/** + * @ingroup IxFeatureCtrlSwConfig + * + * @def IX_FEATURE_CTRL_SWCONFIG_ENABLED + * + * @brief Software configuration is enabled. + * + */ +#define IX_FEATURE_CTRL_SWCONFIG_ENABLED 1 + +/** + * Section for enums + **/ + +/** + * @ingroup IxFeatureCtrlBuildDevice + * + * @enum IxFeatureCtrlBuildDevice + * + * @brief Indicates software build type. + * + * Default build type is IXP42X + * + */ +typedef enum +{ + IX_FEATURE_CTRL_SW_BUILD_IXP42X = 0, /** + * - if(IX_FEATURE_CTRL_COMPONENT_DISABLED != + * ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0))
+ * - if(IX_FEATURE_CTRL_COMPONENT_ENABLED == + * ixFeatureCtrlComponentCheck(IX_FEATURECTRL_PCI))
+ * + * This function is typically called during component initialization time. + * + * @param componentType @ref IxFeatureCtrlComponentType [in] - the type of a component as + * defined above as IX_FEATURECTRL_XXX (Exp: IX_FEATURECTRL_PCI, IX_FEATURECTRL_ETH0) + + * + * @return + * - IX_FEATURE_CTRL_COMPONENT_ENABLED if component is available + * - IX_FEATURE_CTRL_COMPONENT_DISABLED if component is unavailable + */ +PUBLIC IX_STATUS +ixFeatureCtrlComponentCheck (IxFeatureCtrlComponentType componentType); + +/** + * @ingroup IxFeatureCtrlAPI + * + * @fn IxFeatureCtrlProductId ixFeatureCtrlProductIdRead (void) + * + * @brief This function will return IXP400 product ID i.e. CP15, + * Register 0. + * + * @return + * - IxFeatureCtrlProductId - the value of product ID. + * + */ +PUBLIC IxFeatureCtrlProductId +ixFeatureCtrlProductIdRead (void) ; + +/** + * @ingroup IxFeatureCtrlAPI + * + * @fn IX_STATUS ixFeatureCtrlSwConfigurationCheck (IxFeatureCtrlSwConfig swConfigType) + * + * @brief This function checks whether the specified software configuration is + * enabled or disabled. + * + * Usage Example:
+ * - if(IX_FEATURE_CTRL_SWCONFIG_DISABLED != + * ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING))
+ * - if(IX_FEATURE_CTRL_SWCONFIG_ENABLED == + * ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING))
+ * + * This function is typically called during access component initialization time. + * + * @param swConfigType @ref IxFeatureCtrlSwConfig [in] - the type of a software configuration + * defined in IxFeatureCtrlSwConfig enumeration. + * + * @return + * - IX_FEATURE_CTRL_SWCONFIG_ENABLED if software configuration is enabled. + * - IX_FEATURE_CTRL_SWCONFIG_DISABLED if software configuration is disabled. + */ +PUBLIC IX_STATUS +ixFeatureCtrlSwConfigurationCheck (IxFeatureCtrlSwConfig swConfigType); + +/** + * @ingroup IxFeatureCtrlAPI + * + * @fn void ixFeatureCtrlSwConfigurationWrite (IxFeatureCtrlSwConfig swConfigType, BOOL enabled) + * + * @brief This function enable/disable the specified software configuration. + * + * Usage Example:
+ * - ixFeatureCtrlSwConfigurationWrite(IX_FEATURECTRL_ETH_LEARNING, TRUE) is used + * to enable Ethernet Learning Feature
+ * - ixFeatureCtrlSwConfigurationWrite(IX_FEATURECTRL_ETH_LEARNING, FALSE) is used + * to disable Ethernet Learning Feature
+ * + * @param swConfigType IxFeatureCtrlSwConfig [in] - the type of a software configuration + * defined in IxFeatureCtrlSwConfig enumeration. + * @param enabled BOOL [in] - To enable(TRUE) / disable (FALSE) the specified software + * configuration. + * + * @return none + * + */ +PUBLIC void +ixFeatureCtrlSwConfigurationWrite (IxFeatureCtrlSwConfig swConfigType, BOOL enabled); + +/** + * @ingroup IxFeatureCtrlAPI + * + * @fn void ixFeatureCtrlIxp400SwVersionShow (void) + * + * @brief This function shows the current software release information for IXP400 + * + * @return none + * + */ +PUBLIC void +ixFeatureCtrlIxp400SwVersionShow (void); + +#endif /* IXFEATURECTRL_H */ + +/** + * @} defgroup IxFeatureCtrlAPI + */ diff --git a/arch/arm/cpu/ixp/npe/include/IxHssAcc.h b/arch/arm/cpu/ixp/npe/include/IxHssAcc.h new file mode 100644 index 0000000000..07bb119b0b --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/IxHssAcc.h @@ -0,0 +1,1316 @@ +/** + * @file IxHssAcc.h + * + * @date 07-DEC-2001 + * + * @brief This file contains the public API of the IXP400 HSS Access + * component + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- +*/ + +/* ------------------------------------------------------ + Doxygen group definitions + ------------------------------------------------------ */ +/** + * @defgroup IxHssAccAPI IXP400 HSS Access (IxHssAcc) API + * + * @brief The public API for the IXP400 HssAccess component + * + * IxHssAcc is the access layer to the HSS packetised and channelised + * services + * + * Design Notes
+ *
    + *
  • When a packet-pipe is configured for 56Kbps RAW mode, byte alignment of + * the transmitted data is not preserved. All raw data that is transmitted + * will be received in proper order by the receiver, but the first bit of + * the packet may be seen at any offset within a byte; all subsequent bytes + * will have the same offset for the duration of the packet. The same offset + * also applies to all subsequent packets received on the packet-pipe too. + * (Similar results will occur for data received from remote end.) While + * this behavior will also occur for 56Kbps HDLC mode, the HDLC + * encoding/decoding will preserve the original byte alignment at the + * receiver end. + *
+ * + * 56Kbps Packetised Service Bandwidth Limitation
+ *
    + *
  • IxHssAcc supports 56Kbps packetised service at a maximum aggregate rate + * for all HSS ports/HDLC channels of 12.288Mbps[1] in each direction, i.e. + * it supports 56Kbps packetised service on up to 8 T1 trunks. It does + * not support 56Kbps packetised service on 8 E1 trunks (i.e. 4 trunks per + * HSS port) unless those trunks are running 'fractional E1' with maximum + * aggregate rate of 12.288 Mbps in each direction.
    + * [1] 12.288Mbps = 1.536Mbp * 8 T1 + *
+ * @{ */ + +#ifndef IXHSSACC_H +#define IXHSSACC_H + +#include "IxOsal.h" + +/* + * #defines for function return types, etc. + */ + +/** + * @def IX_HSSACC_TSLOTS_PER_HSS_PORT + * + * @brief The max number of TDM timeslots supported per HSS port - 4E1's = + * 32x4 = 128 + */ +#define IX_HSSACC_TSLOTS_PER_HSS_PORT 128 + +/* ----------------------------------------------------------- + The following are HssAccess return values returned through + service interfaces. The globally defined IX_SUCCESS (0) and + IX_FAIL (1) in IxOsalTypes.h are also used. + ----------------------------------------------------------- */ +/** + * @def IX_HSSACC_PARAM_ERR + * + * @brief HssAccess function return value for a parameter error + */ +#define IX_HSSACC_PARAM_ERR 2 + +/** + * @def IX_HSSACC_RESOURCE_ERR + * + * @brief HssAccess function return value for a resource error + */ +#define IX_HSSACC_RESOURCE_ERR 3 + +/** + * @def IX_HSSACC_PKT_DISCONNECTING + * + * @brief Indicates that a disconnect call is progressing and will + * disconnect soon + */ +#define IX_HSSACC_PKT_DISCONNECTING 4 + +/** + * @def IX_HSSACC_Q_WRITE_OVERFLOW + * + * @brief Indicates that an attempt to Tx or to replenish an + * RxFree Q failed due to Q overflow. + */ +#define IX_HSSACC_Q_WRITE_OVERFLOW 5 + +/* ------------------------------------------------------------------- + The following errors are HSS/NPE errors returned on error retrieval + ------------------------------------------------------------------- */ +/** + * @def IX_HSSACC_NO_ERROR + * + * @brief HSS port no error present + */ +#define IX_HSSACC_NO_ERROR 0 + +/** + * @def IX_HSSACC_TX_FRM_SYNC_ERR + * + * @brief HSS port TX Frame Sync error + */ +#define IX_HSSACC_TX_FRM_SYNC_ERR 1 + +/** + * @def IX_HSSACC_TX_OVER_RUN_ERR + * + * @brief HSS port TX over-run error + */ +#define IX_HSSACC_TX_OVER_RUN_ERR 2 + +/** + * @def IX_HSSACC_CHANNELISED_SW_TX_ERR + * + * @brief NPE software error in channelised TX + */ +#define IX_HSSACC_CHANNELISED_SW_TX_ERR 3 + +/** + * @def IX_HSSACC_PACKETISED_SW_TX_ERR + * + * @brief NPE software error in packetised TX + */ +#define IX_HSSACC_PACKETISED_SW_TX_ERR 4 + +/** + * @def IX_HSSACC_RX_FRM_SYNC_ERR + * + * @brief HSS port RX Frame Sync error + */ +#define IX_HSSACC_RX_FRM_SYNC_ERR 5 + +/** + * @def IX_HSSACC_RX_OVER_RUN_ERR + * + * @brief HSS port RX over-run error + */ +#define IX_HSSACC_RX_OVER_RUN_ERR 6 + +/** + * @def IX_HSSACC_CHANNELISED_SW_RX_ERR + * + * @brief NPE software error in channelised RX + */ +#define IX_HSSACC_CHANNELISED_SW_RX_ERR 7 + +/** + * @def IX_HSSACC_PACKETISED_SW_RX_ERR + * + * @brief NPE software error in packetised TX + */ +#define IX_HSSACC_PACKETISED_SW_RX_ERR 8 + +/* ----------------------------------- + Packetised service specific defines + ----------------------------------- */ + +/** + * @def IX_HSSACC_PKT_MIN_RX_MBUF_SIZE + * + * @brief Minimum size of the Rx mbuf in bytes which the client must supply + * to the component. + */ +#define IX_HSSACC_PKT_MIN_RX_MBUF_SIZE 64 + +/* -------------------------------------------------------------------- + Enumerated Types - these enumerated values may be used in setting up + the contents of hardware registers + -------------------------------------------------------------------- */ +/** + * @enum IxHssAccHssPort + * @brief The HSS port ID - There are two identical ports (0-1). + * + */ +typedef enum +{ + IX_HSSACC_HSS_PORT_0, /**< HSS Port 0 */ + IX_HSSACC_HSS_PORT_1, /**< HSS Port 1 */ + IX_HSSACC_HSS_PORT_MAX /**< Delimiter for error checks */ +} IxHssAccHssPort; + +/** + * @enum IxHssAccHdlcPort + * @brief The HDLC port ID - There are four identical HDLC ports (0-3) per + * HSS port and they correspond to the 4 E1/T1 trunks. + * + */ +typedef enum +{ + IX_HSSACC_HDLC_PORT_0, /**< HDLC Port 0 */ + IX_HSSACC_HDLC_PORT_1, /**< HDLC Port 1 */ + IX_HSSACC_HDLC_PORT_2, /**< HDLC Port 2 */ + IX_HSSACC_HDLC_PORT_3, /**< HDLC Port 3 */ + IX_HSSACC_HDLC_PORT_MAX /**< Delimiter for error checks */ +} IxHssAccHdlcPort; + +/** + * @enum IxHssAccTdmSlotUsage + * @brief The HSS TDM stream timeslot assignment types + * + */ +typedef enum +{ + IX_HSSACC_TDMMAP_UNASSIGNED, /**< Unassigned */ + IX_HSSACC_TDMMAP_HDLC, /**< HDLC - packetised */ + IX_HSSACC_TDMMAP_VOICE56K, /**< Voice56K - channelised */ + IX_HSSACC_TDMMAP_VOICE64K, /**< Voice64K - channelised */ + IX_HSSACC_TDMMAP_MAX /**< Delimiter for error checks */ +} IxHssAccTdmSlotUsage; + +/** + * @enum IxHssAccFrmSyncType + * @brief The HSS frame sync pulse type + * + */ +typedef enum +{ + IX_HSSACC_FRM_SYNC_ACTIVE_LOW, /**< Frame sync is sampled low */ + IX_HSSACC_FRM_SYNC_ACTIVE_HIGH, /**< sampled high */ + IX_HSSACC_FRM_SYNC_FALLINGEDGE, /**< sampled on a falling edge */ + IX_HSSACC_FRM_SYNC_RISINGEDGE, /**< sampled on a rising edge */ + IX_HSSACC_FRM_SYNC_TYPE_MAX /**< Delimiter for error checks */ +} IxHssAccFrmSyncType; + +/** + * @enum IxHssAccFrmSyncEnable + * @brief The IxHssAccFrmSyncEnable determines how the frame sync pulse is + * used + * */ +typedef enum +{ + IX_HSSACC_FRM_SYNC_INPUT, /**< Frame sync is sampled as an input */ + IX_HSSACC_FRM_SYNC_INVALID_VALUE, /**< 1 is not used */ + IX_HSSACC_FRM_SYNC_OUTPUT_FALLING, /**< Frame sync is an output generated + off a falling clock edge */ + IX_HSSACC_FRM_SYNC_OUTPUT_RISING, /**< Frame sync is an output generated + off a rising clock edge */ + IX_HSSACC_FRM_SYNC_ENABLE_MAX /**< Delimiter for error checks */ +} IxHssAccFrmSyncEnable; + +/** + * @enum IxHssAccClkEdge + * @brief IxHssAccClkEdge is used to determine the clk edge to use for + * framing and data + * + */ +typedef enum +{ + IX_HSSACC_CLK_EDGE_FALLING, /**< Clock sampled off a falling edge */ + IX_HSSACC_CLK_EDGE_RISING, /**< Clock sampled off a rising edge */ + IX_HSSACC_CLK_EDGE_MAX /**< Delimiter for error checks */ +} IxHssAccClkEdge; + +/** + * @enum IxHssAccClkDir + * @brief The HSS clock direction + * + */ +typedef enum +{ + IX_HSSACC_SYNC_CLK_DIR_INPUT, /**< Clock is an input */ + IX_HSSACC_SYNC_CLK_DIR_OUTPUT, /**< Clock is an output */ + IX_HSSACC_SYNC_CLK_DIR_MAX /**< Delimiter for error checks */ +} IxHssAccClkDir; + +/** + * @enum IxHssAccFrmPulseUsage + * @brief The HSS frame pulse usage + * + */ +typedef enum +{ + IX_HSSACC_FRM_PULSE_ENABLED, /**< Generate/Receive frame pulses */ + IX_HSSACC_FRM_PULSE_DISABLED, /**< Disregard frame pulses */ + IX_HSSACC_FRM_PULSE_MAX /**< Delimiter for error checks */ +} IxHssAccFrmPulseUsage; + +/** + * @enum IxHssAccDataRate + * @brief The HSS Data rate in relation to the clock + * + */ +typedef enum +{ + IX_HSSACC_CLK_RATE, /**< Data rate is at the configured clk speed */ + IX_HSSACC_HALF_CLK_RATE, /**< Data rate is half the configured clk speed */ + IX_HSSACC_DATA_RATE_MAX /**< Delimiter for error checks */ +} IxHssAccDataRate; + +/** + * @enum IxHssAccDataPolarity + * @brief The HSS data polarity type + * + */ +typedef enum +{ + IX_HSSACC_DATA_POLARITY_SAME, /**< Don't invert data between NPE and + HSS FIFOs */ + IX_HSSACC_DATA_POLARITY_INVERT, /**< Invert data between NPE and HSS + FIFOs */ + IX_HSSACC_DATA_POLARITY_MAX /**< Delimiter for error checks */ +} IxHssAccDataPolarity; + +/** + * @enum IxHssAccBitEndian + * @brief HSS Data endianness + * + */ +typedef enum +{ + IX_HSSACC_LSB_ENDIAN, /**< TX/RX Least Significant Bit first */ + IX_HSSACC_MSB_ENDIAN, /**< TX/RX Most Significant Bit first */ + IX_HSSACC_ENDIAN_MAX /**< Delimiter for the purposes of error checks */ +} IxHssAccBitEndian; + + +/** + * @enum IxHssAccDrainMode + * @brief Tx pin open drain mode + * + */ +typedef enum +{ + IX_HSSACC_TX_PINS_NORMAL, /**< Normal mode */ + IX_HSSACC_TX_PINS_OPEN_DRAIN, /**< Open Drain mode */ + IX_HSSACC_TX_PINS_MAX /**< Delimiter for error checks */ +} IxHssAccDrainMode; + +/** + * @enum IxHssAccSOFType + * @brief HSS start of frame types + * + */ +typedef enum +{ + IX_HSSACC_SOF_FBIT, /**< Framing bit transmitted and expected on rx */ + IX_HSSACC_SOF_DATA, /**< Framing bit not transmitted nor expected on rx */ + IX_HSSACC_SOF_MAX /**< Delimiter for error checks */ +} IxHssAccSOFType; + +/** + * @enum IxHssAccDataEnable + * @brief IxHssAccDataEnable is used to determine whether or not to drive + * the data pins + * + */ +typedef enum +{ + IX_HSSACC_DE_TRI_STATE, /**< TRI-State the data pins */ + IX_HSSACC_DE_DATA, /**< Push data out the data pins */ + IX_HSSACC_DE_MAX /**< Delimiter for error checks */ +} IxHssAccDataEnable; + +/** + * @enum IxHssAccTxSigType + * @brief IxHssAccTxSigType is used to determine how to drive the data pins + * + */ +typedef enum +{ + IX_HSSACC_TXSIG_LOW, /**< Drive the data pins low */ + IX_HSSACC_TXSIG_HIGH, /**< Drive the data pins high */ + IX_HSSACC_TXSIG_HIGH_IMP, /**< Drive the data pins with high impedance */ + IX_HSSACC_TXSIG_MAX /**< Delimiter for error checks */ +} IxHssAccTxSigType; + +/** + * @enum IxHssAccFbType + * @brief IxHssAccFbType determines how to drive the Fbit + * + * @warning This will only be used for T1 @ 1.544MHz + * + */ +typedef enum +{ + IX_HSSACC_FB_FIFO, /**< Fbit is dictated in FIFO */ + IX_HSSACC_FB_HIGH_IMP, /**< Fbit is high impedance */ + IX_HSSACC_FB_MAX /**< Delimiter for error checks */ +} IxHssAccFbType; + +/** + * @enum IxHssAcc56kEndianness + * @brief 56k data endianness when using the 56k type + * + */ +typedef enum +{ + IX_HSSACC_56KE_BIT_7_UNUSED, /**< High bit is unused */ + IX_HSSACC_56KE_BIT_0_UNUSED, /**< Low bit is unused */ + IX_HSSACC_56KE_MAX /**< Delimiter for error checks */ +} IxHssAcc56kEndianness; + +/** + * @enum IxHssAcc56kSel + * @brief 56k data transmission type when using the 56k type + * + */ +typedef enum +{ + IX_HSSACC_56KS_32_8_DATA, /**< 32/8 bit data */ + IX_HSSACC_56KS_56K_DATA, /**< 56K data */ + IX_HSSACC_56KS_MAX /**< Delimiter for error checks */ +} IxHssAcc56kSel; + + +/** + * @enum IxHssAccClkSpeed + * @brief IxHssAccClkSpeed represents the HSS clock speeds available + * + */ +typedef enum +{ + IX_HSSACC_CLK_SPEED_512KHZ, /**< 512KHz */ + IX_HSSACC_CLK_SPEED_1536KHZ, /**< 1.536MHz */ + IX_HSSACC_CLK_SPEED_1544KHZ, /**< 1.544MHz */ + IX_HSSACC_CLK_SPEED_2048KHZ, /**< 2.048MHz */ + IX_HSSACC_CLK_SPEED_4096KHZ, /**< 4.096MHz */ + IX_HSSACC_CLK_SPEED_8192KHZ, /**< 8.192MHz */ + IX_HSSACC_CLK_SPEED_MAX /**< Delimiter for error checking */ +} IxHssAccClkSpeed; + +/** + * @enum IxHssAccPktStatus + * @brief Indicates the status of packets passed to the client + * + */ +typedef enum +{ + IX_HSSACC_PKT_OK, /**< Error free.*/ + IX_HSSACC_STOP_SHUTDOWN_ERROR, /**< Errored due to stop or shutdown + occurrance.*/ + IX_HSSACC_HDLC_ALN_ERROR, /**< HDLC alignment error */ + IX_HSSACC_HDLC_FCS_ERROR, /**< HDLC Frame Check Sum error.*/ + IX_HSSACC_RXFREE_Q_EMPTY_ERROR, /**< RxFree Q became empty + while receiving this packet.*/ + IX_HSSACC_HDLC_MAX_FRAME_SIZE_EXCEEDED, /**< HDLC frame size + received is greater than + max specified at connect.*/ + IX_HSSACC_HDLC_ABORT_ERROR, /**< HDLC frame received is invalid due to an + abort sequence received.*/ + IX_HSSACC_DISCONNECT_IN_PROGRESS /**< Packet returned + because a disconnect is in progress */ +} IxHssAccPktStatus; + + +/** + * @enum IxHssAccPktCrcType + * @brief HDLC CRC type + * + */ +typedef enum +{ + IX_HSSACC_PKT_16_BIT_CRC = 16, /**< 16 bit CRC is being used */ + IX_HSSACC_PKT_32_BIT_CRC = 32 /**< 32 bit CRC is being used */ +} IxHssAccPktCrcType; + +/** + * @enum IxHssAccPktHdlcIdleType + * @brief HDLC idle transmission type + * + */ +typedef enum +{ + IX_HSSACC_HDLC_IDLE_ONES, /**< idle tx/rx will be a succession of ones */ + IX_HSSACC_HDLC_IDLE_FLAGS /**< idle tx/rx will be repeated flags */ +} IxHssAccPktHdlcIdleType; + +/** + * @brief Structure containing HSS port configuration parameters + * + * Note: All of these are used for TX. Only some are specific to RX. + * + */ +typedef struct +{ + IxHssAccFrmSyncType frmSyncType; /**< frame sync pulse type (tx/rx) */ + IxHssAccFrmSyncEnable frmSyncIO; /**< how the frame sync pulse is + used (tx/rx) */ + IxHssAccClkEdge frmSyncClkEdge; /**< frame sync clock edge type + (tx/rx) */ + IxHssAccClkEdge dataClkEdge; /**< data clock edge type (tx/rx) */ + IxHssAccClkDir clkDirection; /**< clock direction (tx/rx) */ + IxHssAccFrmPulseUsage frmPulseUsage; /**< whether to use the frame sync + pulse or not (tx/rx) */ + IxHssAccDataRate dataRate; /**< data rate in relation to the + clock (tx/rx) */ + IxHssAccDataPolarity dataPolarity; /**< data polarity type (tx/rx) */ + IxHssAccBitEndian dataEndianness; /**< data endianness (tx/rx) */ + IxHssAccDrainMode drainMode; /**< tx pin open drain mode (tx) */ + IxHssAccSOFType fBitUsage; /**< start of frame types (tx/rx) */ + IxHssAccDataEnable dataEnable; /**< whether or not to drive the data + pins (tx) */ + IxHssAccTxSigType voice56kType; /**< how to drive the data pins for + voice56k type (tx) */ + IxHssAccTxSigType unassignedType; /**< how to drive the data pins for + unassigned type (tx) */ + IxHssAccFbType fBitType; /**< how to drive the Fbit (tx) */ + IxHssAcc56kEndianness voice56kEndian;/**< 56k data endianness when using + the 56k type (tx) */ + IxHssAcc56kSel voice56kSel; /**< 56k data transmission type when + using the 56k type (tx) */ + unsigned frmOffset; /**< frame pulse offset in bits wrt + the first timeslot (0-1023) (tx/rx) */ + unsigned maxFrmSize; /**< frame size in bits (1-1024) + (tx/rx) */ +} IxHssAccPortConfig; + +/** + * @brief Structure containing HSS configuration parameters + * + */ +typedef struct +{ + IxHssAccPortConfig txPortConfig; /**< HSS tx port configuration */ + IxHssAccPortConfig rxPortConfig; /**< HSS rx port configuration */ + unsigned numChannelised; /**< The number of channelised + timeslots (0-32) */ + unsigned hssPktChannelCount; /**< The number of packetised + clients (0 - 4) */ + UINT8 channelisedIdlePattern; /**< The byte to be transmitted on + channelised service when there + is no client data to tx */ + BOOL loopback; /**< The HSS loopback state */ + unsigned packetizedIdlePattern; /**< The data to be transmitted on + packetised service when there is + no client data to tx */ + IxHssAccClkSpeed clkSpeed; /**< The HSS clock speed */ +} IxHssAccConfigParams; + +/** + * @brief This structure contains 56Kbps, HDLC-mode configuration parameters + * + */ +typedef struct +{ + BOOL hdlc56kMode; /**< 56kbps(TRUE)/64kbps(FALSE) HDLC */ + IxHssAcc56kEndianness hdlc56kEndian; /**< 56kbps data endianness + - ignored if hdlc56kMode is FALSE*/ + BOOL hdlc56kUnusedBitPolarity0; /**< The polarity '0'(TRUE)/'1'(FALSE) of the unused + bit while in 56kbps mode + - ignored if hdlc56kMode is FALSE*/ +} IxHssAccHdlcMode; + +/** + * @brief This structure contains information required by the NPE to + * configure the HDLC co-processor + * + */ +typedef struct +{ + IxHssAccPktHdlcIdleType hdlcIdleType; /**< What to transmit when a HDLC port is idle */ + IxHssAccBitEndian dataEndian; /**< The HDLC data endianness */ + IxHssAccPktCrcType crcType; /**< The CRC type to be used for this HDLC port */ +} IxHssAccPktHdlcFraming; + +/** + * @typedef UINT32 IxHssAccPktUserId + * + * @brief The client supplied value which will be supplied as a parameter + * with a given callback. + * + * This value will be passed into the ixHssAccPktPortConnect function once each + * with given callbacks. This value will then be passed back to the client + * as one of the parameters to each of these callbacks, + * when these callbacks are called. + */ +typedef UINT32 IxHssAccPktUserId; + + +/** + * @typedef IxHssAccLastErrorCallback + * @brief Prototype of the clients function to accept notification of the + * last error + * + * This function is registered through the config. The client will initiate + * the last error retrieval. The HssAccess component will send a message to + * the NPE through the NPE Message Handler. When a response to the read is + * received, the NPE Message Handler will callback the HssAccess component + * which will execute this function in the same IxNpeMh context. The client + * will be passed the last error and the related service port (packetised + * 0-3, channelised 0) + * + * @param lastHssError unsigned [in] - The last Hss error registered that + * has been registered. + * @param servicePort unsigned [in] - This is the service port number. + * (packetised 0-3, channelised 0) + * + * @return void + */ +typedef void (*IxHssAccLastErrorCallback) (unsigned lastHssError, + unsigned servicePort); + +/** + * @typedef IxHssAccPktRxCallback + * @brief Prototype of the clients function to accept notification of + * packetised rx + * + * This function is registered through the ixHssAccPktPortConnect. hssPktAcc will pass + * received data in the form of mbufs to the client. The mbuf passed back + * to the client could contain a chain of buffers, depending on the packet + * size received. + * + * @param *buffer @ref IX_OSAL_MBUF [in] - This is the mbuf which contains the + * payload received. + * @param numHssErrs unsigned [in] - This is the number of hssErrors + * the Npe has received + * @param pktStatus @ref IxHssAccPktStatus [in] - This is the status of the + * mbuf that has been received. + * @param rxUserId @ref IxHssAccPktUserId [in] - This is the client supplied value + * passed in at ixHssAccPktPortConnect time which is now returned to the client. + * + * @return void + */ +typedef void (*IxHssAccPktRxCallback) (IX_OSAL_MBUF *buffer, + unsigned numHssErrs, + IxHssAccPktStatus pktStatus, + IxHssAccPktUserId rxUserId); + +/** + * @typedef IxHssAccPktRxFreeLowCallback + * @brief Prototype of the clients function to accept notification of + * requirement of more Rx Free buffers + * + * The client can choose to register a callback of this type when + * calling a connecting. This function is registered through the ixHssAccPktPortConnect. + * If defined, the access layer will provide the trigger for + * this callback. The callback will be responsible for supplying mbufs to + * the access layer for use on the receive path from the HSS using + * ixHssPktAccFreeBufReplenish. + * + * @return void + */ +typedef void (*IxHssAccPktRxFreeLowCallback) (IxHssAccPktUserId rxFreeLowUserId); + +/** + * @typedef IxHssAccPktTxDoneCallback + * @brief Prototype of the clients function to accept notification of + * completion with Tx buffers + * + * This function is registered through the ixHssAccPktPortConnect. It enables + * the hssPktAcc to pass buffers back to the client + * when transmission is complete. + * + * @param *buffer @ref IX_OSAL_MBUF [in] - This is the mbuf which contained + * the payload that was for Tx. + * @param numHssErrs unsigned [in] - This is the number of hssErrors + * the Npe has received + * @param pktStatus @ref IxHssAccPktStatus [in] - This is the status of the + * mbuf that has been transmitted. + * @param txDoneUserId @ref IxHssAccPktUserId [in] - This is the client supplied value + * passed in at ixHssAccPktPortConnect time which is now returned to the client. + * + * @return void + */ +typedef void (*IxHssAccPktTxDoneCallback) (IX_OSAL_MBUF *buffer, + unsigned numHssErrs, + IxHssAccPktStatus pktStatus, + IxHssAccPktUserId txDoneUserId); + +/** + * @typedef IxHssAccChanRxCallback + * @brief Prototype of the clients function to accept notification of + * channelised rx + * + * This callback, if defined by the client in the connect, will get called + * in the context of an IRQ. The IRQ will be triggered when the hssSyncQMQ + * is not empty. The queued entry will be dequeued and this function will + * be executed. + * + * @param hssPortId @ref IxHssAccHssPort - The HSS port Id. There are two + * identical ports (0-1). + * @param txOffset unsigned [in] - an offset indicating from where within + * the txPtrList the NPE is currently transmitting from. + * @param rxOffset unsigned [in] - an offset indicating where within the + * receive buffers the NPE has just written the received data to. + * @param numHssErrs unsigned [in] - This is the number of hssErrors + * the Npe has received + * + * @return void + */ +typedef void (*IxHssAccChanRxCallback) (IxHssAccHssPort hssPortId, + unsigned rxOffset, + unsigned txOffset, + unsigned numHssErrs); + +/* + * Prototypes for interface functions. + */ + +/** + * + * @ingroup IxHssAccAPI + * + * @fn IX_STATUS ixHssAccPortInit (IxHssAccHssPort hssPortId, + IxHssAccConfigParams *configParams, + IxHssAccTdmSlotUsage *tdmMap, + IxHssAccLastErrorCallback lastHssErrorCallback) + * + * @brief Initialise a HSS port. No channelised or packetised connections + * should exist in the HssAccess layer while this interface is being called. + * + * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two + * identical ports (0-1). + * @param *configParams @ref IxHssAccConfigParams [in] - A pointer to the HSS + * configuration structure + * @param *tdmMap @ref IxHssAccTdmSlotUsage [in] - A pointer to an array of size + * IX_HSSACC_TSLOTS_PER_HSS_PORT, defining the slot usage over the HSS port + * @param lastHssErrorCallback @ref IxHssAccLastErrorCallback [in] - Client + * callback to report last error + * + * @return + * - IX_SUCCESS The function executed successfully + * - IX_FAIL The function did not execute successfully + * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a + * parameter error + */ +PUBLIC IX_STATUS +ixHssAccPortInit (IxHssAccHssPort hssPortId, + IxHssAccConfigParams *configParams, + IxHssAccTdmSlotUsage *tdmMap, + IxHssAccLastErrorCallback lastHssErrorCallback); + +/** + * + * @ingroup IxHssAccAPI + * + * @fn IX_STATUS ixHssAccLastErrorRetrievalInitiate ( + IxHssAccHssPort hssPortId) + * + * @brief Initiate the retrieval of the last HSS error. The HSS port + * should be configured before attempting to call this interface. + * + * @param hssPortId @ref IxHssAccHssPort [in] - the HSS port ID + * + * @return + * - IX_SUCCESS The function executed successfully + * - IX_FAIL The function did not execute successfully + * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a + * parameter error + */ +PUBLIC IX_STATUS +ixHssAccLastErrorRetrievalInitiate (IxHssAccHssPort hssPortId); + + +/** + * + * @ingroup IxHssAccAPI + * + * @fn IX_STATUS ixHssAccInit () + * + * @brief This function is responsible for initialising resources for use + * by the packetised and channelised clients. It should be called after + * HSS NPE image has been downloaded into NPE-A and before any other + * HssAccess interface is called. + * No other HssAccPacketised interface should be called while this interface + * is being processed. + * + * @return + * - IX_SUCCESS The function executed successfully + * - IX_FAIL The function did not execute successfully + * - IX_HSSACC_RESOURCE_ERR The function did not execute successfully due + * to a resource error + */ +PUBLIC IX_STATUS +ixHssAccInit (void); + + +/** + * + * @ingroup IxHssAccAPI + * + * @fn ixHssAccPktPortConnect (IxHssAccHssPort hssPortId, + IxHssAccHdlcPort hdlcPortId, + BOOL hdlcFraming, + IxHssAccHdlcMode hdlcMode, + BOOL hdlcBitInvert, + unsigned blockSizeInWords, + UINT32 rawIdleBlockPattern, + IxHssAccPktHdlcFraming hdlcTxFraming, + IxHssAccPktHdlcFraming hdlcRxFraming, + unsigned frmFlagStart, + IxHssAccPktRxCallback rxCallback, + IxHssAccPktUserId rxUserId, + IxHssAccPktRxFreeLowCallback rxFreeLowCallback, + IxHssAccPktUserId rxFreeLowUserId, + IxHssAccPktTxDoneCallback txDoneCallback, + IxHssAccPktUserId txDoneUserId) + * + * @brief This function is responsible for connecting a client to one of + * the 4 available HDLC ports. The HSS port should be configured before + * attempting a connect. No other HssAccPacketised interface should be + * called while this connect is being processed. + * + * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two + * identical ports (0-1). + * @param hdlcPortId @ref IxHssAccHdlcPort [in] - This is the number of the HDLC port and + * it corresponds to the physical E1/T1 trunk i.e. 0, 1, 2, 3 + * @param hdlcFraming BOOL [in] - This value determines whether the service + * will use HDLC data or the debug, raw data type i.e. no HDLC processing + * @param hdlcMode @ref IxHssAccHdlcMode [in] - This structure contains 56Kbps, HDLC-mode + * configuration parameters + * @param hdlcBitInvert BOOL [in] - This value determines whether bit inversion + * will occur between HDLC and HSS co-processors i.e. post-HDLC processing for + * transmit and pre-HDLC processing for receive, for the specified HDLC Termination + * Point + * @param blockSizeInWords unsigned [in] - The max tx/rx block size + * @param rawIdleBlockPattern UINT32 [in] - Tx idle pattern in raw mode + * @param hdlcTxFraming @ref IxHssAccPktHdlcFraming [in] - This structure contains + * the following information required by the NPE to configure the HDLC + * co-processor for TX + * @param hdlcRxFraming @ref IxHssAccPktHdlcFraming [in] - This structure contains + * the following information required by the NPE to configure the HDLC + * co-processor for RX + * @param frmFlagStart unsigned - Number of flags to precede to + * transmitted flags (0-2). + * @param rxCallback @ref IxHssAccPktRxCallback [in] - Pointer to + * the clients packet receive function. + * @param rxUserId @ref IxHssAccPktUserId [in] - The client supplied rx value + * to be passed back as an argument to the supplied rxCallback + * @param rxFreeLowCallback @ref IxHssAccPktRxFreeLowCallback [in] - Pointer to + * the clients Rx free buffer request function. If NULL, assume client will + * trigger independently. + * @param rxFreeLowUserId @ref IxHssAccPktUserId [in] - The client supplied RxFreeLow value + * to be passed back as an argument to the supplied rxFreeLowCallback + * @param txDoneCallback @ref IxHssAccPktTxDoneCallback [in] - Pointer to the + * clients Tx done callback function + * @param txDoneUserId @ref IxHssAccPktUserId [in] - The client supplied txDone value + * to be passed back as an argument to the supplied txDoneCallback + * + * @return + * - IX_SUCCESS The function executed successfully + * - IX_FAIL The function did not execute successfully + * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a + * parameter error + * - IX_HSSACC_RESOURCE_ERR The function did not execute successfully due + * to a resource error + */ +PUBLIC IX_STATUS +ixHssAccPktPortConnect (IxHssAccHssPort hssPortId, + IxHssAccHdlcPort hdlcPortId, + BOOL hdlcFraming, + IxHssAccHdlcMode hdlcMode, + BOOL hdlcBitInvert, + unsigned blockSizeInWords, + UINT32 rawIdleBlockPattern, + IxHssAccPktHdlcFraming hdlcTxFraming, + IxHssAccPktHdlcFraming hdlcRxFraming, + unsigned frmFlagStart, + IxHssAccPktRxCallback rxCallback, + IxHssAccPktUserId rxUserId, + IxHssAccPktRxFreeLowCallback rxFreeLowCallback, + IxHssAccPktUserId rxFreeLowUserId, + IxHssAccPktTxDoneCallback txDoneCallback, + IxHssAccPktUserId txDoneUserId); + +/** + * + * @ingroup IxHssAccAPI + * + * @fn IX_STATUS ixHssAccPktPortEnable (IxHssAccHssPort hssPortId, + IxHssAccHdlcPort hdlcPortId) + * + * @brief This function is responsible for enabling a packetised service + * for the specified HSS/HDLC port combination. It enables the RX flow. The + * client must have already connected to a packetised service and is responsible + * for ensuring an adequate amount of RX mbufs have been supplied to the access + * component before enabling the packetised service. This function must be called + * on a given port before any call to ixHssAccPktPortTx on the same port. + * No other HssAccPacketised interface should be called while this interface is + * being processed. + * + * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two + * identical ports (0-1). + * @param hdlcPortId @ref IxHssAccHdlcPort [in] - The port id (0,1,2,3) to enable the service + * on. + * + * @return + * - IX_SUCCESS The function executed successfully + * - IX_FAIL The function did not execute successfully + * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a + * parameter error + */ +PUBLIC IX_STATUS +ixHssAccPktPortEnable (IxHssAccHssPort hssPortId, + IxHssAccHdlcPort hdlcPortId); + +/** + * @fn IX_STATUS ixHssAccPktPortDisable (IxHssAccHssPort hssPortId, + IxHssAccHdlcPort hdlcPortId) + * + * @brief This function is responsible for disabling a packetised service + * for the specified HSS/HDLC port combination. It disables the RX flow. + * The client must have already connected to and enabled a packetised service + * for the specified HDLC port. This disable interface can be called before a + * disconnect, but is not required to. + * + * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two + * identical ports (0-1). + * @param hdlcPortId @ref IxHssAccHdlcPort [in] - The port id (0,1,2,3) to disable + * the service on. + * + * @return + * - IX_SUCCESS The function executed successfully + * - IX_FAIL The function did not execute successfully + * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a + * parameter error + */ +PUBLIC IX_STATUS +ixHssAccPktPortDisable (IxHssAccHssPort hssPortId, + IxHssAccHdlcPort hdlcPortId); + +/** + * + * @ingroup IxHssAccAPI + * + * @fn IX_STATUS ixHssAccPktPortDisconnect (IxHssAccHssPort hssPortId, + IxHssAccHdlcPort hdlcPortId) + * + * @brief This function is responsible for disconnecting a client from one + * of the 4 available HDLC ports. It is not required that the Rx Flow + * has been disabled before calling this function. If the RX Flow has not been + * disabled, the disconnect will disable it before proceeding with the + * disconnect. No other HssAccPacketised + * interface should be called while this interface is being processed. + * + * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two + * identical ports (0-1). + * @param hdlcPortId @ref IxHssAccHdlcPort [in] - This is the number of the HDLC port + * to disconnect and it corresponds to the physical E1/T1 trunk i.e. 0, 1, 2, 3 + * + * @return + * - IX_SUCCESS The function executed successfully + * - IX_FAIL The function did not execute successfully + * - IX_HSSACC_PKT_DISCONNECTING The function has initiated the disconnecting + * procedure but it has not completed yet. + */ +PUBLIC IX_STATUS +ixHssAccPktPortDisconnect (IxHssAccHssPort hssPortId, + IxHssAccHdlcPort hdlcPortId); + +/** + * + * @ingroup IxHssAccAPI + * + * @fn BOOL ixHssAccPktPortIsDisconnectComplete (IxHssAccHssPort hssPortId, + IxHssAccHdlcPort hdlcPortId) + * + * @brief This function is called to check if a given HSS/HDLC port + * combination is in a connected state or not. This function may be called + * at any time to determine a ports state. No other HssAccPacketised + * interface should be called while this interface is being processed. + * + * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two + * identical ports (0-1). + * @param hdlcPortId @ref IxHssAccHdlcPort [in] - This is the number of the HDLC port + * to disconnect and it corresponds to the physical E1/T1 trunk i.e. 0, 1, 2, 3 + * + * @return + * - TRUE The state of this HSS/HDLC port combination is disconnected, + * so if a disconnect was called, it is now completed. + * - FALSE The state of this HSS/HDLC port combination is connected, + * so if a disconnect was called, it is not yet completed. + */ +PUBLIC BOOL +ixHssAccPktPortIsDisconnectComplete (IxHssAccHssPort hssPortId, + IxHssAccHdlcPort hdlcPortId); + + +/** + * + * @ingroup IxHssAccAPI + * + * @fn IX_STATUS ixHssAccPktPortRxFreeReplenish (IxHssAccHssPort hssPortId, + IxHssAccHdlcPort hdlcPortId, + IX_OSAL_MBUF *buffer) + * + * @brief Function which the client calls at regular intervals to provide + * mbufs to the access component for RX. A connection should exist for + * the specified hssPortId/hdlcPortId combination before attempting to call this + * interface. Also, the connection should not be in a disconnecting state. + * + * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two + * identical ports (0-1). + * @param hdlcPortId @ref IxHssAccHdlcPort [in] - This is the number of the HDLC port + * and it corresponds to the physical E1/T1 trunk i.e. 0, 1, 2, 3 + * @param *buffer @ref IX_OSAL_MBUF [in] - A pointer to a free mbuf to filled with payload. + * + * @return + * - IX_SUCCESS The function executed successfully + * - IX_FAIL The function did not execute successfully + * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a + * parameter error + * - IX_HSSACC_RESOURCE_ERR The function did not execute successfully due + * to a resource error + * - IX_HSSACC_Q_WRITE_OVERFLOW The function did not succeed due to a Q + * overflow + */ +PUBLIC IX_STATUS +ixHssAccPktPortRxFreeReplenish (IxHssAccHssPort hssPortId, + IxHssAccHdlcPort hdlcPortId, + IX_OSAL_MBUF *buffer); + +/** + * + * @ingroup IxHssAccAPI + * + * @fn IX_STATUS ixHssAccPktPortTx (IxHssAccHssPort hssPortId, + IxHssAccHdlcPort hdlcPortId, + IX_OSAL_MBUF *buffer) + * + * @brief Function which the client calls when it wants to transmit + * packetised data. An enabled connection should exist on the specified + * hssPortId/hdlcPortId combination before attempting to call this interface. + * No other HssAccPacketised + * interface should be called while this interface is being processed. + * + * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two + * identical ports (0-1). + * @param hdlcPortId @ref IxHssAccHdlcPort [in] - This is the number of the HDLC port + * and it corresponds to the physical E1/T1 trunk i.e. 0, 1, 2, 3 + * @param *buffer @ref IX_OSAL_MBUF [in] - A pointer to a chain of mbufs which the + * client has filled with the payload + * + * @return + * - IX_SUCCESS The function executed successfully + * - IX_FAIL The function did not execute successfully + * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a + * parameter error + * - IX_HSSACC_RESOURCE_ERR The function did not execute successfully due + * to a resource error. See note. + * - IX_HSSACC_Q_WRITE_OVERFLOW The function did not succeed due to a Q + * overflow + * + * @note IX_HSSACC_RESOURCE_ERR is returned when a free descriptor cannot be + * obtained to send the chain of mbufs to the NPE. This is a normal scenario. + * HssAcc has a pool of descriptors and this error means that they are currently + * all in use. + * The recommended approach to this is to retry until a descriptor becomes free + * and the packet is successfully transmitted. + * Alternatively, the user could wait until the next IxHssAccPktTxDoneCallback + * callback is triggered, and then retry, as it is this event that causes a + * transmit descriptor to be freed. + */ +PUBLIC IX_STATUS +ixHssAccPktPortTx (IxHssAccHssPort hssPortId, + IxHssAccHdlcPort hdlcPortId, + IX_OSAL_MBUF *buffer); + +/** + * + * @ingroup IxHssAccAPI + * + * @fn IX_STATUS ixHssAccChanConnect (IxHssAccHssPort hssPortId, + unsigned bytesPerTSTrigger, + UINT8 *rxCircular, + unsigned numRxBytesPerTS, + UINT32 *txPtrList, + unsigned numTxPtrLists, + unsigned numTxBytesPerBlk, + IxHssAccChanRxCallback rxCallback) + * + * @brief This function allows the client to connect to the Tx/Rx NPE + * Channelised Service. There can only be one client per HSS port. The + * client is responsible for ensuring that the HSS port is configured + * appropriately before its connect request. No other HssAccChannelised + * interface should be called while this interface is being processed. + * + * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two + * identical ports (0-1). + * @param bytesPerTSTrigger unsigned [in] - The NPE will trigger the access + * component after bytesPerTSTrigger have been received for all trunk + * timeslots. This figure is a multiple of 8 e.g. 8 for 1ms trigger, 16 for + * 2ms trigger. + * @param *rxCircular UINT8 [in] - A pointer to memory allocated by the + * client to be filled by data received. The buffer at this address is part + * of a pool of buffers to be accessed in a circular fashion. This address + * will be written to by the NPE. Therefore, it needs to be a physical address. + * @param numRxBytesPerTS unsigned [in] - The number of bytes allocated per + * timeslot within the receive memory. This figure will depend on the + * latency of the system. It needs to be deep enough for data to be read by + * the client before the NPE re-writes over that memory e.g. if the client + * samples at a rate of 40bytes per timeslot, numRxBytesPerTS may need to + * be 40bytes * 3. This would give the client 3 * 5ms of time before + * received data is over-written. + * @param *txPtrList UINT32 [in] - The address of an area of contiguous + * memory allocated by the client to be populated with pointers to data for + * transmission. Each pointer list contains a pointer per active channel. + * The txPtrs will point to data to be transmitted by the NPE. Therefore, + * they must point to physical addresses. + * @param numTxPtrLists unsigned [in] - The number of pointer lists in + * txPtrList. This figure is dependent on jitter. + * @param numTxBytesPerBlk unsigned [in] - The size of the Tx data, in + * bytes, that each pointer within the PtrList points to. + * @param rxCallback @ref IxHssAccChanRxCallback [in] - A client function + * pointer to be called back to handle the actual tx/rx of channelised + * data. If this is not NULL, an ISR will call this function. If this + * pointer is NULL, it implies that the client will use a polling mechanism + * to detect when the tx and rx of channelised data is to occur. The client + * will use hssChanAccStatus for this. + * + * @return + * - IX_SUCCESS The function executed successfully + * - IX_FAIL The function did not execute successfully + * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a + * parameter error + */ + +PUBLIC IX_STATUS +ixHssAccChanConnect (IxHssAccHssPort hssPortId, + unsigned bytesPerTSTrigger, + UINT8 *rxCircular, + unsigned numRxBytesPerTS, + UINT32 *txPtrList, + unsigned numTxPtrLists, + unsigned numTxBytesPerBlk, + IxHssAccChanRxCallback rxCallback); + +/** + * + * @ingroup IxHssAccAPI + * + * @fn IX_STATUS ixHssAccChanPortEnable (IxHssAccHssPort hssPortId) + * + * @brief This function is responsible for enabling a channelised service + * for the specified HSS port. It enables the NPE RX flow. The client must + * have already connected to a channelised service before enabling the + * channelised service. No other HssAccChannelised + * interface should be called while this interface is being processed. + * + * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two + * identical ports (0-1). + * + * @return + * - IX_SUCCESS The function executed successfully + * - IX_FAIL The function did not execute successfully + * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a + * parameter error + */ +PUBLIC IX_STATUS +ixHssAccChanPortEnable (IxHssAccHssPort hssPortId); + +/** + * + * @ingroup IxHssAccAPI + * + * @fn IX_STATUS ixHssAccChanPortDisable (IxHssAccHssPort hssPortId) + * + * @brief This function is responsible for disabling a channelised service + * for the specified HSS port. It disables the NPE RX flow. The client must + * have already connected to and enabled a channelised service for the + * specified HSS port. This disable interface can be called before a + * disconnect, but is not required to. No other HssAccChannelised + * interface should be called while this interface is being processed. + * + * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two + * identical ports (0-1). + * + * @return + * - IX_SUCCESS The function executed successfully + * - IX_FAIL The function did not execute successfully + * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a + * parameter error + */ +PUBLIC IX_STATUS +ixHssAccChanPortDisable (IxHssAccHssPort hssPortId); + +/** + * + * @ingroup IxHssAccAPI + * + * @fn IX_STATUS ixHssAccChanDisconnect (IxHssAccHssPort hssPortId) + * + * @brief This function allows the client to Disconnect from a channelised + * service. If the NPE RX Flow has not been disabled, the disconnect will + * disable it before proceeding with other disconnect functionality. + * No other HssAccChannelised interface should be called while this + * interface is being processed. + * + * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two + * identical ports (0-1). + * + * @return + * - IX_SUCCESS The function executed successfully + * - IX_FAIL The function did not execute successfully + * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a + * parameter error + */ +PUBLIC IX_STATUS +ixHssAccChanDisconnect (IxHssAccHssPort hssPortId); + +/** + * + * @ingroup IxHssAccAPI + * + * @fn IX_STATUS ixHssAccChanStatusQuery (IxHssAccHssPort hssPortId, + BOOL *dataRecvd, + unsigned *rxOffset, + unsigned *txOffset, + unsigned *numHssErrs) + * + * @brief This function is called by the client to query whether or not + * channelised data has been received. If there is, hssChanAcc will return + * the details in the output parameters. An enabled connection should + * exist on the specified hssPortId before attempting to call this interface. + * No other HssAccChannelised interface should be called while this + * interface is being processed. + * + * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two + * identical ports (0-1). + * @param *dataRecvd BOOL [out] - This BOOL indicates to the client whether + * or not the access component has read any data for the client. If + * FALSE, the other output parameters will not have been written to. + * @param *rxOffset unsigned [out] - An offset to indicate to the client + * where within the receive buffers the NPE has just written the received + * data to. + * @param *txOffset unsigned [out] - An offset to indicate to the client + * from where within the txPtrList the NPE is currently transmitting from + * @param *numHssErrs unsigned [out] - The total number of HSS port errors + * since initial port configuration + * + * + * @return + * - IX_SUCCESS The function executed successfully + * - IX_FAIL The function did not execute successfully + * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a + * parameter error + */ +PUBLIC IX_STATUS +ixHssAccChanStatusQuery (IxHssAccHssPort hssPortId, + BOOL *dataRecvd, + unsigned *rxOffset, + unsigned *txOffset, + unsigned *numHssErrs); + +/** + * + * @ingroup IxHssAccAPI + * + * @fn void ixHssAccShow (void) + * + * @brief This function will display the current state of the IxHssAcc + * component. The output is sent to stdout. + * + * @return void + */ +PUBLIC void +ixHssAccShow (void); + +/** + * + * @ingroup IxHssAccAPI + * + * @fn void ixHssAccStatsInit (void) + * + * @brief This function will reset the IxHssAcc statistics. + * + * @return void + */ +PUBLIC void +ixHssAccStatsInit (void); + +#endif /* IXHSSACC_H */ + +/** + * @} defgroup IxHssAcc + */ diff --git a/arch/arm/cpu/ixp/npe/include/IxI2cDrv.h b/arch/arm/cpu/ixp/npe/include/IxI2cDrv.h new file mode 100644 index 0000000000..92c6b24b46 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/IxI2cDrv.h @@ -0,0 +1,867 @@ +/** + * @file IxI2cDrv.h + * + * @brief Header file for the IXP400 I2C Driver (IxI2cDrv) + * + * @version $Revision: 0.1 $ + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +/** + * @defgroup IxI2cDrv IXP400 I2C Driver(IxI2cDrv) API + * + * @brief IXP400 I2C Driver Public API + * + * @{ + */ +#ifndef IXI2CDRV_H +#define IXI2CDRV_H + +#ifdef __ixp46X +#include "IxOsal.h" + +/* + * Section for #define + */ + +/** + * @ingroup IxI2cDrv + * @brief The interval of micro/mili seconds the IXP will wait before it polls for + * status from the ixI2cIntrXferStatus; Every 20us is 1 byte @ + * 400Kbps and 4 bytes @ 100Kbps. This is dependent on delay type selected + * through the API ixI2cDrvDelayTypeSelect. + */ +#define IX_I2C_US_POLL_FOR_XFER_STATUS 20 + +/** + * @ingroup IxI2cDrv + * @brief The number of tries that will be attempted to call a callback + * function if the callback does not or is unable to resolve the + * issue it is called to resolve + */ +#define IX_I2C_NUM_OF_TRIES_TO_CALL_CALLBACK_FUNC 10 + + +/** + * @ingroup IxI2cDrv + * @brief Number of tries slave will poll the IDBR Rx full bit before it + * gives up + */ +#define IX_I2C_NUM_TO_POLL_IDBR_RX_FULL 0x100 + +/** + * @ingroup IxI2cDrv + * @brief Number of tries slave will poll the IDBR Tx empty bit before it + * gives up + */ +#define IX_I2C_NUM_TO_POLL_IDBR_TX_EMPTY 0x100 + +/* + * Section for enum + */ + +/** + * @ingroup IxI2cDrv + * + * @enum IxI2cMasterStatus + * + * @brief The master status - transfer complete, bus error or arbitration loss + */ +typedef enum +{ + IX_I2C_MASTER_XFER_COMPLETE = IX_SUCCESS, + IX_I2C_MASTER_XFER_BUS_ERROR, + IX_I2C_MASTER_XFER_ARB_LOSS +} IxI2cMasterStatus; + + +/** + * @ingroup IxI2cDrv + * + * @enum IX_I2C_STATUS + * + * @brief The status that can be returned in a I2C driver initialization + */ +typedef enum +{ + IX_I2C_SUCCESS = IX_SUCCESS, /**< Success status */ + IX_I2C_FAIL, /**< Fail status */ + IX_I2C_NOT_SUPPORTED, /**< hardware does not have dedicated I2C hardware */ + IX_I2C_NULL_POINTER, /**< parameter passed in is NULL */ + IX_I2C_INVALID_SPEED_MODE_ENUM_VALUE, /**< speed mode selected is invalid */ + IX_I2C_INVALID_FLOW_MODE_ENUM_VALUE, /**< flow mode selected is invalid */ + IX_I2C_SLAVE_ADDR_CB_MISSING, /**< slave callback is NULL */ + IX_I2C_GEN_CALL_CB_MISSING, /**< general callback is NULL */ + IX_I2C_INVALID_SLAVE_ADDR, /**< invalid slave address specified */ + IX_I2C_INT_BIND_FAIL, /**< interrupt bind fail */ + IX_I2C_INT_UNBIND_FAIL, /**< interrupt unbind fail */ + IX_I2C_NOT_INIT, /**< I2C is not initialized yet */ + IX_I2C_MASTER_BUS_BUSY, /**< master detected a I2C bus busy */ + IX_I2C_MASTER_ARB_LOSS, /**< master experienced arbitration loss */ + IX_I2C_MASTER_XFER_ERROR, /**< master experienced a transfer error */ + IX_I2C_MASTER_BUS_ERROR, /**< master detected a I2C bus error */ + IX_I2C_MASTER_NO_BUFFER, /**< no buffer provided for master transfer */ + IX_I2C_MASTER_INVALID_XFER_MODE, /**< xfer mode selected is invalid */ + IX_I2C_SLAVE_ADDR_NOT_DETECTED, /**< polled slave addr not detected */ + IX_I2C_GEN_CALL_ADDR_DETECTED, /**< polling detected general call */ + IX_I2C_SLAVE_READ_DETECTED, /**< polling detected slave read request */ + IX_I2C_SLAVE_WRITE_DETECTED, /**< polling detected slave write request */ + IX_I2C_SLAVE_NO_BUFFER, /**< no buffer provided for slave transfers */ + IX_I2C_DATA_SIZE_ZERO, /**< data size transfer is zero - invalid */ + IX_I2C_SLAVE_WRITE_BUFFER_EMPTY, /**< slave buffer is used till empty */ + IX_I2C_SLAVE_WRITE_ERROR, /**< slave write experienced an error */ + IX_I2C_SLAVE_OR_GEN_READ_BUFFER_FULL, /**< slave buffer is filled up */ + IX_I2C_SLAVE_OR_GEN_READ_ERROR /**< slave read experienced an error */ +} IX_I2C_STATUS; + +/** + * @ingroup IxI2cDrv + * + * @enum IxI2cSpeedMode + * + * @brief Type of speed modes supported by the I2C hardware. + */ +typedef enum +{ + IX_I2C_NORMAL_MODE = 0x0, + IX_I2C_FAST_MODE +} IxI2cSpeedMode; + +/** + * @ingroup IxI2cDrv + * + * @enum IxI2cXferMode + * + * @brief Used for indicating it is a repeated start or normal transfer + */ +typedef enum +{ + IX_I2C_NORMAL = 0x0, + IX_I2C_REPEATED_START +} IxI2cXferMode; + +/** + * @ingroup IxI2cDrv + * + * @enum IxI2cFlowMode + * + * @brief Used for indicating it is a poll or interrupt mode + */ +typedef enum +{ + IX_I2C_POLL_MODE = 0x0, + IX_I2C_INTERRUPT_MODE +} IxI2cFlowMode; + +/** + * @ingroup IxI2cDrv + * + * @enum IxI2cDelayMode + * + * @brief Used for selecting looping delay or OS scheduler delay + */ +typedef enum +{ + IX_I2C_LOOP_DELAY = 1, /**< delay in microseconds */ + IX_I2C_SCHED_DELAY /**< delay in miliseconds */ +} IxI2cDelayMode; + +/** + * @ingroup IxI2cDrv + * + * @brief The pointer to the function that will be called when the master + * has completed its receive. The parameter that is passed will + * provide the status of the read (success, arb loss, or bus + * error), the transfer mode (normal or repeated start, the + * buffer pointer and number of bytes transferred. + */ +typedef void (*IxI2cMasterReadCallbackP)(IxI2cMasterStatus, IxI2cXferMode, char*, UINT32); + +/** + * @ingroup IxI2cDrv + * + * @brief The pointer to the function that will be called when the master + * has completed its transmit. The parameter that is passed will + * provide the status of the write (success, arb loss, or buss + * error), the transfer mode (normal or repeated start), the + * buffer pointer and number of bytes transferred. + */ +typedef void (*IxI2cMasterWriteCallbackP)(IxI2cMasterStatus, IxI2cXferMode, char*, UINT32); + +/** + * @ingroup IxI2cDrv + * + * @brief The pointer to the function that will be called when a slave + * address detected in interrupt mode for a read. The parameters + * that is passed will provide the read status, buffer pointer, + * buffer size, and the bytes received. When a start of a read + * is initiated there will be no buffer allocated and this callback + * will be called to request for a buffer. While receiving, if the + * buffer gets filled, this callback will be called to request for + * a new buffer while sending the filled buffer's pointer and size, + * and data size received. When the receive is complete, this + * callback will be called to process the data and free the memory + * by passing the buffer's pointer and size, and data size received. + */ +typedef void (*IxI2cSlaveReadCallbackP)(IX_I2C_STATUS, char*, UINT32, UINT32); + +/** + * @ingroup IxI2cDrv + * + * @brief The pointer to the function that will be called when a slave + * address detected in interrupt mode for a write. The parameters + * that is passed will provide the write status, buffer pointer, + * buffer size, and the bytes received. When a start of a write is + * initiated there will be no buffer allocated and this callback + * will be called to request for a buffer and to fill it with data. + * While transmitting, if the data in the buffer empties, this + * callback will be called to request for more data to be filled in + * the same or new buffer. When the transmit is complete, this + * callback will be called to free the memory or other actions to + * be taken. + */ +typedef void (*IxI2cSlaveWriteCallbackP)(IX_I2C_STATUS, char*, UINT32, UINT32); + +/** + * @ingroup IxI2cDrv + * + * @brief The pointer to the function that will be called when a general + * call detected in interrupt mode for a read. The parameters that + * is passed will provide the read status, buffer pointer, buffer + * size, and the bytes received. When a start of a read is + * initiated there will be no buffer allocated and this callback + * will be called to request for a buffer. While receiving, if the + * buffer gets filled, this callback will be called to request for + * a new buffer while sending the filled buffer's pointer and size, + * and data size received. When the receive is complete, this + * callback will be called to process the data and free the memory + * by passing the buffer's pointer and size, and data size received. + */ +typedef void (*IxI2cGenCallCallbackP)(IX_I2C_STATUS, char*, UINT32, UINT32); + +/* + * Section for struct + */ + +/** + * @brief contains all the variables required to initialize the I2C unit + * + * Structure to be filled and used for calling initialization + */ +typedef struct +{ + IxI2cSpeedMode I2cSpeedSelect; /** + * NOTE: 1) An individual callback is to be registered for each Slave and Master + * Auxiliary Time Stamp registers. Thus to register for both Master and Slave time + * stamp interrupts either the same callback or two separate callbacks the API has + * to be invoked twice. + * 2) On the IXDP465 Development Platform, the Auxiliary Timestamp signal for + * slave mode is tied to GPIO 8 pin. This signal is software routed by default to + * PCI for backwards compatibility with the IXDP425 Development Platform. This + * routing must be disabled for the auxiliary slave time stamp register to work + * properly. The following commands may be used to accomplish this. However, refer + * to the IXDP465 Development Platform Users Guide or the BSP/LSP documentation for + * more specific information. + * + * For Linux (at the Redboot prompt i.e., before loading zImage): + * mfill -b 0x54100000 -1 -l 1 -p 8 + * mfill -b 0x54100001 -1 -l 1 -p 0x7f + * For vxWorks, at the prompt: + * intDisable(25) + * ixdp400FpgaIODetach(8) + * + * + * @li Re-entrant : no + * @li ISR Callable : no + * + * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful + * @li IX_TIMESYNCACC_INVALIDPARAM - Null parameter passed for callback or + invalid auxiliary snapshot mode + * @li IX_TIMESYNCACC_FAILED - Internal error occurred + */ +PUBLIC IxTimeSyncAccStatus +ixTimeSyncAccAuxTimeInterruptEnable(IxTimeSyncAccAuxMode auxMode, + IxTimeSyncAccAuxTimeCallback auxTimeCallback); + +/** + * @ingroup IxTimeSyncAcc + * + * @fn IxTimeSyncAccStatus ixTimeSyncAccAuxTimeInterruptDisable( + IxTimeSyncAccAuxMode auxMode) + * + * @brief Disables the interrupt for the indicated mode of Auxiliary Time Stamp + * in the IEEE 1588 hardware assist block + * + * @param auxMode [in] - Auxiliary time stamp mode (slave or master) using which + * the interrupt will be disabled. + * + * This API will disable the Auxiliary Time Stamp Interrupt (Master or Slave) + * + * @li Re-entrant : yes + * @li ISR Callable : no + * + * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful + * @li IX_TIMESYNCACC_INVALIDPARAM - Invalid parameters passed + * @li IX_TIMESYNCACC_FAILED - Internal error occurred + */ +PUBLIC IxTimeSyncAccStatus +ixTimeSyncAccAuxTimeInterruptDisable(IxTimeSyncAccAuxMode auxMode); + +/** + * @ingroup IxTimeSyncAcc + * + * @fn IxTimeSyncAccStatus ixTimeSyncAccAuxTimePoll( + IxTimeSyncAccAuxMode auxMode, + BOOL *auxPollFlag, + IxTimeSyncAccTimeValue *auxTime) + * + * @brief Poll for the Auxiliary Time Stamp captured for the mode indicated + * (Master or Slave) + * + * @param auxMode [in] - Auxiliary Snapshot Register (Slave or Master) to be checked + * @param auxPollFlag [out] - TRUE if the time stamp captured in auxiliary + snapshot register + * FALSE if the time stamp not captured in + auxiliary snapshot register + * @param auxTime [out] - Copy the current Auxiliary Snapshot Register value into the + * client provided buffer + * + * Polls for the Time stamp in the appropriate Auxiliary Snapshot Registers based + * on the mode specified. Return true and the contents of the Auxiliary snapshot, + * if it is available else return false. + * + * Please refer to the note #2 of the API @ref ixTimeSyncAccAuxTimeInterruptEnable + * for more information for Auxiliary Slave mode. + * + * @li Re-entrant : yes + * @li ISR Callable : no + * + * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful + * @li IX_TIMESYNCACC_INVALIDPARAM - Null parameter passed for auxPollFlag, + callback or invalid auxiliary snapshot mode + * @li IX_TIMESYNCACC_FAILED - Internal error occurred + * @li IX_TIMESYNCACC_INTERRUPTMODEINUSE - Interrupt mode in use + */ +PUBLIC IxTimeSyncAccStatus +ixTimeSyncAccAuxTimePoll(IxTimeSyncAccAuxMode auxMode, + BOOL *auxPollFlag, + IxTimeSyncAccTimeValue *auxTime); + +/** + * @ingroup IxTimeSyncAcc + * + * @fn IxTimeSyncAccStatus ixTimeSyncAccReset(void) + * + * @brief Resets the IEEE 1588 hardware assist block + * + * Sets the reset bit in the IEEE1588 silicon which fully resets the silicon block + * + * @li Reentrant : yes + * @li ISR Callable : no + * + * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful + * @li IX_TIMESYNCACC_FAILED - Internal error occurred + */ +PUBLIC IxTimeSyncAccStatus +ixTimeSyncAccReset(void); + +/** + * @ingroup IxTimeSyncAcc + * + * @fn IxTimeSyncAccStatus ixTimeSyncAccStatsGet(IxTimeSyncAccStats + *timeSyncStats) + * + * @brief Returns the IxTimeSyncAcc Statistics in the client supplied buffer + * + * @param timeSyncStats [out] - TimeSync statistics counter values + * + * This API will return the statistics of the received or transmitted messages. + * + * NOTE: 1) These counters are updated only when the client polls for the time + * stamps or interrupt are enabled. This is because the IxTimeSyncAcc module + * does not either transmit or receive messages and does only run the code + * when explicit requests received by client application. + * + * 2) These statistics reflect the number of valid PTP messages exchanged + * in Master and Slave modes but includes all the messages (including valid + * non-PTP messages) while operating in the Any mode. + * + * @li Reentrant : no + * @li ISR Callable : no + * + * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful + * @li IX_TIMESYNCACC_INVALIDPARAM - NULL parameter passed + * @li IX_TIMESYNCACC_FAILED - Internal error occurred + */ +PUBLIC IxTimeSyncAccStatus +ixTimeSyncAccStatsGet(IxTimeSyncAccStats *timeSyncStats); + +/** + * @ingroup IxTimeSyncAcc + * + * @fn void ixTimeSyncAccStatsReset(void) + * + * @brief Reset Time Sync statistics + * + * This API will reset the statistics counters of the TimeSync access layer. + * + * @li Reentrant : yes + * @li ISR Callable: no + * + * @return @li None + */ +PUBLIC void +ixTimeSyncAccStatsReset(void); + +/** + * @ingroup IxTimeSyncAcc + * + * @fn IxTimeSyncAccStatus ixTimeSyncAccShow(void) + * + * @brief Displays the Time Sync current status + * + * This API will display status on the current configuration of the IEEE + * 1588 hardware assist block, contents of the various time stamp registers, + * outstanding interrupts and/or events. + * + * Note that this is intended for debug only, and in contrast to the other + * functions, it does not clear the any of the status bits associated with + * active timestamps and so is passive in its nature. + * + * @li Reentrant : yes + * @li ISR Callable : no + * + * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful + * @li IX_TIMESYNCACC_FAILED - Internal error occurred + */ +PUBLIC IxTimeSyncAccStatus +ixTimeSyncAccShow(void); + +#endif /* __ixp46X */ +#endif /* IXTIMESYNCACC_H */ + +/** + * @} defgroup IxTimeSyncAcc + */ + diff --git a/arch/arm/cpu/ixp/npe/include/IxTimerCtrl.h b/arch/arm/cpu/ixp/npe/include/IxTimerCtrl.h new file mode 100644 index 0000000000..669dd3ef28 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/IxTimerCtrl.h @@ -0,0 +1,263 @@ +/** + * @file IxTimerCtrl.h + * @brief + * This is the header file for the Timer Control component. + * + * The timer callback control component provides a mechanism by which different + * client components can start a timer and have a supplied callback function + * invoked when the timer expires. + * The callbacks are all dispatched from one thread inside this component. + * Any component that needs to be called periodically should use this facility + * rather than create its own task with a sleep loop. + * + * @par + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- +*/ + +/** + * @defgroup IxTimerCtrl IXP400 Timer Control (IxTimerCtrl) API + * + * @brief The public API for the IXP400 Timer Control Component. + * + * @{ + */ + +#ifndef IxTimerCtrl_H +#define IxTimerCtrl_H + + +#include "IxTypes.h" +/* #include "Ossl.h" */ + +/* + * #defines and macros used in this file. + */ + +/** + * @ingroup IxTimerCtrl + * + * @def IX_TIMERCTRL_NO_FREE_TIMERS + * + * @brief Timer schedule return code. + * + * Indicates that the request to start a timer failed because + * all available timer resources are used. + */ +#define IX_TIMERCTRL_NO_FREE_TIMERS 2 + + +/** + * @ingroup IxTimerCtrl + * + * @def IX_TIMERCTRL_PARAM_ERROR + * + * @brief Timer schedule return code. + * + * Indicates that the request to start a timer failed because + * the client has supplied invalid parameters. + */ +#define IX_TIMERCTRL_PARAM_ERROR 3 + + +/* + * Typedefs whose scope is limited to this file. + */ + +/** + * @ingroup IxTimerCtrl + * + * @brief A typedef for a pointer to a timer callback function. + * @para void * - This parameter is supplied by the client when the + * timer is started and passed back to the client in the callback. + * @note in general timer callback functions should not block or + * take longer than 100ms. This constraint is required to ensure that + * higher priority callbacks are not held up. + * All callbacks are called from the same thread. + * This thread is a shared resource. + * The parameter passed is provided when the timer is scheduled. + */ +typedef void (*IxTimerCtrlTimerCallback)(void *userParam); + + +/** + * @ingroup IxTimerCtrl + * + * @brief List used to identify the users of timers. + * @note The order in this list indicates priority. Components appearing + * higher in the list will be given priority over components lower in the + * list. When adding components, please insert at an appropriate position + * for priority ( i.e values should be less than IxTimerCtrlMaxPurpose ) . + */ +typedef enum +{ + IxTimerCtrlAdslPurpose, + /* Insert new purposes above this line only + */ + IxTimerCtrlMaxPurpose +} +IxTimerCtrlPurpose; + + +/* + * Function definition + */ + +/** + * @ingroup IxTimerCtrl + * + * @fn ixTimerCtrlSchedule(IxTimerCtrlTimerCallback func, + void *userParam, + IxTimerCtrlPurpose purpose, + UINT32 relativeTime, + unsigned *timerId ) + * + * @brief Schedules a callback function to be called after a period of "time". + * The callback function should not block or run for more than 100ms. + * This function + * + * @param func @ref IxTimerCtrlTimerCallback [in] - the callback function to be called. + * @param userParam void [in] - a parameter to send to the callback function, can be NULL. + * @param purpose @ref IxTimerCtrlPurpose [in] - the purpose of the callback, internally this component will + * decide the priority of callbacks with different purpose. + * @param relativeTime UINT32 [in] - time relative to now in milliseconds after which the callback + * will be called. The time must be greater than the duration of one OS tick. + * @param *timerId unsigned [out] - An id for the callback scheduled. + * This id can be used to cancel the callback. + * @return + * @li IX_SUCCESS - The timer was started successfully. + * @li IX_TIMERCTRL_NO_FREE_TIMERS - The timer was not started because the maximum number + * of running timers has been exceeded. + * @li IX_TIMERCTRL_PARAM_ERROR - The timer was not started because the client has supplied + * a NULL callback func, or the requested timeout is less than one OS tick. + * @note This function is re-entrant. The function accesses a list of running timers + * and may suspend the calling thread if this list is being accesed by another thread. + */ +PUBLIC IX_STATUS +ixTimerCtrlSchedule(IxTimerCtrlTimerCallback func, + void *userParam, + IxTimerCtrlPurpose purpose, + UINT32 relativeTime, + unsigned *timerId ); + + +/** + * @ingroup IxTimerCtrl + * + * @fn ixTimerCtrlScheduleRepeating(IxTimerCtrlTimerCallback func, + void *param, + IxTimerCtrlPurpose purpose, + UINT32 interval, + unsigned *timerId ) + * + * @brief Schedules a callback function to be called after a period of "time". + * The callback function should not block or run for more than 100ms. + * + * @param func @ref IxTimerCtrlTimerCallback [in] - the callback function to be called. + * @param userParam void [in] - a parameter to send to the callback function, can be NULL. + * @param purpose @ref IxTimerCtrlPurpose [in] - the purpose of the callback, internally this component will + * decide the priority of callbacks with different purpose. + * @param interval UINT32 [in] - the interval in milliseconds between calls to func. + * @param timerId unsigned [out] - An id for the callback scheduled. + * This id can be used to cancel the callback. + * @return + * @li IX_SUCCESS - The timer was started successfully. + * @li IX_TIMERCTRL_NO_FREE_TIMERS - The timer was not started because the maximum number + * of running timers has been exceeded. + * @li IX_TIMERCTRL_PARAM_ERROR - The timer was not started because the client has supplied + * a NULL callback func, or the requested timeout is less than one OS tick. + * @note This function is re-entrant. The function accesses a list of running timers + * and may suspend the calling thread if this list is being accesed by another thread. + */ +PUBLIC IX_STATUS +ixTimerCtrlScheduleRepeating(IxTimerCtrlTimerCallback func, + void *param, + IxTimerCtrlPurpose purpose, + UINT32 interval, + unsigned *timerId ); + +/** + * @ingroup IxTimerCtrl + * + * @fn ixTimerCtrlCancel (unsigned id) + * + * @brief Cancels a scheduled callback. + * + * @param id unsigned [in] - the id of the callback to be cancelled. + * @return + * @li IX_SUCCESS - The timer was successfully stopped. + * @li IX_FAIL - The id parameter did not corrrespond to any running timer.. + * @note This function is re-entrant. The function accesses a list of running timers + * and may suspend the calling thread if this list is being accesed by another thread. + */ +PUBLIC IX_STATUS +ixTimerCtrlCancel (unsigned id); + +/** + * @ingroup IxTimerCtrl + * + * @fn ixTimerCtrlInit(void) + * + * @brief Initialise the Timer Control Component. + * @return + * @li IX_SUCCESS - The timer control component initialized successfully. + * @li IX_FAIL - The timer control component initialization failed, + * or the component was already initialized. + * @note This must be done before any other API function is called. + * This function should be called once only and is not re-entrant. + */ +PUBLIC IX_STATUS +ixTimerCtrlInit(void); + + +/** + * @ingroup IxTimerCtrl + * + * @fn ixTimerCtrlShow( void ) + * + * @brief Display the status of the Timer Control Component. + * @return void + * @note Displays a list of running timers. + * This function is not re-entrant. This function does not suspend the calling thread. + */ +PUBLIC void +ixTimerCtrlShow( void ); + +#endif /* IXTIMERCTRL_H */ + diff --git a/arch/arm/cpu/ixp/npe/include/IxTypes.h b/arch/arm/cpu/ixp/npe/include/IxTypes.h new file mode 100644 index 0000000000..c4c5a2d267 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/IxTypes.h @@ -0,0 +1,86 @@ +/** + * @file IxTypes.h (Replaced by OSAL) + * + * @date 28-NOV-2001 + + * @brief This file contains basic types used by the IXP400 software + * + * Design Notes: + * This file shall only include fundamental types and definitions to be + * shared by all the IXP400 components. + * Please DO NOT add component-specific types here. + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +/** + * @defgroup IxTypes IXP400 Types (IxTypes) + * + * @brief Basic data types used by the IXP400 project + * + * @{ + */ + +#ifndef IxTypes_H + +#ifndef __doxygen_HIDE + +#define IxTypes_H + +#endif /* __doxygen_HIDE */ + + +/* WR51880: Undefined data types workaround for backward compatibility */ +#ifdef __linux +#ifndef __INCvxTypesOldh +typedef int (*FUNCPTR)(void); +typedef int STATUS; +#define OK (0) +#define ERROR (-1) +#endif +#endif + +#include "IxOsalBackward.h" + +#endif /* IxTypes_H */ + +/** + * @} addtogroup IxTypes + */ diff --git a/arch/arm/cpu/ixp/npe/include/IxUART.h b/arch/arm/cpu/ixp/npe/include/IxUART.h new file mode 100644 index 0000000000..03a44441c5 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/IxUART.h @@ -0,0 +1,458 @@ +/** + * @file IxUART.h + * + * @date 12-OCT-01 + * + * @brief Public header for the Intel IXP400 internal UART, generic driver. + * + * Design Notes: + * This driver allows you to perform the following functions: + * Device Initialization, + * send/receive characters. + * + * Perform Uart IOCTL for the following: + * Set/Get the current baud rate, + * set parity, + * set the number of Stop bits, + * set the character Length (5,6,7,8), + * enable/disable Hardware flow control. + * + * Only Polled mode is supported for now. + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- +*/ + +/** + * @defgroup IxUARTAccAPI IXP400 UART Access (IxUARTAcc) API + * + * @brief IXP400 UARTAcc Driver Public API + * + * @{ + */ + + +/* Defaults */ + +/** + * @defgroup DefaultDefines Defines for Default Values + * + * @brief Default values which can be used for UART configuration + * + * @sa ixUARTDev + */ + +/** + * @def IX_UART_DEF_OPTS + * + * @brief The default hardware options to set the UART to - + * no flow control, 8 bit word, 1 stop bit, no parity + * + * @ingroup DefaultDefines + */ +#define IX_UART_DEF_OPTS (CLOCAL | CS8) + +/** + * @def IX_UART_DEF_XMIT + * + * @brief The default UART FIFO size - must be no bigger than 64 + * + * @ingroup DefaultDefines + */ +#define IX_UART_DEF_XMIT 64 + +/** + * @def IX_UART_DEF_BAUD + * + * @brief The default UART baud rate - 9600 + * + * @ingroup DefaultDefines + */ +#define IX_UART_DEF_BAUD 9600 + +/** + * @def IX_UART_MIN_BAUD + * + * @brief The minimum UART baud rate - 9600 + * + * @ingroup DefaultDefines + */ +#define IX_UART_MIN_BAUD 9600 + +/** + * @def IX_UART_MAX_BAUD + * + * @brief The maximum UART baud rate - 926100 + * + * @ingroup DefaultDefines + */ +#define IX_UART_MAX_BAUD 926100 + +/** + * @def IX_UART_XTAL + * + * @brief The UART clock speed + * + * @ingroup DefaultDefines + */ +#define IX_UART_XTAL 14745600 + + + +/* IOCTL commands (Request codes) */ + +/** + * @defgroup IoctlCommandDefines Defines for IOCTL Commands + * + * @brief IOCTL Commands (Request codes) which can be used + * with @ref ixUARTIoctl + */ + + +/** + * @ingroup IoctlCommandDefines + * + * @def IX_BAUD_SET + * + * @brief Set the baud rate + */ +#define IX_BAUD_SET 0 + +/** + * @ingroup IoctlCommandDefines + * + * @def IX_BAUD_GET + * + * @brief Get the baud rate + */ +#define IX_BAUD_GET 1 + +/** + * @ingroup IoctlCommandDefines + * @def IX_MODE_SET + * @brief Set the UART mode of operation + */ +#define IX_MODE_SET 2 + +/** + * @ingroup IoctlCommandDefines + * + * @def IX_MODE_GET + * + * @brief Get the current UART mode of operation + */ +#define IX_MODE_GET 3 + +/** + * @ingroup IoctlCommandDefines + * + * @def IX_OPTS_SET + * + * @brief Set the UART device options + */ +#define IX_OPTS_SET 4 + +/** + * @ingroup IoctlCommandDefines + * + * @def IX_OPTS_GET + * + * @brief Get the UART device options + */ +#define IX_OPTS_GET 5 + +/** + * @ingroup IoctlCommandDefines + * + * @def IX_STATS_GET + * + * @brief Get the UART statistics + */ +#define IX_STATS_GET 6 + + +/* POSIX style ioctl arguments */ + +/** + * @defgroup IoctlArgDefines Defines for IOCTL Arguments + * + * @brief POSIX style IOCTL arguments which can be used + * with @ref ixUARTIoctl + * + * @sa ixUARTMode + */ + + +/** + * @ingroup IoctlArgDefines + * + * @def CLOCAL + * + * @brief Software flow control + */ +#ifdef CLOCAL +#undef CLOCAL +#endif +#define CLOCAL 0x1 + +/** + * @ingroup IoctlArgDefines + * + * @def CREAD + * + * @brief Enable interrupt receiver + */ +#ifdef CREAD +#undef CREAD +#endif +#define CREAD 0x2 + +/** + * @ingroup IoctlArgDefines + * + * @def CSIZE + * + * @brief Characters size + */ +#ifdef CSIZE +#undef CSIZE +#endif +#define CSIZE 0xc + +/** + * @ingroup IoctlArgDefines + * + * @def CS5 + * + * @brief 5 bits + */ +#ifdef CS5 +#undef CS5 +#endif +#define CS5 0x0 + +/** + * @ingroup IoctlArgDefines + * + * @def CS6 + * + * @brief 6 bits + */ +#ifdef CS6 +#undef CS6 +#endif +#define CS6 0x4 + +/** + * @ingroup IoctlArgDefines + * + * @def CS7 + * + * @brief 7 bits + */ +#ifdef CS7 +#undef CS7 +#endif +#define CS7 0x8 + +/** + * @ingroup IoctlArgDefines + * + * @def CS8 + * + * @brief 8 bits + */ +#ifdef CS8 +#undef CS8 +#endif +#define CS8 0xc + +/** + * @ingroup IoctlArgDefines + * + * @def STOPB + * + * @brief Send two stop bits (else one) + */ +#define STOPB 0x20 + +/** + * @ingroup IoctlArgDefines + * + * @def PARENB + * + * @brief Parity detection enabled (else disabled) + */ +#ifdef PARENB +#undef PARENB +#endif +#define PARENB 0x40 + +/** + * @ingroup IoctlArgDefines + * + * @def PARODD + * + * @brief Odd parity (else even) + */ +#ifdef PARODD +#undef PARODD +#endif +#define PARODD 0x80 + +/** + * @enum ixUARTMode + * @brief The mode to set to UART to. + */ +typedef enum +{ + INTERRUPT=0, /**< Interrupt mode */ + POLLED, /**< Polled mode */ + LOOPBACK /**< Loopback mode */ +} ixUARTMode; + +/** + * @struct ixUARTStats + * @brief Statistics for the UART. + */ +typedef struct +{ + UINT32 rxCount; + UINT32 txCount; + UINT32 overrunErr; + UINT32 parityErr; + UINT32 framingErr; + UINT32 breakErr; +} ixUARTStats; + +/** + * @struct ixUARTDev + * @brief Device descriptor for the UART. + */ +typedef struct +{ + UINT8 *addr; /**< device base address */ + ixUARTMode mode; /**< interrupt, polled or loopback */ + int baudRate; /**< baud rate */ + int freq; /**< UART clock frequency */ + int options; /**< hardware options */ + int fifoSize; /**< FIFO xmit size */ + + ixUARTStats stats; /**< device statistics */ +} ixUARTDev; + +/** + * @ingroup IxUARTAccAPI + * + * @fn IX_STATUS ixUARTInit(ixUARTDev* pUART) + * + * @param pUART @ref ixUARTDev [in] - pointer to UART structure describing our device. + * + * @brief Initialise the UART. This puts the chip in a quiescent state. + * + * @pre The base address for the UART must contain a valid value. + * Also the baud rate and hardware options must contain sensible values + * otherwise the defaults will be used as defined in ixUART.h + * + * @post UART is initialized and ready to send and receive data. + * + * @note This function should only be called once per device. + * + * @retval IX_SUCCESS - UART device successfully initialised. + * @retval IX_FAIL - Critical error, device not initialised. + ***************************************************************************/ +PUBLIC IX_STATUS ixUARTInit(ixUARTDev* pUART); + +/** + * @ingroup IxUARTAccAPI + * + * @fn IX_STATUS ixUARTPollOutput(ixUARTDev* pUART, int outChar) + * + * @param pUART @ref ixUARTDev [out] - pointer to UART structure describing our device. + * @param outChar int [out] - character to transmit. + * + * @brief Transmit a character in polled mode. + * + * @pre UART device must be initialised. + * + * @retval IX_SUCCESS - character was successfully transmitted. + * @retval IX_FAIL - output buffer is full (try again). + ***************************************************************************/ +PUBLIC IX_STATUS ixUARTPollOutput(ixUARTDev* pUART, int outChar); + +/** + * @ingroup IxUARTAccAPI + * + * @fn IX_STATUS ixUARTPollInput(ixUARTDev* pUART, char *inChar) + * + * @param pUART @ref ixUARTDev [in] - pointer to UART structure describing our device. + * @param *inChar char [in] - character read from the device. + * + * @brief Receive a character in polled mode. + * + * @pre UART device must be initialised. + * + * @retval IX_SUCCESS - character was successfully read. + * @retval IX_FAIL - input buffer empty (try again). + ***************************************************************************/ +PUBLIC IX_STATUS ixUARTPollInput(ixUARTDev* pUART, char *inChar); + +/** + * @ingroup IxUARTAccAPI + * + * @fn IX_STATUS ixUARTIoctl(ixUARTDev* pUART, int cmd, void* arg) + * + * @param pUART @ref ixUARTDev [in] - pointer to UART structure describing our device. + * @param cmd int [in] - an ioctl request code. + * @param arg void* [in] - optional argument used to set the device mode, + * baud rate, and hardware options. + * + * @brief Perform I/O control routines on the device. + * + * @retval IX_SUCCESS - requested feature was set/read successfully. + * @retval IX_FAIL - error setting/reading the requested feature. + * + * @sa IoctlCommandDefines + * @sa IoctlArgDefines + ***************************************************************************/ +PUBLIC IX_STATUS ixUARTIoctl(ixUARTDev* pUART, int cmd, void* arg); + +/** + * @} defgroup IxUARTAcc + */ diff --git a/arch/arm/cpu/ixp/npe/include/IxVersionId.h b/arch/arm/cpu/ixp/npe/include/IxVersionId.h new file mode 100644 index 0000000000..27796ede84 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/IxVersionId.h @@ -0,0 +1,155 @@ +/** + * @file IxVersionId.h + * + * @date 22-Aug-2002 + * + * @brief This file contains the IXP400 Software version identifier + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +/** + * @defgroup IxVersionId IXP400 Version ID (IxVersionId) + * + * @brief Version Identifiers + * + * @{ + */ + +#ifndef IXVERSIONID_H +#define IXVERSIONID_H + +/** + * @brief Version Identifier String + * + * This string will be updated with each customer release of the IXP400 + * Software. + */ +#define IX_VERSION_ID "2_0" + +/** + * This string will be updated with each customer release of the IXP400 + * ADSL driver package. + */ +#define IX_VERSION_ADSL_ID "1_12" + + +/** + * This string will be updated with each customer release of the IXP400 + * USB Client driver package. + */ +#define IX_VERSION_USBRNDIS_ID "1_9" + +/** + * This string will be updated with each customer release of the IXP400 + * I2C Linux driver package. + */ +#define IX_VERSION_I2C_LINUX_ID "1_0" + +/** + * @brief Linux Ethernet Driver Patch Version Identifier String + * + * This string will be updated with each release of Linux Ethernet Patch + */ +#define LINUX_ETHERNET_DRIVER_PATCH_ID "1_4" + +/** + * @brief Linux Integration Patch Version Identifier String + * + * This String will be updated with each release of Linux Integration Patch + */ +#define LINUX_INTEGRATION_PATCH_ID "1_3" + +/** + * @brief Linux Ethernet Readme version Identifier String + * + * This string will be updated with each release of Linux Ethernet Readme + */ +#define LINUX_ETHERNET_README_ID "1_3" + +/** + * @brief Linux Integration Readme version Identifier String + * + * This string will be updated with each release of Linux Integration Readme + */ + +#define LINUX_INTEGRATION_README_ID "1_3" + +/** + * @brief Linux I2C driver Readme version Identifier String + * + * This string will be updated with each release of Linux I2C Driver Readme + */ +#define LINUX_I2C_DRIVER_README_ID "1_0" + +/** + * @brief ixp425_eth_update_nf_bridge.patch version Identifier String + * + * This string will be updated with each release of ixp425_eth_update_nf_bridge. +patch + * + */ + +#define IXP425_ETH_UPDATE_NF_BRIDGE_ID "1_3" + +/** + * @brief Internal Release Identifier String + * + * This string will be updated with each internal release (SQA drop) + * of the IXP400 Software. + */ +#define IX_VERSION_INTERNAL_ID "SQA3_5" + +/** + * @brief Compatible Tornado Version Identifier + */ +#define IX_VERSION_COMPATIBLE_TORNADO "Tornado2_2_1-PNE2_0" + +/** + * @brief Compatible Linux Version Identifier + */ +#define IX_VERSION_COMPATIBLE_LINUX "MVL3_1" + + +#endif /* IXVERSIONID_H */ + +/** + * @} addtogroup IxVersionId + */ diff --git a/arch/arm/cpu/ixp/npe/include/ix_error.h b/arch/arm/cpu/ixp/npe/include/ix_error.h new file mode 100644 index 0000000000..d32ace20b5 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/ix_error.h @@ -0,0 +1,66 @@ +/** + * ============================================================================ + * = COPYRIGHT + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + * = PRODUCT + * Intel(r) IXP425 Software Release + * + * = FILENAME + * ix_error.h (Replaced by OSAL) + * + * = DESCRIPTION + * This file will describe the basic error type and support functions that + * will be used by the IXA SDK Framework API. + * + * = AUTHOR + * Intel Corporation + * + * = CHANGE HISTORY + * 4/22/2002 4:19:03 PM - creation time + * ============================================================================ + */ + +#if !defined(__IX_ERROR_H__) +#define __IX_ERROR_H__ + +#include "IxOsalBackward.h" + +#endif /* end !defined(__IX_ERROR_H__) */ + diff --git a/arch/arm/cpu/ixp/npe/include/ix_macros.h b/arch/arm/cpu/ixp/npe/include/ix_macros.h new file mode 100644 index 0000000000..53f5942f97 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/ix_macros.h @@ -0,0 +1,266 @@ +/** + * ============================================================================ + * = COPYRIGHT + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + * = PRODUCT + * Intel(r) IXP425 Software Release + * + * = FILENAME + * ix_macros.h + * + * = DESCRIPTION + * This file will define the basic preprocessor macros that are going to be used + * the IXA SDK Framework API. + * + * = AUTHOR + * Intel Corporation + * + * = CHANGE HISTORY + * 4/22/2002 4:41:05 PM - creation time + * ============================================================================ + */ + +#if !defined(__IX_MACROS_H__) +#define __IX_MACROS_H__ + + +#if defined(__cplusplus) +extern "C" +{ +#endif /* end defined(__cplusplus) */ + + +/** + * MACRO NAME: IX_BIT_FIELD_MASK16 + * + * DESCRIPTION: Builds the mask required to extract the bit field from a 16 bit unsigned integer value. + * + * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant + * bit of the bit field. + * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant + * bit of the bit field. + * + * @Return: Returns a 16 bit mask that will extract the bit field from a 16 bit unsigned integer value. + */ +#define IX_BIT_FIELD_MASK16( \ + arg_FieldLSBBit, \ + arg_FieldMSBBit \ + ) \ + ((ix_bit_mask16)((((ix_uint16)1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - \ + (ix_uint16)1) << arg_FieldLSBBit)) + + + +/** + * MACRO NAME: IX_GET_BIT_FIELD16 + * + * DESCRIPTION: Extracts a bit field from 16 bit unsigned integer. The returned value is normalized in + * in the sense that will be right aligned. + * + * @Param: - IN arg_PackedData16 a 16 bit unsigned integer that contains the bit field of interest. + * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant + * bit of the bit field. + * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant + * bit of the bit field. + * + * @Return: Returns the value of the bit field. The value can be from 0 to (1 << (arg_FieldMSBBit + 1 - + * arg_FieldLSBBit)) - 1. + */ +#define IX_GET_BIT_FIELD16( \ + arg_PackedData16, \ + arg_FieldLSBBit, \ + arg_FieldMSBBit \ + ) \ + (((ix_uint16)(arg_PackedData16) & IX_BIT_FIELD_MASK16(arg_FieldLSBBit, arg_FieldMSBBit)) >> \ + arg_FieldLSBBit) + + +/** + * MACRO NAME: IX_MAKE_BIT_FIELD16 + * + * DESCRIPTION: This macro will create a temporary 16 bit value with the bit field + * desired set to the desired value. + * + * @Param: - IN arg_BitFieldValue is the new value of the bit field. The value can be from 0 to + * (1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - 1. + * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant + * bit of the bit field. + * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant + * bit of the bit field. + * + * @Return: Returns a temporary ix_uint16 value that has the bit field set to the appropriate value. + */ +#define IX_MAKE_BIT_FIELD16( \ + arg_BitFieldValue, \ + arg_FieldLSBBit, \ + arg_FieldMSBBit \ + ) \ + (((ix_uint16)(arg_BitFieldValue) << arg_FieldLSBBit) & \ + IX_BIT_FIELD_MASK16(arg_FieldLSBBit, arg_FieldMSBBit)) + +/** + * MACRO NAME: IX_SET_BIT_FIELD16 + * + * DESCRIPTION: Sets a new value for a bit field from a 16 bit unsigned integer. + * + * @Param: - IN arg_PackedData16 a 16 bit unsigned integer that contains the bit field of interest. + * @Param: - IN arg_BitFieldValue is the new vale of the bit field. The value can be from 0 to + * (1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - 1. + * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant + * bit of the bit field. + * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant + * bit of the bit field. + * + * @Return: Returns the updated value of arg_PackedData16. + */ +#define IX_SET_BIT_FIELD16( \ + arg_PackedData16, \ + arg_BitFieldValue, \ + arg_FieldLSBBit, \ + arg_FieldMSBBit \ + ) \ + (arg_PackedData16 = (((ix_uint16)(arg_PackedData16) & \ + ~(IX_BIT_FIELD_MASK16(arg_FieldLSBBit, arg_FieldMSBBit))) | \ + IX_MAKE_BIT_FIELD16(arg_BitFieldValue, arg_FieldLSBBit, arg_FieldMSBBit))) + + +/** + * MACRO NAME: IX_BIT_FIELD_MASK32 + * + * DESCRIPTION: Builds the mask required to extract the bit field from a 32 bit unsigned integer value. + * + * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant + * bit of the bit field. + * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant + * bit of the bit field. + * + * @Return: Returns a 32 bit mask that will extract the bit field from a 32 bit unsigned integer value. + */ +#define IX_BIT_FIELD_MASK32( \ + arg_FieldLSBBit, \ + arg_FieldMSBBit \ + ) \ + ((ix_bit_mask32)((((ix_uint32)1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - \ + (ix_uint32)1) << arg_FieldLSBBit)) + + + +/** + * MACRO NAME: IX_GET_BIT_FIELD32 + * + * DESCRIPTION: Extracts a bit field from 32 bit unsigned integer. The returned value is normalized in + * in the sense that will be right aligned. + * + * @Param: - IN arg_PackedData32 a 32 bit unsigned integer that contains the bit field of interest. + * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant + * bit of the bit field. + * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant + * bit of the bit field. + * + * @Return: Returns the value of the bit field. The value can be from 0 to (1 << (arg_FieldMSBBit + 1 - + * arg_FieldLSBBit)) - 1. + */ +#define IX_GET_BIT_FIELD32( \ + arg_PackedData32, \ + arg_FieldLSBBit, \ + arg_FieldMSBBit \ + ) \ + (((ix_uint32)(arg_PackedData32) & IX_BIT_FIELD_MASK32(arg_FieldLSBBit, arg_FieldMSBBit)) >> \ + arg_FieldLSBBit) + + + + +/** + * MACRO NAME: IX_MAKE_BIT_FIELD32 + * + * DESCRIPTION: This macro will create a temporary 32 bit value with the bit field + * desired set to the desired value. + * + * @Param: - IN arg_BitFieldValue is the new value of the bit field. The value can be from 0 to + * (1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - 1. + * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant + * bit of the bit field. + * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant + * bit of the bit field. + * + * @Return: Returns a temporary ix_uint32 value that has the bit field set to the appropriate value. + */ +#define IX_MAKE_BIT_FIELD32( \ + arg_BitFieldValue, \ + arg_FieldLSBBit, \ + arg_FieldMSBBit \ + ) \ + (((ix_uint32)(arg_BitFieldValue) << arg_FieldLSBBit) & \ + IX_BIT_FIELD_MASK32(arg_FieldLSBBit, arg_FieldMSBBit)) + + +/** + * MACRO NAME: IX_SET_BIT_FIELD32 + * + * DESCRIPTION: Sets a new value for a bit field from a 32 bit unsigned integer. + * + * @Param: - IN arg_PackedData32 a 32 bit unsigned integer that contains the bit field of interest. + * @Param: - IN arg_BitFieldValue is the new value of the bit field. The value can be from 0 to + * (1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - 1. + * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant + * bit of the bit field. + * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant + * bit of the bit field. + * + * @Return: Returns the updated value of arg_PackedData32. + */ +#define IX_SET_BIT_FIELD32( \ + arg_PackedData32, \ + arg_BitFieldValue, \ + arg_FieldLSBBit, \ + arg_FieldMSBBit \ + ) \ + (arg_PackedData32 = (((ix_uint32)(arg_PackedData32) & \ + ~(IX_BIT_FIELD_MASK32(arg_FieldLSBBit, arg_FieldMSBBit))) | \ + IX_MAKE_BIT_FIELD32(arg_BitFieldValue, arg_FieldLSBBit, arg_FieldMSBBit))) + + + +#if defined(__cplusplus) +} +#endif /* end defined(__cplusplus) */ + +#endif /* end !defined(__IX_MACROS_H__) */ diff --git a/arch/arm/cpu/ixp/npe/include/ix_os_type.h b/arch/arm/cpu/ixp/npe/include/ix_os_type.h new file mode 100644 index 0000000000..8575096722 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/ix_os_type.h @@ -0,0 +1,65 @@ +/** + * ============================================================================ + * = COPYRIGHT + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + * = PRODUCT + * Intel(r) IXP425 Software Release + * + * = FILENAME + * ix_os_type.h (Replaced by OSAL) + * + * = DESCRIPTION + * This file provides protable symbol definitions for the current OS type. + * + * = AUTHOR + * Intel Corporation + * + * = CHANGE HISTORY + * 4/22/2002 4:43:30 PM - creation time + * ============================================================================ + */ + +#if !defined(__IX_OS_TYPE_H__) +#define __IX_OS_TYPE_H__ + +#include "IxOsalBackward.h" + +#endif /* end !defined(__IX_OS_TYPE_H__) */ + diff --git a/arch/arm/cpu/ixp/npe/include/ix_ossl.h b/arch/arm/cpu/ixp/npe/include/ix_ossl.h new file mode 100644 index 0000000000..b59f7d0873 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/ix_ossl.h @@ -0,0 +1,160 @@ +/** + * ============================================================================ + * = COPYRIGHT + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + * = PRODUCT + * Intel(r) IXP425 Software Release + * + * = LIBRARY + * OSSL - Operating System Services Library + * + * = MODULE + * OSSL Abstraction layer header file + * + * = FILENAME + * ix_ossl.h (Replaced by OSAL) + * + * = DESCRIPTION + * This file contains the prototypes of OS-independent wrapper + * functions which allow the programmer not to be tied to a specific + * operating system. The OSSL functions can be divided into three classes: + * + * 1) synchronization-related wrapper functions around thread system calls + * 2) thread-related wrapper functions around thread calls + * 3) transactor/workbench osapi calls -- defined in osApi.h + * + * Both 1 and 2 classes of functions provide Thread Management, Thread + * Synchronization, Mutual Exclusion and Timer primitives. Namely, + * creation and deletion functions as well as the standard "wait" and + * "exit". Additionally, a couple of utility functions which enable to + * pause the execution of a thread are also provided. + * + * The 3rd class provides a slew of other OSAPI functions to handle + * Transactor/WorkBench OS calls. + * + * + * OSSL Thread APIs: + * The OSSL thread functions that allow for thread creation, + * get thread id, thread deletion and set thread priroity. + * + * ix_ossl_thread_create + * ix_ossl_thread_get_id + * ix_ossl_thread_exit + * ix_ossl_thread_kill + * ix_ossl_thread_set_priority + * ix_ossl_thread__delay + * + * OSSL Semaphore APIs: + * The OSSL semaphore functions that allow for initialization, + * posting, waiting and deletion of semaphores. + * + * ix_ossl_sem_init + * ix_ossl_sem_fini + * ix_ossl_sem_take + * ix_ossl_sem_give + * ix_ossl_sem_flush + * + * OSSL Mutex APIs: + * The OSSL wrapper functions that allow for initialization, + * posting, waiting and deletion of mutexes. + * + * ix_ossl_mutex_init + * ix_ossl_mutex_fini + * ix_ossl_mutex_lock + * ix_ossl_mutex_unlock + * + * OSSL Timer APIs: + * The timer APIs provide sleep and get time functions. + * + * ix_ossl_sleep + * ix_ossl_sleep_tick + * ix_ossl_time_get + * + * OSAPIs for Transactor/WorkBench: + * These OSAPI functions are used for transator OS calls. + * They are defined in osApi.h. + * + * Sem_Init + * Sem_Destroy + * Sem_Wait + * Sem_Wait + * Thread_Create + * Thread_Cancel + * Thread_SetPriority + * delayMs + * delayTick + * + * + * + ********************************************************************** + * + * + * = AUTHOR + * Intel Corporation + * + * = ACKNOWLEDGEMENTS + * + * + * = CREATION TIME + * 1/8/2002 1:53:42 PM + * + * = CHANGE HISTORY + * 02/22/2002 : Renamed osapi.h os_api.h + * Moved OS header file includes from OSSL.h to os_api.h + * Moved OS specific datatypes to os_api.h + * Modified data types, macros and functions as per + * 'C' coding guidelines. + * + * + * ============================================================================ + */ + +#ifndef _IX_OSSL_H +#ifndef __doxygen_hide +#define _IX_OSSL_H +#endif /* __doxygen_hide */ + +#include "IxOsalBackward.h" + +#endif /* _IX_OSSL_H */ + +/** + * @} defgroup IxOSSL + */ diff --git a/arch/arm/cpu/ixp/npe/include/ix_symbols.h b/arch/arm/cpu/ixp/npe/include/ix_symbols.h new file mode 100644 index 0000000000..f7bb029d66 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/ix_symbols.h @@ -0,0 +1,106 @@ +/** + * ============================================================================ + * = COPYRIGHT + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + * = PRODUCT + * Intel(r) IXP425 Software Release + * + * = FILENAME + * ix_symbols.h + * + * = DESCRIPTION + * This file declares all the global preprocessor symbols required by + * the IXA SDK Framework API. + * + * = AUTHOR + * Intel Corporation + * + * = CHANGE HISTORY + * 4/23/2002 10:41:13 AM - creation time + * ============================================================================ + */ + +#if !defined(__IX_SYMBOLS_H__) +#define __IX_SYMBOLS_H__ + + +#if defined(__cplusplus) +extern "C" +{ +#endif /* end defined(__cplusplus) */ + +/** + * The IX_EXPORT_FUNCTION symbol will be used for compilation on different platforms. + * We are planning to provide a simulation version of the library that should work + * with the Transactor rather than the hardware. This implementation will be done on + * WIN32 in the form of a DLL that will need to export functions and symbols. + */ +#if (_IX_OS_TYPE_ == _IX_OS_WIN32_) +# if defined(_IX_LIB_INTERFACE_IMPLEMENTATION_) +# define IX_EXPORT_FUNCTION __declspec( dllexport ) +# elif defined(_IX_LIB_INTERFACE_IMPORT_DLL_) +# define IX_EXPORT_FUNCTION __declspec( dllimport ) +# else +# define IX_EXPORT_FUNCTION extern +# endif +#elif (_IX_OS_TYPE_ == _IX_OS_WINCE_) +# define IX_EXPORT_FUNCTION __declspec(dllexport) +#else +# define IX_EXPORT_FUNCTION extern +#endif + + +/** + * This symbols should be defined when we want to build for a multithreaded environment + */ +#define _IX_MULTI_THREADED_ 1 + + +/** + * This symbol should be defined in the case we to buils for a multithreaded environment + * but we want that our modules to work as if they are used in a single threaded environment. + */ +/* #define _IX_RM_EXPLICIT_SINGLE_THREADED_ 1 */ + +#if defined(__cplusplus) +} +#endif /* end defined(__cplusplus) */ + +#endif /* end !defined(__IX_SYMBOLS_H__) */ diff --git a/arch/arm/cpu/ixp/npe/include/ix_types.h b/arch/arm/cpu/ixp/npe/include/ix_types.h new file mode 100644 index 0000000000..fc7b1e993a --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/ix_types.h @@ -0,0 +1,208 @@ +/** + * ============================================================================ + * = COPYRIGHT + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + * = PRODUCT + * Intel(r) IXP425 Software Release + * + * = FILENAME + * ix_types.h + * + * = DESCRIPTION + * This file will define generic types that will guarantee the protability + * between different architectures and compilers. It should be used the entire + * IXA SDK Framework API. + * + * = AUTHOR + * Intel Corporation + * + * = CHANGE HISTORY + * 4/22/2002 4:44:17 PM - creation time + * ============================================================================ + */ + +#if !defined(__IX_TYPES_H__) +#define __IX_TYPES_H__ + + +#if defined(__cplusplus) +extern "C" +{ +#endif /* end defined(__cplusplus) */ + + +/** + * Define generic integral data types that will guarantee the size. + */ + +/** + * TYPENAME: ix_int8 + * + * DESCRIPTION: This type defines an 8 bit signed integer value. + * + */ +typedef signed char ix_int8; + + +/** + * TYPENAME: ix_uint8 + * + * DESCRIPTION: This type defines an 8 bit unsigned integer value. + * + */ +typedef unsigned char ix_uint8; + + +/** + * TYPENAME: ix_int16 + * + * DESCRIPTION: This type defines an 16 bit signed integer value. + * + */ +typedef signed short int ix_int16; + + +/** + * TYPENAME: ix_uint16 + * + * DESCRIPTION: This type defines an 16 bit unsigned integer value. + * + */ +typedef unsigned short int ix_uint16; + + +/** + * TYPENAME: ix_int32 + * + * DESCRIPTION: This type defines an 32 bit signed integer value. + * + */ +typedef signed int ix_int32; + + +/** + * TYPENAME: ix_uint32 + * + * DESCRIPTION: This type defines an 32 bit unsigned integer value. + * + */ +#ifndef __wince +typedef unsigned int ix_uint32; +#else +typedef unsigned long ix_uint32; +#endif + +/** + * TYPENAME: ix_int64 + * + * DESCRIPTION: This type defines an 64 bit signed integer value. + * + */ +#ifndef __wince +__extension__ typedef signed long long int ix_int64; +#endif + +/** + * TYPENAME: ix_uint64 + * + * DESCRIPTION: This type defines an 64 bit unsigned integer value. + * + */ +#ifndef __wince +__extension__ typedef unsigned long long int ix_uint64; +#endif + + +/** + * TYPENAME: ix_bit_mask8 + * + * DESCRIPTION: This is a generic type for a 8 bit mask. + */ +typedef ix_uint8 ix_bit_mask8; + + +/** + * TYPENAME: ix_bit_mask16 + * + * DESCRIPTION: This is a generic type for a 16 bit mask. + */ +typedef ix_uint16 ix_bit_mask16; + + +/** + * TYPENAME: ix_bit_mask32 + * + * DESCRIPTION: This is a generic type for a 32 bit mask. + */ +typedef ix_uint32 ix_bit_mask32; + + +/** + * TYPENAME: ix_bit_mask64 + * + * DESCRIPTION: This is a generic type for a 64 bit mask. + */ +#ifndef __wince +typedef ix_uint64 ix_bit_mask64; +#endif + + +/** + * TYPENAME: ix_handle + * + * DESCRIPTION: This type defines a generic handle. + * + */ +typedef ix_uint32 ix_handle; + + + +/** + * DESCRIPTION: This symbol defines a NULL handle + * + */ +#define IX_NULL_HANDLE ((ix_handle)0) + + +#if defined(__cplusplus) +} +#endif /* end defined(__cplusplus) */ + +#endif /* end !defined(__IX_TYPES_H__) */ diff --git a/arch/arm/cpu/ixp/npe/include/npe.h b/arch/arm/cpu/ixp/npe/include/npe.h new file mode 100644 index 0000000000..3d6f727476 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/npe.h @@ -0,0 +1,90 @@ +/* + * (C) Copyright 2005 + * Stefan Roese, DENX Software Engineering, sr@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef NPE_H +#define NPE_H + +/* + * defines... + */ +#define CONFIG_SYS_NPE_NUMS 1 +#ifdef CONFIG_HAS_ETH1 +#undef CONFIG_SYS_NPE_NUMS +#define CONFIG_SYS_NPE_NUMS 2 +#endif + +#define NPE_NUM_PORTS 3 +#define ACTIVE_PORTS 1 + +#define NPE_PKT_SIZE 1600 + +#define CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS 64 +#define CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS 2 + +#define NPE_MBUF_POOL_SIZE \ + ((CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS + \ + CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS) * \ + sizeof(IX_OSAL_MBUF) * ACTIVE_PORTS) + +#define NPE_PKT_POOL_SIZE \ + ((CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS + \ + CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS) * \ + NPE_PKT_SIZE * ACTIVE_PORTS) + +#define NPE_MEM_POOL_SIZE (NPE_MBUF_POOL_SIZE + NPE_PKT_POOL_SIZE) + +#define PHY_AUTONEGOTIATE_TIMEOUT 4000 /* 4000 ms autonegotiate timeout */ + +/* + * structs... + */ +struct npe { + u8 active; /* NPE active */ + u8 eth_id; /* IX_ETH_PORT_1 or IX_ETH_PORT_2 */ + u8 phy_no; /* which PHY (0 - 31) */ + u8 mac_address[6]; + + IX_OSAL_MBUF *rxQHead; + IX_OSAL_MBUF *txQHead; + + u8 *tx_pkts; + u8 *rx_pkts; + IX_OSAL_MBUF *rx_mbufs; + IX_OSAL_MBUF *tx_mbufs; + + int print_speed; + + int rx_read; + int rx_write; + int rx_len[PKTBUFSRX]; +}; + +/* + * prototypes... + */ +extern int npe_miiphy_read (char *devname, unsigned char addr, + unsigned char reg, unsigned short *value); +extern int npe_miiphy_write (char *devname, unsigned char addr, + unsigned char reg, unsigned short value); + +#endif /* ifndef NPE_H */ diff --git a/arch/arm/cpu/ixp/npe/include/os_datatypes.h b/arch/arm/cpu/ixp/npe/include/os_datatypes.h new file mode 100644 index 0000000000..4387b2a052 --- /dev/null +++ b/arch/arm/cpu/ixp/npe/include/os_datatypes.h @@ -0,0 +1,82 @@ +/** + * ============================================================================ + * = COPYRIGHT + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + * = PRODUCT + * Intel(r) IXP425 Software Release + * + * = LIBRARY + * OSSL - Operating System Services Library + * + * = MODULE + * OS Specific Data Types header file + * + * = FILENAME + * OSSL.h (Replaced by OSAL) + * + * = DESCRIPTION + * This file contains definitions and encapsulations for OS specific data types. These + * encapsulated data types are used by OSSL header files and OS API functions. + * + * + ********************************************************************** + * + * + * = AUTHOR + * Intel Corporation + * + * = AKNOWLEDGEMENTS + * + * + * = CREATION TIME + * 1/8/2002 1:53:42 PM + * + * = CHANGE HISTORY + + * ============================================================================ + */ + +#ifndef _OS_DATATYPES_H +#define _OS_DATATYPES_H + +#include "IxOsalBackward.h" + +#endif /* _OS_DATATYPES_H */ + diff --git a/arch/arm/cpu/ixp/npe/miiphy.c b/arch/arm/cpu/ixp/npe/miiphy.c new file mode 100644 index 0000000000..b208c51eae --- /dev/null +++ b/arch/arm/cpu/ixp/npe/miiphy.c @@ -0,0 +1,120 @@ +/*-----------------------------------------------------------------------------+ + | This source code is dual-licensed. You may use it under the terms of the + | GNU General Public License version 2, or under the license below. + | + | This source code has been made available to you by IBM on an AS-IS + | basis. Anyone receiving this source is licensed under IBM + | copyrights to use it in any way he or she deems fit, including + | copying it, modifying it, compiling it, and redistributing it either + | with or without modifications. No license under IBM patents or + | patent applications is to be implied by the copyright license. + | + | Any user of this software should understand that IBM cannot provide + | technical support for this software and will not be responsible for + | any consequences resulting from the use of this software. + | + | Any person who transfers this source code or any derivative work + | must include the IBM copyright notice, this paragraph, and the + | preceding two paragraphs in the transferred software. + | + | COPYRIGHT I B M CORPORATION 1995 + | LICENSED MATERIAL - PROGRAM PROPERTY OF I B M + +-----------------------------------------------------------------------------*/ +/*-----------------------------------------------------------------------------+ + | + | File Name: miiphy.c + | + | Function: This module has utilities for accessing the MII PHY through + | the EMAC3 macro. + | + | Author: Mark Wisner + | + | Change Activity- + | + | Date Description of Change BY + | --------- --------------------- --- + | 05-May-99 Created MKW + | 01-Jul-99 Changed clock setting of sta_reg from 66MHz to 50MHz to + | better match OPB speed. Also modified delay times. JWB + | 29-Jul-99 Added Full duplex support MKW + | 24-Aug-99 Removed printf from dp83843_duplex() JWB + | 19-Jul-00 Ported to esd cpci405 sr + | 23-Dec-03 Ported from miiphy.c to 440GX Travis Sawyer TBS + | + | + +-----------------------------------------------------------------------------*/ + +#include +#include +#include "IxOsal.h" +#include "IxEthAcc.h" +#include "IxEthAcc_p.h" +#include "IxEthAccMac_p.h" +#include "IxEthAccMii_p.h" + +/***********************************************************/ +/* Dump out to the screen PHY regs */ +/***********************************************************/ + +void miiphy_dump (char *devname, unsigned char addr) +{ + unsigned long i; + unsigned short data; + + + for (i = 0; i < 0x1A; i++) { + if (miiphy_read (devname, addr, i, &data)) { + printf ("read error for reg %lx\n", i); + return; + } + printf ("Phy reg %lx ==> %4x\n", i, data); + + /* jump to the next set of regs */ + if (i == 0x07) + i = 0x0f; + + } /* end for loop */ +} /* end dump */ + + +/***********************************************************/ +/* (Re)start autonegotiation */ +/***********************************************************/ +int phy_setup_aneg (char *devname, unsigned char addr) +{ + unsigned short ctl, adv; + + /* Setup standard advertise */ + miiphy_read (devname, addr, PHY_ANAR, &adv); + adv |= (PHY_ANLPAR_ACK | PHY_ANLPAR_RF | PHY_ANLPAR_T4 | + PHY_ANLPAR_TXFD | PHY_ANLPAR_TX | PHY_ANLPAR_10FD | + PHY_ANLPAR_10); + miiphy_write (devname, addr, PHY_ANAR, adv); + + /* Start/Restart aneg */ + miiphy_read (devname, addr, PHY_BMCR, &ctl); + ctl |= (PHY_BMCR_AUTON | PHY_BMCR_RST_NEG); + miiphy_write (devname, addr, PHY_BMCR, ctl); + + return 0; +} + + +int npe_miiphy_read (char *devname, unsigned char addr, + unsigned char reg, unsigned short *value) +{ + u16 val; + + ixEthAccMiiReadRtn(addr, reg, &val); + *value = val; + + return 0; +} /* phy_read */ + + +int npe_miiphy_write (char *devname, unsigned char addr, + unsigned char reg, unsigned short value) +{ + ixEthAccMiiWriteRtn(addr, reg, value); + return 0; +} /* phy_write */ diff --git a/arch/arm/cpu/ixp/npe/npe.c b/arch/arm/cpu/ixp/npe/npe.c new file mode 100644 index 0000000000..2e6868960a --- /dev/null +++ b/arch/arm/cpu/ixp/npe/npe.c @@ -0,0 +1,676 @@ +/* + * (C) Copyright 2005-2006 + * Stefan Roese, DENX Software Engineering, sr@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#if 0 +#define DEBUG /* define for debug output */ +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static IxQMgrDispatcherFuncPtr qDispatcherFunc = NULL; +static int npe_exists[NPE_NUM_PORTS]; +static int npe_used[NPE_NUM_PORTS]; + +/* A little extra so we can align to cacheline. */ +static u8 npe_alloc_pool[NPE_MEM_POOL_SIZE + CONFIG_SYS_CACHELINE_SIZE - 1]; +static u8 *npe_alloc_end; +static u8 *npe_alloc_free; + +static void *npe_alloc(int size) +{ + static int count = 0; + void *p = NULL; + + size = (size + (CONFIG_SYS_CACHELINE_SIZE-1)) & ~(CONFIG_SYS_CACHELINE_SIZE-1); + count++; + + if ((npe_alloc_free + size) < npe_alloc_end) { + p = npe_alloc_free; + npe_alloc_free += size; + } else { + printf("npe_alloc: failed (count=%d, size=%d)!\n", count, size); + } + return p; +} + +/* Not interrupt safe! */ +static void mbuf_enqueue(IX_OSAL_MBUF **q, IX_OSAL_MBUF *new) +{ + IX_OSAL_MBUF *m = *q; + + IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(new) = NULL; + + if (m) { + while(IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m)) + m = IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m); + IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m) = new; + } else + *q = new; +} + +/* Not interrupt safe! */ +static IX_OSAL_MBUF *mbuf_dequeue(IX_OSAL_MBUF **q) +{ + IX_OSAL_MBUF *m = *q; + if (m) + *q = IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m); + return m; +} + +static void reset_tx_mbufs(struct npe* p_npe) +{ + IX_OSAL_MBUF *m; + int i; + + p_npe->txQHead = NULL; + + for (i = 0; i < CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS; i++) { + m = &p_npe->tx_mbufs[i]; + + memset(m, 0, sizeof(*m)); + + IX_OSAL_MBUF_MDATA(m) = (void *)&p_npe->tx_pkts[i * NPE_PKT_SIZE]; + IX_OSAL_MBUF_MLEN(m) = IX_OSAL_MBUF_PKT_LEN(m) = NPE_PKT_SIZE; + mbuf_enqueue(&p_npe->txQHead, m); + } +} + +static void reset_rx_mbufs(struct npe* p_npe) +{ + IX_OSAL_MBUF *m; + int i; + + p_npe->rxQHead = NULL; + + HAL_DCACHE_INVALIDATE(p_npe->rx_pkts, NPE_PKT_SIZE * + CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS); + + for (i = 0; i < CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS; i++) { + m = &p_npe->rx_mbufs[i]; + + memset(m, 0, sizeof(*m)); + + IX_OSAL_MBUF_MDATA(m) = (void *)&p_npe->rx_pkts[i * NPE_PKT_SIZE]; + IX_OSAL_MBUF_MLEN(m) = IX_OSAL_MBUF_PKT_LEN(m) = NPE_PKT_SIZE; + + if(ixEthAccPortRxFreeReplenish(p_npe->eth_id, m) != IX_SUCCESS) { + printf("ixEthAccPortRxFreeReplenish failed for port %d\n", p_npe->eth_id); + break; + } + } +} + +static void init_rx_mbufs(struct npe* p_npe) +{ + p_npe->rxQHead = NULL; + + p_npe->rx_pkts = npe_alloc(NPE_PKT_SIZE * + CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS); + if (p_npe->rx_pkts == NULL) { + printf("alloc of packets failed.\n"); + return; + } + + p_npe->rx_mbufs = (IX_OSAL_MBUF *) + npe_alloc(sizeof(IX_OSAL_MBUF) * + CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS); + if (p_npe->rx_mbufs == NULL) { + printf("alloc of mbufs failed.\n"); + return; + } + + reset_rx_mbufs(p_npe); +} + +static void init_tx_mbufs(struct npe* p_npe) +{ + p_npe->tx_pkts = npe_alloc(NPE_PKT_SIZE * + CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS); + if (p_npe->tx_pkts == NULL) { + printf("alloc of packets failed.\n"); + return; + } + + p_npe->tx_mbufs = (IX_OSAL_MBUF *) + npe_alloc(sizeof(IX_OSAL_MBUF) * + CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS); + if (p_npe->tx_mbufs == NULL) { + printf("alloc of mbufs failed.\n"); + return; + } + + reset_tx_mbufs(p_npe); +} + +/* Convert IX_ETH_PORT_n to IX_NPEMH_NPEID_NPEx */ +static int __eth_to_npe(int eth_id) +{ + switch(eth_id) { + case IX_ETH_PORT_1: + return IX_NPEMH_NPEID_NPEB; + + case IX_ETH_PORT_2: + return IX_NPEMH_NPEID_NPEC; + + case IX_ETH_PORT_3: + return IX_NPEMH_NPEID_NPEA; + } + return 0; +} + +/* Poll the CSR machinery. */ +static void npe_poll(int eth_id) +{ + if (qDispatcherFunc != NULL) { + ixNpeMhMessagesReceive(__eth_to_npe(eth_id)); + (*qDispatcherFunc)(IX_QMGR_QUELOW_GROUP); + } +} + +/* ethAcc RX callback */ +static void npe_rx_callback(u32 cbTag, IX_OSAL_MBUF *m, IxEthAccPortId portid) +{ + struct npe* p_npe = (struct npe *)cbTag; + + if (IX_OSAL_MBUF_MLEN(m) > 0) { + mbuf_enqueue(&p_npe->rxQHead, m); + + if (p_npe->rx_write == ((p_npe->rx_read-1) & (PKTBUFSRX-1))) { + debug("Rx overflow: rx_write=%d rx_read=%d\n", + p_npe->rx_write, p_npe->rx_read); + } else { + debug("Received message #%d (len=%d)\n", p_npe->rx_write, + IX_OSAL_MBUF_MLEN(m)); + memcpy((void *)NetRxPackets[p_npe->rx_write], IX_OSAL_MBUF_MDATA(m), + IX_OSAL_MBUF_MLEN(m)); + p_npe->rx_len[p_npe->rx_write] = IX_OSAL_MBUF_MLEN(m); + p_npe->rx_write++; + if (p_npe->rx_write == PKTBUFSRX) + p_npe->rx_write = 0; + +#ifdef CONFIG_PRINT_RX_FRAMES + { + u8 *ptr = IX_OSAL_MBUF_MDATA(m); + int i; + + for (i=0; i<60; i++) { + debug("%02x ", *ptr++); + } + debug("\n"); + } +#endif + } + + m = mbuf_dequeue(&p_npe->rxQHead); + } else { + debug("Received frame with length 0!!!\n"); + m = mbuf_dequeue(&p_npe->rxQHead); + } + + /* Now return mbuf to NPE */ + IX_OSAL_MBUF_MLEN(m) = IX_OSAL_MBUF_PKT_LEN(m) = NPE_PKT_SIZE; + IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(m) = NULL; + IX_OSAL_MBUF_FLAGS(m) = 0; + + if(ixEthAccPortRxFreeReplenish(p_npe->eth_id, m) != IX_SUCCESS) { + debug("npe_rx_callback: Error returning mbuf.\n"); + } +} + +/* ethAcc TX callback */ +static void npe_tx_callback(u32 cbTag, IX_OSAL_MBUF *m) +{ + struct npe* p_npe = (struct npe *)cbTag; + + debug("%s\n", __FUNCTION__); + + IX_OSAL_MBUF_MLEN(m) = IX_OSAL_MBUF_PKT_LEN(m) = NPE_PKT_SIZE; + IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(m) = NULL; + IX_OSAL_MBUF_FLAGS(m) = 0; + + mbuf_enqueue(&p_npe->txQHead, m); +} + + +static int npe_set_mac_address(struct eth_device *dev) +{ + struct npe *p_npe = (struct npe *)dev->priv; + IxEthAccMacAddr npeMac; + + debug("%s\n", __FUNCTION__); + + /* Set MAC address */ + memcpy(npeMac.macAddress, dev->enetaddr, 6); + + if (ixEthAccPortUnicastMacAddressSet(p_npe->eth_id, &npeMac) != IX_ETH_ACC_SUCCESS) { + printf("Error setting unicast address! %02x:%02x:%02x:%02x:%02x:%02x\n", + npeMac.macAddress[0], npeMac.macAddress[1], + npeMac.macAddress[2], npeMac.macAddress[3], + npeMac.macAddress[4], npeMac.macAddress[5]); + return 0; + } + + return 1; +} + +/* Boot-time CSR library initialization. */ +static int npe_csr_load(void) +{ + int i; + + if (ixQMgrInit() != IX_SUCCESS) { + debug("Error initialising queue manager!\n"); + return 0; + } + + ixQMgrDispatcherLoopGet(&qDispatcherFunc); + + if(ixNpeMhInitialize(IX_NPEMH_NPEINTERRUPTS_YES) != IX_SUCCESS) { + printf("Error initialising NPE Message handler!\n"); + return 0; + } + + if (npe_used[IX_ETH_PORT_1] && npe_exists[IX_ETH_PORT_1] && + ixNpeDlNpeInitAndStart(IX_NPEDL_NPEIMAGE_NPEB_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS) + != IX_SUCCESS) { + printf("Error downloading firmware to NPE-B!\n"); + return 0; + } + + if (npe_used[IX_ETH_PORT_2] && npe_exists[IX_ETH_PORT_2] && + ixNpeDlNpeInitAndStart(IX_NPEDL_NPEIMAGE_NPEC_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS) + != IX_SUCCESS) { + printf("Error downloading firmware to NPE-C!\n"); + return 0; + } + + /* don't need this for U-Boot */ + ixFeatureCtrlSwConfigurationWrite(IX_FEATURECTRL_ETH_LEARNING, FALSE); + + if (ixEthAccInit() != IX_ETH_ACC_SUCCESS) { + printf("Error initialising Ethernet access driver!\n"); + return 0; + } + + for (i = 0; i < IX_ETH_ACC_NUMBER_OF_PORTS; i++) { + if (!npe_used[i] || !npe_exists[i]) + continue; + if (ixEthAccPortInit(i) != IX_ETH_ACC_SUCCESS) { + printf("Error initialising Ethernet port%d!\n", i); + } + if (ixEthAccTxSchedulingDisciplineSet(i, FIFO_NO_PRIORITY) != IX_ETH_ACC_SUCCESS) { + printf("Error setting scheduling discipline for port %d.\n", i); + } + if (ixEthAccPortRxFrameAppendFCSDisable(i) != IX_ETH_ACC_SUCCESS) { + printf("Error disabling RX FCS for port %d.\n", i); + } + if (ixEthAccPortTxFrameAppendFCSEnable(i) != IX_ETH_ACC_SUCCESS) { + printf("Error enabling TX FCS for port %d.\n", i); + } + } + + return 1; +} + +static int npe_init(struct eth_device *dev, bd_t * bis) +{ + struct npe *p_npe = (struct npe *)dev->priv; + int i; + u16 reg_short; + int speed; + int duplex; + + debug("%s: 1\n", __FUNCTION__); + + miiphy_read (dev->name, p_npe->phy_no, PHY_BMSR, ®_short); + + /* + * Wait if PHY is capable of autonegotiation and autonegotiation is not complete + */ + if ((reg_short & PHY_BMSR_AUTN_ABLE) && !(reg_short & PHY_BMSR_AUTN_COMP)) { + puts ("Waiting for PHY auto negotiation to complete"); + i = 0; + while (!(reg_short & PHY_BMSR_AUTN_COMP)) { + /* + * Timeout reached ? + */ + if (i > PHY_AUTONEGOTIATE_TIMEOUT) { + puts (" TIMEOUT !\n"); + break; + } + + if ((i++ % 1000) == 0) { + putc ('.'); + miiphy_read (dev->name, p_npe->phy_no, PHY_BMSR, ®_short); + } + udelay (1000); /* 1 ms */ + } + puts (" done\n"); + udelay (500000); /* another 500 ms (results in faster booting) */ + } + + speed = miiphy_speed (dev->name, p_npe->phy_no); + duplex = miiphy_duplex (dev->name, p_npe->phy_no); + + if (p_npe->print_speed) { + p_npe->print_speed = 0; + printf ("ENET Speed is %d Mbps - %s duplex connection\n", + (int) speed, (duplex == HALF) ? "HALF" : "FULL"); + } + + npe_alloc_end = npe_alloc_pool + sizeof(npe_alloc_pool); + npe_alloc_free = (u8 *)(((unsigned)npe_alloc_pool + + CONFIG_SYS_CACHELINE_SIZE - 1) & ~(CONFIG_SYS_CACHELINE_SIZE - 1)); + + /* initialize mbuf pool */ + init_rx_mbufs(p_npe); + init_tx_mbufs(p_npe); + + if (ixEthAccPortRxCallbackRegister(p_npe->eth_id, npe_rx_callback, + (u32)p_npe) != IX_ETH_ACC_SUCCESS) { + printf("can't register RX callback!\n"); + return -1; + } + + if (ixEthAccPortTxDoneCallbackRegister(p_npe->eth_id, npe_tx_callback, + (u32)p_npe) != IX_ETH_ACC_SUCCESS) { + printf("can't register TX callback!\n"); + return -1; + } + + npe_set_mac_address(dev); + + if (ixEthAccPortEnable(p_npe->eth_id) != IX_ETH_ACC_SUCCESS) { + printf("can't enable port!\n"); + return -1; + } + + p_npe->active = 1; + + return 0; +} + +#if 0 /* test-only: probably have to deal with it when booting linux (for a clean state) */ +/* Uninitialize CSR library. */ +static void npe_csr_unload(void) +{ + ixEthAccUnload(); + ixEthDBUnload(); + ixNpeMhUnload(); + ixQMgrUnload(); +} + +/* callback which is used by ethAcc to recover RX buffers when stopping */ +static void npe_rx_stop_callback(u32 cbTag, IX_OSAL_MBUF *m, IxEthAccPortId portid) +{ + debug("%s\n", __FUNCTION__); +} + +/* callback which is used by ethAcc to recover TX buffers when stopping */ +static void npe_tx_stop_callback(u32 cbTag, IX_OSAL_MBUF *m) +{ + debug("%s\n", __FUNCTION__); +} +#endif + +static void npe_halt(struct eth_device *dev) +{ + struct npe *p_npe = (struct npe *)dev->priv; + int i; + + debug("%s\n", __FUNCTION__); + + /* Delay to give time for recovery of mbufs */ + for (i = 0; i < 100; i++) { + npe_poll(p_npe->eth_id); + udelay(100); + } + +#if 0 /* test-only: probably have to deal with it when booting linux (for a clean state) */ + if (ixEthAccPortRxCallbackRegister(p_npe->eth_id, npe_rx_stop_callback, + (u32)p_npe) != IX_ETH_ACC_SUCCESS) { + debug("Error registering rx callback!\n"); + } + + if (ixEthAccPortTxDoneCallbackRegister(p_npe->eth_id, npe_tx_stop_callback, + (u32)p_npe) != IX_ETH_ACC_SUCCESS) { + debug("Error registering tx callback!\n"); + } + + if (ixEthAccPortDisable(p_npe->eth_id) != IX_ETH_ACC_SUCCESS) { + debug("npe_stop: Error disabling NPEB!\n"); + } + + /* Delay to give time for recovery of mbufs */ + for (i = 0; i < 100; i++) { + npe_poll(p_npe->eth_id); + udelay(10000); + } + + /* + * For U-Boot only, we are probably launching Linux or other OS that + * needs a clean slate for its NPE library. + */ +#if 0 /* test-only */ + for (i = 0; i < IX_ETH_ACC_NUMBER_OF_PORTS; i++) { + if (npe_used[i] && npe_exists[i]) + if (ixNpeDlNpeStopAndReset(__eth_to_npe(i)) != IX_SUCCESS) + printf("Failed to stop and reset NPE B.\n"); + } +#endif + +#endif + p_npe->active = 0; +} + + +static int npe_send(struct eth_device *dev, volatile void *packet, int len) +{ + struct npe *p_npe = (struct npe *)dev->priv; + u8 *dest; + int err; + IX_OSAL_MBUF *m; + + debug("%s\n", __FUNCTION__); + m = mbuf_dequeue(&p_npe->txQHead); + dest = IX_OSAL_MBUF_MDATA(m); + IX_OSAL_MBUF_PKT_LEN(m) = IX_OSAL_MBUF_MLEN(m) = len; + IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m) = NULL; + + memcpy(dest, (char *)packet, len); + + if ((err = ixEthAccPortTxFrameSubmit(p_npe->eth_id, m, IX_ETH_ACC_TX_DEFAULT_PRIORITY)) + != IX_ETH_ACC_SUCCESS) { + printf("npe_send: Can't submit frame. err[%d]\n", err); + mbuf_enqueue(&p_npe->txQHead, m); + return 0; + } + +#ifdef DEBUG_PRINT_TX_FRAMES + { + u8 *ptr = IX_OSAL_MBUF_MDATA(m); + int i; + + for (i=0; ieth_id); + + return len; +} + +static int npe_rx(struct eth_device *dev) +{ + struct npe *p_npe = (struct npe *)dev->priv; + + debug("%s\n", __FUNCTION__); + npe_poll(p_npe->eth_id); + + debug("%s: rx_write=%d rx_read=%d\n", __FUNCTION__, p_npe->rx_write, p_npe->rx_read); + while (p_npe->rx_write != p_npe->rx_read) { + debug("Reading message #%d\n", p_npe->rx_read); + NetReceive(NetRxPackets[p_npe->rx_read], p_npe->rx_len[p_npe->rx_read]); + p_npe->rx_read++; + if (p_npe->rx_read == PKTBUFSRX) + p_npe->rx_read = 0; + } + + return 0; +} + +int npe_initialize(bd_t * bis) +{ + static int virgin = 0; + struct eth_device *dev; + int eth_num = 0; + struct npe *p_npe = NULL; + uchar enetaddr[6]; + + for (eth_num = 0; eth_num < CONFIG_SYS_NPE_NUMS; eth_num++) { + + /* See if we can actually bring up the interface, otherwise, skip it */ +#ifdef CONFIG_HAS_ETH1 + if (eth_num == 1) { + if (!eth_getenv_enetaddr("eth1addr", enetaddr)) + continue; + } else +#endif + if (!eth_getenv_enetaddr("ethaddr", enetaddr)) + continue; + + /* Allocate device structure */ + dev = (struct eth_device *)malloc(sizeof(*dev)); + if (dev == NULL) { + printf ("%s: Cannot allocate eth_device %d\n", __FUNCTION__, eth_num); + return -1; + } + memset(dev, 0, sizeof(*dev)); + + /* Allocate our private use data */ + p_npe = (struct npe *)malloc(sizeof(struct npe)); + if (p_npe == NULL) { + printf("%s: Cannot allocate private hw data for eth_device %d", + __FUNCTION__, eth_num); + free(dev); + return -1; + } + memset(p_npe, 0, sizeof(struct npe)); + + p_npe->eth_id = eth_num; + memcpy(dev->enetaddr, enetaddr, 6); +#ifdef CONFIG_HAS_ETH1 + if (eth_num == 1) + p_npe->phy_no = CONFIG_PHY1_ADDR; + else +#endif + p_npe->phy_no = CONFIG_PHY_ADDR; + + sprintf(dev->name, "NPE%d", eth_num); + dev->priv = (void *)p_npe; + dev->init = npe_init; + dev->halt = npe_halt; + dev->send = npe_send; + dev->recv = npe_rx; + + p_npe->print_speed = 1; + + if (0 == virgin) { + virgin = 1; + + if (ixFeatureCtrlDeviceRead() == IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X) { + switch (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK) { + case IX_FEATURE_CTRL_SILICON_TYPE_B0: + /* + * If it is B0 Silicon, we only enable port when its corresponding + * Eth Coprocessor is available. + */ + if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) == + IX_FEATURE_CTRL_COMPONENT_ENABLED) + npe_exists[IX_ETH_PORT_1] = TRUE; + + if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) == + IX_FEATURE_CTRL_COMPONENT_ENABLED) + npe_exists[IX_ETH_PORT_2] = TRUE; + break; + case IX_FEATURE_CTRL_SILICON_TYPE_A0: + /* + * If it is A0 Silicon, we enable both as both Eth Coprocessors + * are available. + */ + npe_exists[IX_ETH_PORT_1] = TRUE; + npe_exists[IX_ETH_PORT_2] = TRUE; + break; + } + } else if (ixFeatureCtrlDeviceRead() == IX_FEATURE_CTRL_DEVICE_TYPE_IXP46X) { + if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) == + IX_FEATURE_CTRL_COMPONENT_ENABLED) + npe_exists[IX_ETH_PORT_1] = TRUE; + + if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) == + IX_FEATURE_CTRL_COMPONENT_ENABLED) + npe_exists[IX_ETH_PORT_2] = TRUE; + } + + npe_used[IX_ETH_PORT_1] = 1; + npe_used[IX_ETH_PORT_2] = 1; + + npe_alloc_end = npe_alloc_pool + sizeof(npe_alloc_pool); + npe_alloc_free = (u8 *)(((unsigned)npe_alloc_pool + + CONFIG_SYS_CACHELINE_SIZE - 1) + & ~(CONFIG_SYS_CACHELINE_SIZE - 1)); + + if (!npe_csr_load()) + return 0; + } + + eth_register(dev); + +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) + miiphy_register(dev->name, npe_miiphy_read, npe_miiphy_write); +#endif + + } /* end for each supported device */ + + return 1; +} diff --git a/arch/arm/cpu/ixp/start.S b/arch/arm/cpu/ixp/start.S new file mode 100644 index 0000000000..5ebce5338c --- /dev/null +++ b/arch/arm/cpu/ixp/start.S @@ -0,0 +1,525 @@ +/* vi: set ts=8 sw=8 noet: */ +/* + * u-boot - Startup Code for XScale IXP + * + * Copyright (C) 2003 Kyle Harris + * + * Based on startup code example contained in the + * Intel IXP4xx Programmer's Guide and past u-boot Start.S + * samples. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +#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: b 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 + +_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 + */ + +_TEXT_BASE: + .word TEXT_BASE + +.globl _armboot_start +_armboot_start: + .word _start + +/* + * These are defined in the board-specific linker script. + */ +.globl _bss_start +_bss_start: + .word __bss_start + +.globl _bss_end +_bss_end: + .word _end + +#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 + +/****************************************************************************/ +/* */ +/* 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 */ +#if 0 + ldr r2, =IXP425_EXP_CFG0 + ldr r1, [r2] + orr r1, r1, #0x80000000 + str r1, [r2] +#endif + 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 + + /* copy */ + mov r0, #0 + mov r4, r0 + add r2, r0, #CONFIG_SYS_MONITOR_LEN + mov r1, #0x10000000 + mov r5, r1 + + 30: + ldr r3, [r0], #4 + str r3, [r1], #4 + cmp r0, r2 + bne 30b + + /* 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 + + /* move flash to 0x50000000 */ + ldr r2, =IXP425_EXP_CFG0 + ldr r1, [r2] + bic r1, r1, #0x80000000 + str r1, [r2] + + nop + nop + nop + nop + nop + nop + + /* 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 + +#ifndef CONFIG_SKIP_RELOCATE_UBOOT +relocate: /* relocate U-Boot to RAM */ + adr r0, _start /* r0 <- current position of code */ + ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ + cmp r0, r1 /* don't reloc during debug */ + beq stack_setup + + ldr r2, _armboot_start + ldr r3, _bss_start + sub r2, r3, r2 /* r2 <- size of armboot */ + add r2, r0, r2 /* r2 <- source end address */ + +copy_loop: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end addreee [r2] */ + ble copy_loop +#endif /* CONFIG_SKIP_RELOCATE_UBOOT */ + + /* Set up the stack */ +stack_setup: + ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ + sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */ + sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ +#ifdef CONFIG_USE_IRQ + sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) +#endif + sub sp, r0, #12 /* leave 3 words for abort-stack */ + +clear_bss: + ldr r0, _bss_start /* find start of bss segment */ + ldr r1, _bss_end /* stop here */ + mov r2, #0x00000000 /* clear */ + +clbss_l:str r2, [r0] /* clear loop... */ + add r0, r0, #4 + cmp r0, r1 + ble clbss_l + + ldr pc, _start_armboot + +_start_armboot: .word start_armboot + + +/****************************************************************************/ +/* */ +/* 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, _armboot_start + sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) + sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack + 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, _armboot_start @ setup our mode stack + sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) + sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort 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 + +#ifdef CONFIG_USE_IRQ + +.LC0: .word loops_per_jiffy + +/* + * 0 <= r0 <= 2000 + */ +.globl __udelay +__udelay: + mov r2, #0x6800 + orr r2, r2, #0x00db + mul r0, r2, r0 + ldr r2, .LC0 + ldr r2, [r2] @ max = 0x0fffffff + mov r0, r0, lsr #11 @ max = 0x00003fff + mov r2, r2, lsr #11 @ max = 0x0003ffff + mul r0, r2, r0 @ max = 2^32-1 + movs r0, r0, lsr #6 + +delay_loop: + subs r0, r0, #1 + bne delay_loop + mov pc, lr + +#endif /* CONFIG_USE_IRQ */ diff --git a/arch/arm/cpu/ixp/timer.c b/arch/arm/cpu/ixp/timer.c new file mode 100644 index 0000000000..edf341ff9f --- /dev/null +++ b/arch/arm/cpu/ixp/timer.c @@ -0,0 +1,135 @@ +/* + * (C) Copyright 2006 + * Stefan Roese, DENX Software Engineering, sr@denx.de. + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +#ifdef CONFIG_TIMER_IRQ + +#define FREQ 66666666 +#define CLOCK_TICK_RATE (((FREQ / CONFIG_SYS_HZ & ~IXP425_OST_RELOAD_MASK) + 1) * CONFIG_SYS_HZ) +#define LATCH ((CLOCK_TICK_RATE + CONFIG_SYS_HZ/2) / CONFIG_SYS_HZ) /* For divider */ + +/* + * When interrupts are enabled, use timer 2 for time/delay generation... + */ + +static volatile ulong timestamp; + +static void timer_isr(void *data) +{ + unsigned int *pTime = (unsigned int *)data; + + (*pTime)++; + + /* + * Reset IRQ source + */ + *IXP425_OSST = IXP425_OSST_TIMER_2_PEND; +} + +ulong get_timer (ulong base) +{ + return timestamp - base; +} + +void reset_timer (void) +{ + timestamp = 0; +} + +int timer_init (void) +{ + /* install interrupt handler for timer */ + irq_install_handler(IXP425_TIMER_2_IRQ, timer_isr, (void *)×tamp); + + /* setup the Timer counter value */ + *IXP425_OSRT2 = (LATCH & ~IXP425_OST_RELOAD_MASK) | IXP425_OST_ENABLE; + + /* enable timer irq */ + *IXP425_ICMR = (1 << IXP425_TIMER_2_IRQ); + + return 0; +} +#else +ulong get_timer (ulong base) +{ + return get_timer_masked () - base; +} + +void ixp425_udelay(unsigned long usec) +{ + /* + * This function has a max usec, but since it is called from udelay + * we should not have to worry... be happy + */ + unsigned long usecs = CONFIG_SYS_HZ/1000000L & ~IXP425_OST_RELOAD_MASK; + + *IXP425_OSST = IXP425_OSST_TIMER_1_PEND; + usecs |= IXP425_OST_ONE_SHOT | IXP425_OST_ENABLE; + *IXP425_OSRT1 = usecs; + while (!(*IXP425_OSST & IXP425_OSST_TIMER_1_PEND)); +} + +void __udelay (unsigned long usec) +{ + while (usec--) ixp425_udelay(1); +} + +static ulong reload_constant = 0xfffffff0; + +void reset_timer_masked (void) +{ + ulong reload = reload_constant | IXP425_OST_ONE_SHOT | IXP425_OST_ENABLE; + + *IXP425_OSST = IXP425_OSST_TIMER_1_PEND; + *IXP425_OSRT1 = reload; +} + +ulong get_timer_masked (void) +{ + /* + * Note that it is possible for this to wrap! + * In this case we return max. + */ + ulong current = *IXP425_OST1; + if (*IXP425_OSST & IXP425_OSST_TIMER_1_PEND) + { + return reload_constant; + } + return (reload_constant - current); +} + +int timer_init(void) +{ + return 0; +} +#endif diff --git a/arch/arm/cpu/ixp/u-boot.lds b/arch/arm/cpu/ixp/u-boot.lds new file mode 100644 index 0000000000..b8ff2eed5c --- /dev/null +++ b/arch/arm/cpu/ixp/u-boot.lds @@ -0,0 +1,56 @@ +/* + * (C) Copyright 2000-2006 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_FORMAT("elf32-bigarm", "elf32-bigarm", "elf32-bigarm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + arch/arm/cpu/ixp/start.o(.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = ALIGN(4); + __bss_start = .; + .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } + _end = .; +} diff --git a/arch/arm/cpu/lh7a40x/Makefile b/arch/arm/cpu/lh7a40x/Makefile new file mode 100644 index 0000000000..1b3f58abb9 --- /dev/null +++ b/arch/arm/cpu/lh7a40x/Makefile @@ -0,0 +1,47 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(CPU).a + +START = start.o +COBJS = cpu.o speed.o timer.o + +SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/lh7a40x/config.mk b/arch/arm/cpu/lh7a40x/config.mk new file mode 100644 index 0000000000..47b2b7b722 --- /dev/null +++ b/arch/arm/cpu/lh7a40x/config.mk @@ -0,0 +1,32 @@ +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float + +PLATFORM_CPPFLAGS += -march=armv4 +# ========================================================================= +# +# Supply options according to compiler version +# +# ======================================================================== +PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/arch/arm/cpu/lh7a40x/cpu.c b/arch/arm/cpu/lh7a40x/cpu.c new file mode 100644 index 0000000000..b193189123 --- /dev/null +++ b/arch/arm/cpu/lh7a40x/cpu.c @@ -0,0 +1,65 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * CPU specific code + */ + +#include +#include +#include + +static void cache_flush(void); + +int cleanup_before_linux (void) +{ + /* + * this function is called just before we call linux + * it prepares the processor for linux + * + * we turn off caches etc ... + */ + + disable_interrupts (); + + /* turn off I/D-cache */ + icache_disable(); + dcache_disable(); + + /* flush I/D-cache */ + cache_flush(); + + return 0; +} + +/* flush I/D-cache */ +static void cache_flush (void) +{ + unsigned long i = 0; + + asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); +} diff --git a/arch/arm/cpu/lh7a40x/speed.c b/arch/arm/cpu/lh7a40x/speed.c new file mode 100644 index 0000000000..333ebb504a --- /dev/null +++ b/arch/arm/cpu/lh7a40x/speed.c @@ -0,0 +1,83 @@ +/* + * (C) Copyright 2001-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2002 + * David Mueller, ELSOFT AG, d.mueller@elsoft.ch + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + + +/* ------------------------------------------------------------------------- */ +/* NOTE: This describes the proper use of this file. + * + * CONFIG_SYS_CLK_FREQ should be defined as the input frequency of the PLL. + * + * get_FCLK(), get_HCLK(), get_PCLK() return the clock of + * the specified bus in HZ. + */ +/* ------------------------------------------------------------------------- */ + +ulong get_PLLCLK (void) +{ + return CONFIG_SYS_CLK_FREQ; +} + +/* return FCLK frequency */ +ulong get_FCLK (void) +{ + lh7a40x_csc_t* csc = LH7A40X_CSC_PTR; + ulong maindiv1, maindiv2, prediv, ps; + + /* + * from userguide 6.1.1.2 + * + * FCLK = ((MAINDIV1 +2) * (MAINDIV2 +2) * 14.7456MHz) / + * ((PREDIV+2) * (2^PS)) + */ + maindiv2 = (csc->clkset & CLKSET_MAINDIV2) >> 11; + maindiv1 = (csc->clkset & CLKSET_MAINDIV1) >> 7; + prediv = (csc->clkset & CLKSET_PREDIV) >> 2; + ps = (csc->clkset & CLKSET_PS) >> 16; + + return (((maindiv2 + 2) * (maindiv1 + 2) * CONFIG_SYS_CLK_FREQ) / + ((prediv + 2) * (1 << ps))); +} + + +/* return HCLK frequency */ +ulong get_HCLK (void) +{ + lh7a40x_csc_t* csc = LH7A40X_CSC_PTR; + + return (get_FCLK () / ((csc->clkset & CLKSET_HCLKDIV) + 1)); +} + +/* return PCLK frequency */ +ulong get_PCLK (void) +{ + lh7a40x_csc_t* csc = LH7A40X_CSC_PTR; + + return (get_HCLK () / + (1 << (((csc->clkset & CLKSET_PCLKDIV) >> 16) + 1))); +} diff --git a/arch/arm/cpu/lh7a40x/start.S b/arch/arm/cpu/lh7a40x/start.S new file mode 100644 index 0000000000..a1321b1d74 --- /dev/null +++ b/arch/arm/cpu/lh7a40x/start.S @@ -0,0 +1,428 @@ +/* + * armboot - Startup Code for ARM920 CPU-core + * + * Copyright (c) 2001 Marius Gröger + * Copyright (c) 2002 Alex Züpke + * Copyright (c) 2002 Gary Jennejohn + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + +#include +#include + + +/* + ************************************************************************* + * + * Jump vector table as in table 3.1 in [1] + * + ************************************************************************* + */ + + +.globl _start +_start: b 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 + +_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 + * + ************************************************************************* + */ + +_TEXT_BASE: + .word TEXT_BASE + +.globl _armboot_start +_armboot_start: + .word _start + +/* + * These are defined in the board-specific linker script. + */ +.globl _bss_start +_bss_start: + .word __bss_start + +.globl _bss_end +_bss_end: + .word _end + +#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 + + +/* + * the actual reset code + */ + +reset: + /* + * set the cpu to SVC32 mode + */ + mrs r0,cpsr + bic r0,r0,#0x1f + orr r0,r0,#0xd3 + msr cpsr,r0 + +#define pWDTCTL 0x80001400 /* Watchdog Timer control register */ +#define pINTENC 0x8000050C /* Interupt-Controller enable clear register */ +#define pCLKSET 0x80000420 /* clock divisor register */ + + /* disable watchdog, set watchdog control register to + * all zeros (default reset) + */ + ldr r0, =pWDTCTL + mov r1, #0x0 + str r1, [r0] + + /* + * mask all IRQs by setting all bits in the INTENC register (default) + */ + mov r1, #0xffffffff + ldr r0, =pINTENC + str r1, [r0] + + /* FCLK:HCLK:PCLK = 1:2:2 */ + /* default FCLK is 200 MHz, using 14.7456 MHz fin */ + ldr r0, =pCLKSET + ldr r1, =0x0004ee39 +@ ldr r1, =0x0005ee39 @ 1: 2: 4 + str r1, [r0] + + /* + * we do sys-critical inits only at reboot, + * not when booting from ram! + */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl cpu_init_crit +#endif + +#ifndef CONFIG_SKIP_RELOCATE_UBOOT +relocate: /* relocate U-Boot to RAM */ + adr r0, _start /* r0 <- current position of code */ + ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ + cmp r0, r1 /* don't reloc during debug */ + beq stack_setup + + ldr r2, _armboot_start + ldr r3, _bss_start + sub r2, r3, r2 /* r2 <- size of armboot */ + add r2, r0, r2 /* r2 <- source end address */ + +copy_loop: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end addreee [r2] */ + blt copy_loop /* a 'ble' here actually copies */ + /* four bytes of bss */ +#endif /* CONFIG_SKIP_RELOCATE_UBOOT */ + + /* Set up the stack */ +stack_setup: + ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ + sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */ + sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ +#ifdef CONFIG_USE_IRQ + sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) +#endif + sub sp, r0, #12 /* leave 3 words for abort-stack */ + +clear_bss: + ldr r0, _bss_start /* find start of bss segment */ + @add r0, r0, #4 /* start at first byte of bss */ + /* why inc. 4 bytes past then? */ + ldr r1, _bss_end /* stop here */ + mov r2, #0x00000000 /* clear */ + +clbss_l:str r2, [r0] /* clear loop... */ + add r0, r0, #4 + cmp r0, r1 + ble clbss_l + + ldr pc, _start_armboot + +_start_armboot: .word start_armboot + + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + ************************************************************************* + */ + + +cpu_init_crit: + /* + * flush v4 I/D caches + */ + mov r0, #0 + mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ + mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ + + /* + * disable MMU stuff and caches + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) + bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) + orr r0, r0, #0x00000002 @ set bit 2 (A) Align + orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache + orr r0, r0, #0x40000000 @ set bit 30 (nF) notFastBus + mcr p15, 0, r0, c1, c0, 0 + + + /* + * before relocating, we have to setup RAM timing + * because memory timing is board-dependend, you will + * find a lowlevel_init.S in your board directory. + */ + mov ip, lr + bl lowlevel_init + mov lr, ip + + mov pc, 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 +#define I_BIT 0x80 + +/* + * use bad_save_user_regs for abort/prefetch/undef/swi ... + * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling + */ + + .macro bad_save_user_regs + sub sp, sp, #S_FRAME_SIZE + stmia sp, {r0 - r12} @ Calling r0-r12 + ldr r2, _armboot_start + sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) + sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack + ldmia r2, {r2 - r3} @ get pc, cpsr + add r0, sp, #S_FRAME_SIZE @ restore sp_SVC + + add r5, sp, #S_SP + mov r1, lr + stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr + mov r0, sp + .endm + + .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, _armboot_start @ setup our mode stack + sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) + sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort 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 + msr spsr, 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 + /* someone ought to write a more effiction fiq_save_user_regs */ + irq_save_user_regs + bl do_fiq + 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 + + .align 5 +.globl reset_cpu +reset_cpu: + bl disable_interrupts + + /* Disable watchdog */ + ldr r1, =pWDTCTL + mov r3, #0 + str r3, [r1] + + /* reset counter */ + ldr r3, =0x00001984 + str r3, [r1, #4] + + /* Enable the watchdog */ + mov r3, #1 + str r3, [r1] + +_loop_forever: + b _loop_forever diff --git a/arch/arm/cpu/lh7a40x/timer.c b/arch/arm/cpu/lh7a40x/timer.c new file mode 100644 index 0000000000..2691315d84 --- /dev/null +++ b/arch/arm/cpu/lh7a40x/timer.c @@ -0,0 +1,193 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +static ulong timer_load_val = 0; + +/* macro to read the 16 bit timer */ +static inline ulong READ_TIMER(void) +{ + lh7a40x_timers_t* timers = LH7A40X_TIMERS_PTR; + lh7a40x_timer_t* timer = &timers->timer1; + + return (timer->value & 0x0000ffff); +} + +static ulong timestamp; +static ulong lastdec; + +int timer_init (void) +{ + lh7a40x_timers_t* timers = LH7A40X_TIMERS_PTR; + lh7a40x_timer_t* timer = &timers->timer1; + + /* a periodic timer using the 508kHz source */ + timer->control = (TIMER_PER | TIMER_CLK508K); + + if (timer_load_val == 0) { + /* + * 10ms period with 508.469kHz clock = 5084 + */ + timer_load_val = CONFIG_SYS_HZ/100; + } + + /* load value for 10 ms timeout */ + lastdec = timer->load = timer_load_val; + + /* auto load, start timer */ + timer->control = timer->control | TIMER_EN; + timestamp = 0; + + return (0); +} + +/* + * timer without interrupts + */ + +void reset_timer (void) +{ + reset_timer_masked (); +} + +ulong get_timer (ulong base) +{ + return (get_timer_masked() - base); +} + +void set_timer (ulong t) +{ + timestamp = t; +} + +void __udelay (unsigned long usec) +{ + ulong tmo,tmp; + + /* normalize */ + if (usec >= 1000) { + tmo = usec / 1000; + tmo *= CONFIG_SYS_HZ; + tmo /= 1000; + } + else { + if (usec > 1) { + tmo = usec * CONFIG_SYS_HZ; + tmo /= (1000*1000); + } + else + tmo = 1; + } + + /* check for rollover during this delay */ + tmp = get_timer (0); + if ((tmp + tmo) < tmp ) + reset_timer_masked(); /* timer would roll over */ + else + tmo += tmp; + + while (get_timer_masked () < tmo); +} + +void reset_timer_masked (void) +{ + /* reset time */ + lastdec = READ_TIMER(); + timestamp = 0; +} + +ulong get_timer_masked (void) +{ + ulong now = READ_TIMER(); + + if (lastdec >= now) { + /* normal mode */ + timestamp += (lastdec - now); + } else { + /* we have an overflow ... */ + timestamp += ((lastdec + timer_load_val) - now); + } + lastdec = now; + + return timestamp; +} + +void udelay_masked (unsigned long usec) +{ + ulong tmo; + ulong endtime; + signed long diff; + + /* normalize */ + if (usec >= 1000) { + tmo = usec / 1000; + tmo *= CONFIG_SYS_HZ; + tmo /= 1000; + } else { + if (usec > 1) { + tmo = usec * CONFIG_SYS_HZ; + tmo /= (1000*1000); + } else { + tmo = 1; + } + } + + endtime = get_timer_masked () + tmo; + + do { + ulong now = get_timer_masked (); + diff = endtime - now; + } while (diff >= 0); +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk (void) +{ + ulong tbclk; + + tbclk = timer_load_val * 100; + + return tbclk; +} diff --git a/arch/arm/cpu/lh7a40x/u-boot.lds b/arch/arm/cpu/lh7a40x/u-boot.lds new file mode 100644 index 0000000000..5a8ccf5888 --- /dev/null +++ b/arch/arm/cpu/lh7a40x/u-boot.lds @@ -0,0 +1,56 @@ +/* + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + arch/arm/cpu/lh7a40x/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = ALIGN(4); + __bss_start = .; + .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } + _end = .; +} diff --git a/arch/arm/cpu/pxa/Makefile b/arch/arm/cpu/pxa/Makefile new file mode 100644 index 0000000000..07a151a170 --- /dev/null +++ b/arch/arm/cpu/pxa/Makefile @@ -0,0 +1,52 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(CPU).a + +START = start.o + +COBJS += cpu.o +COBJS += i2c.o +COBJS += pxafb.o +COBJS += timer.o +COBJS += usb.o + +SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/pxa/config.mk b/arch/arm/cpu/pxa/config.mk new file mode 100644 index 0000000000..a05d69ca27 --- /dev/null +++ b/arch/arm/cpu/pxa/config.mk @@ -0,0 +1,33 @@ +# +# (C) Copyright 2002 +# Sysgo Real-Time Solutions, GmbH +# Marius Groeger +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float + +PLATFORM_CPPFLAGS += -march=armv5te -mtune=xscale +# ========================================================================= +# +# Supply options according to compiler version +# +# ======================================================================== +PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/arch/arm/cpu/pxa/cpu.c b/arch/arm/cpu/pxa/cpu.c new file mode 100644 index 0000000000..800d120e71 --- /dev/null +++ b/arch/arm/cpu/pxa/cpu.c @@ -0,0 +1,87 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * CPU specific code + */ + +#include +#include +#include +#include + +static void cache_flush(void); + +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)); +} + +#ifndef CONFIG_CPU_MONAHANS +void set_GPIO_mode(int gpio_mode) +{ + int gpio = gpio_mode & GPIO_MD_MASK_NR; + int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8; + int gafr; + + if (gpio_mode & GPIO_MD_MASK_DIR) + { + GPDR(gpio) |= GPIO_bit(gpio); + } + else + { + GPDR(gpio) &= ~GPIO_bit(gpio); + } + gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2)); + GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2)); +} +#endif /* CONFIG_CPU_MONAHANS */ diff --git a/arch/arm/cpu/pxa/i2c.c b/arch/arm/cpu/pxa/i2c.c new file mode 100644 index 0000000000..6b72ba13a0 --- /dev/null +++ b/arch/arm/cpu/pxa/i2c.c @@ -0,0 +1,458 @@ +/* + * (C) Copyright 2000 + * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it + * + * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2003 Pengutronix e.K. + * Robert Schwebel + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Back ported to the 8xx platform (from the 8260 platform) by + * Murray.Jensen@cmst.csiro.au, 27-Jan-01. + */ + +/* FIXME: this file is PXA255 specific! What about other XScales? */ + +#include + +#ifdef CONFIG_HARD_I2C + +/* + * - CONFIG_SYS_I2C_SPEED + * - I2C_PXA_SLAVE_ADDR + */ + +#include +#include +#include + +/*#define DEBUG_I2C 1 /###* activate local debugging output */ +#define I2C_PXA_SLAVE_ADDR 0x1 /* slave pxa unit address */ + +#if (CONFIG_SYS_I2C_SPEED == 400000) +#define I2C_ICR_INIT (ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE) +#else +#define I2C_ICR_INIT (ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE) +#endif + +#define I2C_ISR_INIT 0x7FF + +#ifdef DEBUG_I2C +#define PRINTD(x) printf x +#else +#define PRINTD(x) +#endif + + +/* Shall the current transfer have a start/stop condition? */ +#define I2C_COND_NORMAL 0 +#define I2C_COND_START 1 +#define I2C_COND_STOP 2 + +/* Shall the current transfer be ack/nacked or being waited for it? */ +#define I2C_ACKNAK_WAITACK 1 +#define I2C_ACKNAK_SENDACK 2 +#define I2C_ACKNAK_SENDNAK 4 + +/* Specify who shall transfer the data (master or slave) */ +#define I2C_READ 0 +#define I2C_WRITE 1 + +/* All transfers are described by this data structure */ +struct i2c_msg { + u8 condition; + u8 acknack; + u8 direction; + u8 data; +}; + + +/** + * i2c_pxa_reset: - reset the host controller + * + */ + +static void i2c_reset( void ) +{ + ICR &= ~ICR_IUE; /* disable unit */ + ICR |= ICR_UR; /* reset the unit */ + udelay(100); + ICR &= ~ICR_IUE; /* disable unit */ +#ifdef CONFIG_CPU_MONAHANS + CKENB |= (CKENB_4_I2C); /* | CKENB_1_PWM1 | CKENB_0_PWM0); */ +#else /* CONFIG_CPU_MONAHANS */ + CKEN |= CKEN14_I2C; /* set the global I2C clock on */ +#endif + ISAR = I2C_PXA_SLAVE_ADDR; /* set our slave address */ + ICR = I2C_ICR_INIT; /* set control register values */ + ISR = I2C_ISR_INIT; /* set clear interrupt bits */ + ICR |= ICR_IUE; /* enable unit */ + udelay(100); +} + + +/** + * i2c_isr_set_cleared: - wait until certain bits of the I2C status register + * are set and cleared + * + * @return: 1 in case of success, 0 means timeout (no match within 10 ms). + */ +static int i2c_isr_set_cleared( unsigned long set_mask, unsigned long cleared_mask ) +{ + int timeout = 10000; + + while( ((ISR & set_mask)!=set_mask) || ((ISR & cleared_mask)!=0) ){ + udelay( 10 ); + if( timeout-- < 0 ) return 0; + } + + return 1; +} + + +/** + * i2c_transfer: - Transfer one byte over the i2c bus + * + * This function can tranfer a byte over the i2c bus in both directions. + * It is used by the public API functions. + * + * @return: 0: transfer successful + * -1: message is empty + * -2: transmit timeout + * -3: ACK missing + * -4: receive timeout + * -5: illegal parameters + * -6: bus is busy and couldn't be aquired + */ +int i2c_transfer(struct i2c_msg *msg) +{ + int ret; + + if (!msg) + goto transfer_error_msg_empty; + + switch(msg->direction) { + + case I2C_WRITE: + + /* check if bus is not busy */ + if (!i2c_isr_set_cleared(0,ISR_IBB)) + goto transfer_error_bus_busy; + + /* start transmission */ + ICR &= ~ICR_START; + ICR &= ~ICR_STOP; + IDBR = msg->data; + if (msg->condition == I2C_COND_START) ICR |= ICR_START; + if (msg->condition == I2C_COND_STOP) ICR |= ICR_STOP; + if (msg->acknack == I2C_ACKNAK_SENDNAK) ICR |= ICR_ACKNAK; + if (msg->acknack == I2C_ACKNAK_SENDACK) ICR &= ~ICR_ACKNAK; + ICR &= ~ICR_ALDIE; + ICR |= ICR_TB; + + /* transmit register empty? */ + if (!i2c_isr_set_cleared(ISR_ITE,0)) + goto transfer_error_transmit_timeout; + + /* clear 'transmit empty' state */ + ISR |= ISR_ITE; + + /* wait for ACK from slave */ + if (msg->acknack == I2C_ACKNAK_WAITACK) + if (!i2c_isr_set_cleared(0,ISR_ACKNAK)) + goto transfer_error_ack_missing; + break; + + case I2C_READ: + + /* check if bus is not busy */ + if (!i2c_isr_set_cleared(0,ISR_IBB)) + goto transfer_error_bus_busy; + + /* start receive */ + ICR &= ~ICR_START; + ICR &= ~ICR_STOP; + if (msg->condition == I2C_COND_START) ICR |= ICR_START; + if (msg->condition == I2C_COND_STOP) ICR |= ICR_STOP; + if (msg->acknack == I2C_ACKNAK_SENDNAK) ICR |= ICR_ACKNAK; + if (msg->acknack == I2C_ACKNAK_SENDACK) ICR &= ~ICR_ACKNAK; + ICR &= ~ICR_ALDIE; + ICR |= ICR_TB; + + /* receive register full? */ + if (!i2c_isr_set_cleared(ISR_IRF,0)) + goto transfer_error_receive_timeout; + + msg->data = IDBR; + + /* clear 'receive empty' state */ + ISR |= ISR_IRF; + + break; + + default: + + goto transfer_error_illegal_param; + + } + + return 0; + +transfer_error_msg_empty: + PRINTD(("i2c_transfer: error: 'msg' is empty\n")); + ret = -1; goto i2c_transfer_finish; + +transfer_error_transmit_timeout: + PRINTD(("i2c_transfer: error: transmit timeout\n")); + ret = -2; goto i2c_transfer_finish; + +transfer_error_ack_missing: + PRINTD(("i2c_transfer: error: ACK missing\n")); + ret = -3; goto i2c_transfer_finish; + +transfer_error_receive_timeout: + PRINTD(("i2c_transfer: error: receive timeout\n")); + ret = -4; goto i2c_transfer_finish; + +transfer_error_illegal_param: + PRINTD(("i2c_transfer: error: illegal parameters\n")); + ret = -5; goto i2c_transfer_finish; + +transfer_error_bus_busy: + PRINTD(("i2c_transfer: error: bus is busy\n")); + ret = -6; goto i2c_transfer_finish; + +i2c_transfer_finish: + PRINTD(("i2c_transfer: ISR: 0x%04x\n",ISR)); + i2c_reset(); + return ret; + +} + +/* ------------------------------------------------------------------------ */ +/* API Functions */ +/* ------------------------------------------------------------------------ */ + +void i2c_init(int speed, int slaveaddr) +{ +#ifdef CONFIG_SYS_I2C_INIT_BOARD + /* call board specific i2c bus reset routine before accessing the */ + /* environment, which might be in a chip on that bus. For details */ + /* about this problem see doc/I2C_Edge_Conditions. */ + i2c_init_board(); +#endif +} + + +/** + * i2c_probe: - Test if a chip answers for a given i2c address + * + * @chip: address of the chip which is searched for + * @return: 0 if a chip was found, -1 otherwhise + */ + +int i2c_probe(uchar chip) +{ + struct i2c_msg msg; + + i2c_reset(); + + msg.condition = I2C_COND_START; + msg.acknack = I2C_ACKNAK_WAITACK; + msg.direction = I2C_WRITE; + msg.data = (chip << 1) + 1; + if (i2c_transfer(&msg)) return -1; + + msg.condition = I2C_COND_STOP; + msg.acknack = I2C_ACKNAK_SENDNAK; + msg.direction = I2C_READ; + msg.data = 0x00; + if (i2c_transfer(&msg)) return -1; + + return 0; +} + + +/** + * i2c_read: - Read multiple bytes from an i2c device + * + * The higher level routines take into account that this function is only + * called with len < page length of the device (see configuration file) + * + * @chip: address of the chip which is to be read + * @addr: i2c data address within the chip + * @alen: length of the i2c data address (1..2 bytes) + * @buffer: where to write the data + * @len: how much byte do we want to read + * @return: 0 in case of success + */ + +int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) +{ + struct i2c_msg msg; + u8 addr_bytes[3]; /* lowest...highest byte of data address */ + int ret; + + PRINTD(("i2c_read(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len)); + + i2c_reset(); + + /* dummy chip address write */ + PRINTD(("i2c_read: dummy chip address write\n")); + msg.condition = I2C_COND_START; + msg.acknack = I2C_ACKNAK_WAITACK; + msg.direction = I2C_WRITE; + msg.data = (chip << 1); + msg.data &= 0xFE; + if ((ret=i2c_transfer(&msg))) return -1; + + /* + * send memory address bytes; + * alen defines how much bytes we have to send. + */ + /*addr &= ((1 << CONFIG_SYS_EEPROM_PAGE_WRITE_BITS)-1); */ + addr_bytes[0] = (u8)((addr >> 0) & 0x000000FF); + addr_bytes[1] = (u8)((addr >> 8) & 0x000000FF); + addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF); + + while (--alen >= 0) { + + PRINTD(("i2c_read: send memory word address byte %1d\n",alen)); + msg.condition = I2C_COND_NORMAL; + msg.acknack = I2C_ACKNAK_WAITACK; + msg.direction = I2C_WRITE; + msg.data = addr_bytes[alen]; + if ((ret=i2c_transfer(&msg))) return -1; + } + + + /* start read sequence */ + PRINTD(("i2c_read: start read sequence\n")); + msg.condition = I2C_COND_START; + msg.acknack = I2C_ACKNAK_WAITACK; + msg.direction = I2C_WRITE; + msg.data = (chip << 1); + msg.data |= 0x01; + if ((ret=i2c_transfer(&msg))) return -1; + + /* read bytes; send NACK at last byte */ + while (len--) { + + if (len==0) { + msg.condition = I2C_COND_STOP; + msg.acknack = I2C_ACKNAK_SENDNAK; + } else { + msg.condition = I2C_COND_NORMAL; + msg.acknack = I2C_ACKNAK_SENDACK; + } + + msg.direction = I2C_READ; + msg.data = 0x00; + if ((ret=i2c_transfer(&msg))) return -1; + + *buffer = msg.data; + PRINTD(("i2c_read: reading byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer)); + buffer++; + + } + + i2c_reset(); + + return 0; +} + + +/** + * i2c_write: - Write multiple bytes to an i2c device + * + * The higher level routines take into account that this function is only + * called with len < page length of the device (see configuration file) + * + * @chip: address of the chip which is to be written + * @addr: i2c data address within the chip + * @alen: length of the i2c data address (1..2 bytes) + * @buffer: where to find the data to be written + * @len: how much byte do we want to read + * @return: 0 in case of success + */ + +int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) +{ + struct i2c_msg msg; + u8 addr_bytes[3]; /* lowest...highest byte of data address */ + + PRINTD(("i2c_write(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len)); + + i2c_reset(); + + /* chip address write */ + PRINTD(("i2c_write: chip address write\n")); + msg.condition = I2C_COND_START; + msg.acknack = I2C_ACKNAK_WAITACK; + msg.direction = I2C_WRITE; + msg.data = (chip << 1); + msg.data &= 0xFE; + if (i2c_transfer(&msg)) return -1; + + /* + * send memory address bytes; + * alen defines how much bytes we have to send. + */ + addr_bytes[0] = (u8)((addr >> 0) & 0x000000FF); + addr_bytes[1] = (u8)((addr >> 8) & 0x000000FF); + addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF); + + while (--alen >= 0) { + + PRINTD(("i2c_write: send memory word address\n")); + msg.condition = I2C_COND_NORMAL; + msg.acknack = I2C_ACKNAK_WAITACK; + msg.direction = I2C_WRITE; + msg.data = addr_bytes[alen]; + if (i2c_transfer(&msg)) return -1; + } + + /* write bytes; send NACK at last byte */ + while (len--) { + + PRINTD(("i2c_write: writing byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer)); + + if (len==0) + msg.condition = I2C_COND_STOP; + else + msg.condition = I2C_COND_NORMAL; + + msg.acknack = I2C_ACKNAK_WAITACK; + msg.direction = I2C_WRITE; + msg.data = *(buffer++); + + if (i2c_transfer(&msg)) return -1; + + } + + i2c_reset(); + + return 0; + +} + +#endif /* CONFIG_HARD_I2C */ diff --git a/arch/arm/cpu/pxa/pxafb.c b/arch/arm/cpu/pxa/pxafb.c new file mode 100644 index 0000000000..d56c5f099f --- /dev/null +++ b/arch/arm/cpu/pxa/pxafb.c @@ -0,0 +1,471 @@ +/* + * PXA LCD Controller + * + * (C) Copyright 2001-2002 + * Wolfgang Denk, DENX Software Engineering -- wd@denx.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/************************************************************************/ +/* ** HEADER FILES */ +/************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* #define DEBUG */ + +#ifdef CONFIG_LCD + +/*----------------------------------------------------------------------*/ +/* + * Define panel bpp, LCCR0, LCCR3 and panel_info video struct for + * your display. + */ + +#ifdef CONFIG_PXA_VGA +/* LCD outputs connected to a video DAC */ +# define LCD_BPP LCD_COLOR8 + +/* you have to set lccr0 and lccr3 (including pcd) */ +# define REG_LCCR0 0x003008f8 +# define REG_LCCR3 0x0300FF01 + +/* 640x480x16 @ 61 Hz */ +vidinfo_t panel_info = { + vl_col: 640, + vl_row: 480, + vl_width: 640, + vl_height: 480, + vl_clkp: CONFIG_SYS_HIGH, + vl_oep: CONFIG_SYS_HIGH, + vl_hsp: CONFIG_SYS_HIGH, + vl_vsp: CONFIG_SYS_HIGH, + vl_dp: CONFIG_SYS_HIGH, + vl_bpix: LCD_BPP, + vl_lbw: 0, + vl_splt: 0, + vl_clor: 0, + vl_tft: 1, + vl_hpw: 40, + vl_blw: 56, + vl_elw: 56, + vl_vpw: 20, + vl_bfw: 8, + vl_efw: 8, +}; +#endif /* CONFIG_PXA_VIDEO */ + +/*----------------------------------------------------------------------*/ +#ifdef CONFIG_SHARP_LM8V31 + +# define LCD_BPP LCD_COLOR8 +# define LCD_INVERT_COLORS /* Needed for colors to be correct, but why? */ + +/* you have to set lccr0 and lccr3 (including pcd) */ +# define REG_LCCR0 0x0030087C +# define REG_LCCR3 0x0340FF08 + +vidinfo_t panel_info = { + vl_col: 640, + vl_row: 480, + vl_width: 157, + vl_height: 118, + vl_clkp: CONFIG_SYS_HIGH, + vl_oep: CONFIG_SYS_HIGH, + vl_hsp: CONFIG_SYS_HIGH, + vl_vsp: CONFIG_SYS_HIGH, + vl_dp: CONFIG_SYS_HIGH, + vl_bpix: LCD_BPP, + vl_lbw: 0, + vl_splt: 1, + vl_clor: 1, + vl_tft: 0, + vl_hpw: 1, + vl_blw: 3, + vl_elw: 3, + vl_vpw: 1, + vl_bfw: 0, + vl_efw: 0, +}; +#endif /* CONFIG_SHARP_LM8V31 */ + +/*----------------------------------------------------------------------*/ +#ifdef CONFIG_HITACHI_SX14 +/* Hitachi SX14Q004-ZZA color STN LCD */ +#define LCD_BPP LCD_COLOR8 + +/* you have to set lccr0 and lccr3 (including pcd) */ +#define REG_LCCR0 0x00301079 +#define REG_LCCR3 0x0340FF20 + +vidinfo_t panel_info = { + vl_col: 320, + vl_row: 240, + vl_width: 167, + vl_height: 109, + vl_clkp: CONFIG_SYS_HIGH, + vl_oep: CONFIG_SYS_HIGH, + vl_hsp: CONFIG_SYS_HIGH, + vl_vsp: CONFIG_SYS_HIGH, + vl_dp: CONFIG_SYS_HIGH, + vl_bpix: LCD_BPP, + vl_lbw: 1, + vl_splt: 0, + vl_clor: 1, + vl_tft: 0, + vl_hpw: 1, + vl_blw: 1, + vl_elw: 1, + vl_vpw: 7, + vl_bfw: 0, + vl_efw: 0, +}; +#endif /* CONFIG_HITACHI_SX14 */ + +/*----------------------------------------------------------------------*/ + +#if LCD_BPP == LCD_COLOR8 +void lcd_setcolreg (ushort regno, ushort red, ushort green, ushort blue); +#endif +#if LCD_BPP == LCD_MONOCHROME +void lcd_initcolregs (void); +#endif + +#ifdef NOT_USED_SO_FAR +void lcd_disable (void); +void lcd_getcolreg (ushort regno, ushort *red, ushort *green, ushort *blue); +#endif /* NOT_USED_SO_FAR */ + +void lcd_ctrl_init (void *lcdbase); +void lcd_enable (void); + +int lcd_line_length; +int lcd_color_fg; +int lcd_color_bg; + +void *lcd_base; /* Start of framebuffer memory */ +void *lcd_console_address; /* Start of console buffer */ + +short console_col; +short console_row; + +static int pxafb_init_mem (void *lcdbase, vidinfo_t *vid); +static void pxafb_setup_gpio (vidinfo_t *vid); +static void pxafb_enable_controller (vidinfo_t *vid); +static int pxafb_init (vidinfo_t *vid); +/************************************************************************/ + +/************************************************************************/ +/* --------------- PXA chipset specific functions ------------------- */ +/************************************************************************/ + +void lcd_ctrl_init (void *lcdbase) +{ + pxafb_init_mem(lcdbase, &panel_info); + pxafb_init(&panel_info); + pxafb_setup_gpio(&panel_info); + pxafb_enable_controller(&panel_info); +} + +/*----------------------------------------------------------------------*/ +#ifdef NOT_USED_SO_FAR +void +lcd_getcolreg (ushort regno, ushort *red, ushort *green, ushort *blue) +{ +} +#endif /* NOT_USED_SO_FAR */ + +/*----------------------------------------------------------------------*/ +#if LCD_BPP == LCD_COLOR8 +void +lcd_setcolreg (ushort regno, ushort red, ushort green, ushort blue) +{ + struct pxafb_info *fbi = &panel_info.pxa; + unsigned short *palette = (unsigned short *)fbi->palette; + u_int val; + + if (regno < fbi->palette_size) { + val = ((red << 8) & 0xf800); + val |= ((green << 4) & 0x07e0); + val |= (blue & 0x001f); + +#ifdef LCD_INVERT_COLORS + palette[regno] = ~val; +#else + palette[regno] = val; +#endif + } + + debug ("setcolreg: reg %2d @ %p: R=%02X G=%02X B=%02X => %04X\n", + regno, &palette[regno], + red, green, blue, + palette[regno]); +} +#endif /* LCD_COLOR8 */ + +/*----------------------------------------------------------------------*/ +#if LCD_BPP == LCD_MONOCHROME +void lcd_initcolregs (void) +{ + struct pxafb_info *fbi = &panel_info.pxa; + cmap = (ushort *)fbi->palette; + ushort regno; + + for (regno = 0; regno < 16; regno++) { + cmap[regno * 2] = 0; + cmap[(regno * 2) + 1] = regno & 0x0f; + } +} +#endif /* LCD_MONOCHROME */ + +/*----------------------------------------------------------------------*/ +void lcd_enable (void) +{ +} + +/*----------------------------------------------------------------------*/ +#ifdef NOT_USED_SO_FAR +static void lcd_disable (void) +{ +} +#endif /* NOT_USED_SO_FAR */ + +/*----------------------------------------------------------------------*/ + +/************************************************************************/ +/* ** PXA255 specific routines */ +/************************************************************************/ + +/* + * Calculate fb size for VIDEOLFB_ATAG. Size returned contains fb, + * descriptors and palette areas. + */ +ulong calc_fbsize (void) +{ + ulong size; + int line_length = (panel_info.vl_col * NBITS (panel_info.vl_bpix)) / 8; + + size = line_length * panel_info.vl_row; + size += PAGE_SIZE; + + return size; +} + +static int pxafb_init_mem (void *lcdbase, vidinfo_t *vid) +{ + u_long palette_mem_size; + struct pxafb_info *fbi = &vid->pxa; + int fb_size = vid->vl_row * (vid->vl_col * NBITS (vid->vl_bpix)) / 8; + + fbi->screen = (u_long)lcdbase; + + fbi->palette_size = NBITS(vid->vl_bpix) == 8 ? 256 : 16; + palette_mem_size = fbi->palette_size * sizeof(u16); + + debug("palette_mem_size = 0x%08lx\n", (u_long) palette_mem_size); + /* locate palette and descs at end of page following fb */ + fbi->palette = (u_long)lcdbase + fb_size + PAGE_SIZE - palette_mem_size; + + return 0; +} + +static void pxafb_setup_gpio (vidinfo_t *vid) +{ + u_long lccr0; + + /* + * setup is based on type of panel supported + */ + + lccr0 = vid->pxa.reg_lccr0; + + /* 4 bit interface */ + if ((lccr0 & LCCR0_CMS) && (lccr0 & LCCR0_SDS) && !(lccr0 & LCCR0_DPD)) + { + debug("Setting GPIO for 4 bit data\n"); + /* bits 58-61 */ + GPDR1 |= (0xf << 26); + GAFR1_U = (GAFR1_U & ~(0xff << 20)) | (0xaa << 20); + + /* bits 74-77 */ + GPDR2 |= (0xf << 10); + GAFR2_L = (GAFR2_L & ~(0xff << 20)) | (0xaa << 20); + } + + /* 8 bit interface */ + else if (((lccr0 & LCCR0_CMS) && ((lccr0 & LCCR0_SDS) || (lccr0 & LCCR0_DPD))) || + (!(lccr0 & LCCR0_CMS) && !(lccr0 & LCCR0_PAS) && !(lccr0 & LCCR0_SDS))) + { + debug("Setting GPIO for 8 bit data\n"); + /* bits 58-65 */ + GPDR1 |= (0x3f << 26); + GPDR2 |= (0x3); + + GAFR1_U = (GAFR1_U & ~(0xfff << 20)) | (0xaaa << 20); + GAFR2_L = (GAFR2_L & ~0xf) | (0xa); + + /* bits 74-77 */ + GPDR2 |= (0xf << 10); + GAFR2_L = (GAFR2_L & ~(0xff << 20)) | (0xaa << 20); + } + + /* 16 bit interface */ + else if (!(lccr0 & LCCR0_CMS) && ((lccr0 & LCCR0_SDS) || (lccr0 & LCCR0_PAS))) + { + debug("Setting GPIO for 16 bit data\n"); + /* bits 58-77 */ + GPDR1 |= (0x3f << 26); + GPDR2 |= 0x00003fff; + + GAFR1_U = (GAFR1_U & ~(0xfff << 20)) | (0xaaa << 20); + GAFR2_L = (GAFR2_L & 0xf0000000) | 0x0aaaaaaa; + } + else + { + printf("pxafb_setup_gpio: unable to determine bits per pixel\n"); + } +} + +static void pxafb_enable_controller (vidinfo_t *vid) +{ + debug("Enabling LCD controller\n"); + + /* Sequence from 11.7.10 */ + LCCR3 = vid->pxa.reg_lccr3; + LCCR2 = vid->pxa.reg_lccr2; + LCCR1 = vid->pxa.reg_lccr1; + LCCR0 = vid->pxa.reg_lccr0 & ~LCCR0_ENB; + FDADR0 = vid->pxa.fdadr0; + FDADR1 = vid->pxa.fdadr1; + LCCR0 |= LCCR0_ENB; + + CKEN |= CKEN16_LCD; + + debug("FDADR0 = 0x%08x\n", (unsigned int)FDADR0); + debug("FDADR1 = 0x%08x\n", (unsigned int)FDADR1); + debug("LCCR0 = 0x%08x\n", (unsigned int)LCCR0); + debug("LCCR1 = 0x%08x\n", (unsigned int)LCCR1); + debug("LCCR2 = 0x%08x\n", (unsigned int)LCCR2); + debug("LCCR3 = 0x%08x\n", (unsigned int)LCCR3); +} + +static int pxafb_init (vidinfo_t *vid) +{ + struct pxafb_info *fbi = &vid->pxa; + + debug("Configuring PXA LCD\n"); + + fbi->reg_lccr0 = REG_LCCR0; + fbi->reg_lccr3 = REG_LCCR3; + + debug("vid: vl_col=%d hslen=%d lm=%d rm=%d\n", + vid->vl_col, vid->vl_hpw, + vid->vl_blw, vid->vl_elw); + debug("vid: vl_row=%d vslen=%d um=%d bm=%d\n", + vid->vl_row, vid->vl_vpw, + vid->vl_bfw, vid->vl_efw); + + fbi->reg_lccr1 = + LCCR1_DisWdth(vid->vl_col) + + LCCR1_HorSnchWdth(vid->vl_hpw) + + LCCR1_BegLnDel(vid->vl_blw) + + LCCR1_EndLnDel(vid->vl_elw); + + fbi->reg_lccr2 = + LCCR2_DisHght(vid->vl_row) + + LCCR2_VrtSnchWdth(vid->vl_vpw) + + LCCR2_BegFrmDel(vid->vl_bfw) + + LCCR2_EndFrmDel(vid->vl_efw); + + fbi->reg_lccr3 = REG_LCCR3 & ~(LCCR3_HSP | LCCR3_VSP); + fbi->reg_lccr3 |= (vid->vl_hsp ? LCCR3_HorSnchL : LCCR3_HorSnchH) + | (vid->vl_vsp ? LCCR3_VrtSnchL : LCCR3_VrtSnchH); + + + /* setup dma descriptors */ + fbi->dmadesc_fblow = (struct pxafb_dma_descriptor *)((unsigned int)fbi->palette - 3*16); + fbi->dmadesc_fbhigh = (struct pxafb_dma_descriptor *)((unsigned int)fbi->palette - 2*16); + fbi->dmadesc_palette = (struct pxafb_dma_descriptor *)((unsigned int)fbi->palette - 1*16); + + #define BYTES_PER_PANEL ((fbi->reg_lccr0 & LCCR0_SDS) ? \ + (vid->vl_col * vid->vl_row * NBITS(vid->vl_bpix) / 8 / 2) : \ + (vid->vl_col * vid->vl_row * NBITS(vid->vl_bpix) / 8)) + + /* populate descriptors */ + fbi->dmadesc_fblow->fdadr = (u_long)fbi->dmadesc_fblow; + fbi->dmadesc_fblow->fsadr = fbi->screen + BYTES_PER_PANEL; + fbi->dmadesc_fblow->fidr = 0; + fbi->dmadesc_fblow->ldcmd = BYTES_PER_PANEL; + + fbi->fdadr1 = (u_long)fbi->dmadesc_fblow; /* only used in dual-panel mode */ + + fbi->dmadesc_fbhigh->fsadr = fbi->screen; + fbi->dmadesc_fbhigh->fidr = 0; + fbi->dmadesc_fbhigh->ldcmd = BYTES_PER_PANEL; + + fbi->dmadesc_palette->fsadr = fbi->palette; + fbi->dmadesc_palette->fidr = 0; + fbi->dmadesc_palette->ldcmd = (fbi->palette_size * 2) | LDCMD_PAL; + + if( NBITS(vid->vl_bpix) < 12) + { + /* assume any mode with <12 bpp is palette driven */ + fbi->dmadesc_palette->fdadr = (u_long)fbi->dmadesc_fbhigh; + fbi->dmadesc_fbhigh->fdadr = (u_long)fbi->dmadesc_palette; + /* flips back and forth between pal and fbhigh */ + fbi->fdadr0 = (u_long)fbi->dmadesc_palette; + } + else + { + /* palette shouldn't be loaded in true-color mode */ + fbi->dmadesc_fbhigh->fdadr = (u_long)fbi->dmadesc_fbhigh; + fbi->fdadr0 = (u_long)fbi->dmadesc_fbhigh; /* no pal just fbhigh */ + } + + debug("fbi->dmadesc_fblow = 0x%lx\n", (u_long)fbi->dmadesc_fblow); + debug("fbi->dmadesc_fbhigh = 0x%lx\n", (u_long)fbi->dmadesc_fbhigh); + debug("fbi->dmadesc_palette = 0x%lx\n", (u_long)fbi->dmadesc_palette); + + debug("fbi->dmadesc_fblow->fdadr = 0x%lx\n", fbi->dmadesc_fblow->fdadr); + debug("fbi->dmadesc_fbhigh->fdadr = 0x%lx\n", fbi->dmadesc_fbhigh->fdadr); + debug("fbi->dmadesc_palette->fdadr = 0x%lx\n", fbi->dmadesc_palette->fdadr); + + debug("fbi->dmadesc_fblow->fsadr = 0x%lx\n", fbi->dmadesc_fblow->fsadr); + debug("fbi->dmadesc_fbhigh->fsadr = 0x%lx\n", fbi->dmadesc_fbhigh->fsadr); + debug("fbi->dmadesc_palette->fsadr = 0x%lx\n", fbi->dmadesc_palette->fsadr); + + debug("fbi->dmadesc_fblow->ldcmd = 0x%lx\n", fbi->dmadesc_fblow->ldcmd); + debug("fbi->dmadesc_fbhigh->ldcmd = 0x%lx\n", fbi->dmadesc_fbhigh->ldcmd); + debug("fbi->dmadesc_palette->ldcmd = 0x%lx\n", fbi->dmadesc_palette->ldcmd); + + return 0; +} + +/************************************************************************/ +/************************************************************************/ + +#endif /* CONFIG_LCD */ diff --git a/arch/arm/cpu/pxa/start.S b/arch/arm/cpu/pxa/start.S new file mode 100644 index 0000000000..63ab0c591a --- /dev/null +++ b/arch/arm/cpu/pxa/start.S @@ -0,0 +1,498 @@ +/* + * armboot - Startup Code for XScale + * + * Copyright (C) 1998 Dan Malek + * Copyright (C) 1999 Magnus Damm + * Copyright (C) 2000 Wolfgang Denk + * Copyright (C) 2001 Alex Zuepke + * Copyright (C) 2002 Kyle Harris + * Copyright (C) 2003 Robert Schwebel + * Copyright (C) 2003 Kai-Uwe Bloem + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +.globl _start +_start: b 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 + +_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 RAM! + * - relocate armboot to RAM + * - setup stack + * - jump to second stage + */ + +_TEXT_BASE: + .word TEXT_BASE + +.globl _armboot_start +_armboot_start: + .word _start + +/* + * These are defined in the board-specific linker script. + */ +.globl _bss_start +_bss_start: + .word __bss_start + +.globl _bss_end +_bss_end: + .word _end + +#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 /* CONFIG_USE_IRQ */ + + +/****************************************************************************/ +/* */ +/* the actual reset code */ +/* */ +/****************************************************************************/ + +reset: + mrs r0,cpsr /* set the CPU to SVC32 mode */ + bic r0,r0,#0x1f /* (superviser mode, M=10011) */ + orr r0,r0,#0x13 + msr cpsr,r0 + + /* + * we do sys-critical inits only at reboot, + * not when booting from RAM! + */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl cpu_init_crit /* we do sys-critical inits */ +#endif /* !CONFIG_SKIP_LOWLEVEL_INIT */ + +#ifndef CONFIG_SKIP_RELOCATE_UBOOT +relocate: /* relocate U-Boot to RAM */ + adr r0, _start /* r0 <- current position of code */ + ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ + cmp r0, r1 /* don't reloc during debug */ + beq stack_setup + + ldr r2, _armboot_start + ldr r3, _bss_start + sub r2, r3, r2 /* r2 <- size of armboot */ + add r2, r0, r2 /* r2 <- source end address */ + +copy_loop: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end address [r2] */ + ble copy_loop +#endif /* !CONFIG_SKIP_RELOCATE_UBOOT */ + + /* Set up the stack */ +stack_setup: + ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ + sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */ + sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ +#ifdef CONFIG_USE_IRQ + sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) +#endif /* CONFIG_USE_IRQ */ + sub sp, r0, #12 /* leave 3 words for abort-stack */ + +clear_bss: + ldr r0, _bss_start /* find start of bss segment */ + ldr r1, _bss_end /* stop here */ + mov r2, #0x00000000 /* clear */ + +clbss_l:str r2, [r0] /* clear loop... */ + add r0, r0, #4 + cmp r0, r1 + ble clbss_l + + ldr pc, _start_armboot + +_start_armboot: .word start_armboot + + +/****************************************************************************/ +/* */ +/* CPU_init_critical registers */ +/* */ +/* - setup important registers */ +/* - setup memory timing */ +/* */ +/****************************************************************************/ +/* mk@tbd: Fix this! */ +#undef RCSR +#undef ICMR +#undef OSMR3 +#undef OSCR +#undef OWER +#undef OIER +#undef CCCR + +/* Interrupt-Controller base address */ +IC_BASE: .word 0x40d00000 +#define ICMR 0x04 + +/* Reset-Controller */ +RST_BASE: .word 0x40f00030 +#define RCSR 0x00 + +/* Operating System Timer */ +OSTIMER_BASE: .word 0x40a00000 +#define OSMR3 0x0C +#define OSCR 0x10 +#define OWER 0x18 +#define OIER 0x1C + +/* Clock Manager Registers */ +#ifdef CONFIG_CPU_MONAHANS +# ifndef CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO +# error "You have to define CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO!!" +# endif /* !CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO */ +# ifndef CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO +# define CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO 0x1 +# endif /* !CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO */ +#else /* !CONFIG_CPU_MONAHANS */ +#ifdef CONFIG_SYS_CPUSPEED +CC_BASE: .word 0x41300000 +#define CCCR 0x00 +cpuspeed: .word CONFIG_SYS_CPUSPEED +#else /* !CONFIG_SYS_CPUSPEED */ +#error "You have to define CONFIG_SYS_CPUSPEED!!" +#endif /* CONFIG_SYS_CPUSPEED */ +#endif /* CONFIG_CPU_MONAHANS */ + + /* takes care the CP15 update has taken place */ + .macro CPWAIT reg + mrc p15,0,\reg,c2,c0,0 + mov \reg,\reg + sub pc,pc,#4 + .endm + +cpu_init_crit: + + /* mask all IRQs */ +#ifndef CONFIG_CPU_MONAHANS + ldr r0, IC_BASE + mov r1, #0x00 + str r1, [r0, #ICMR] +#else /* CONFIG_CPU_MONAHANS */ + /* Step 1 - Enable CP6 permission */ + mrc p15, 0, r1, c15, c1, 0 @ read CPAR + orr r1, r1, #0x40 + mcr p15, 0, r1, c15, c1, 0 + CPWAIT r1 + + /* Step 2 - Mask ICMR & ICMR2 */ + mov r1, #0 + mcr p6, 0, r1, c1, c0, 0 @ ICMR + mcr p6, 0, r1, c7, c0, 0 @ ICMR2 + + /* turn off all clocks but the ones we will definitly require */ + ldr r1, =CKENA + ldr r2, =(CKENA_22_FFUART | CKENA_10_SRAM | CKENA_9_SMC | CKENA_8_DMC) + str r2, [r1] + ldr r1, =CKENB + ldr r2, =(CKENB_6_IRQ) + str r2, [r1] +#endif /* !CONFIG_CPU_MONAHANS */ + + /* set clock speed */ +#ifdef CONFIG_CPU_MONAHANS + ldr r0, =ACCR + ldr r1, =(((CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO<<8) & ACCR_XN_MASK) | (CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO & ACCR_XL_MASK)) + str r1, [r0] +#else /* !CONFIG_CPU_MONAHANS */ +#ifdef CONFIG_SYS_CPUSPEED + ldr r0, CC_BASE + ldr r1, cpuspeed + str r1, [r0, #CCCR] + mov r0, #2 + mcr p14, 0, r0, c6, c0, 0 + +setspeed_done: + +#endif /* CONFIG_SYS_CPUSPEED */ +#endif /* CONFIG_CPU_MONAHANS */ + + /* + * before relocating, we have to setup RAM timing + * because memory timing is board-dependend, you will + * find a lowlevel_init.S in your board directory. + */ + mov ip, lr + bl lowlevel_init + mov lr, ip + + /* Memory interfaces are working. Disable MMU and enable I-cache. */ + /* mk: hmm, this is not in the monahans docs, leave it now but + * check here if it doesn't work :-) */ + + ldr r0, =0x2001 /* enable access to all coproc. */ + mcr p15, 0, r0, c15, c1, 0 + CPWAIT r0 + + mcr p15, 0, r0, c7, c10, 4 /* drain the write & fill buffers */ + CPWAIT r0 + + mcr p15, 0, r0, c7, c7, 0 /* flush Icache, Dcache and BTB */ + CPWAIT r0 + + mcr p15, 0, r0, c8, c7, 0 /* flush instuction and data TLBs */ + CPWAIT r0 + + /* Enable the Icache */ +/* + mrc p15, 0, r0, c1, c0, 0 + orr r0, r0, #0x1800 + mcr p15, 0, r0, c1, c0, 0 + CPWAIT +*/ + mov pc, 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, _armboot_start + sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) + sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack + 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, _armboot_start @ setup our mode stack + sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) + sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort 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 /* !CONFIG_USE_IRQ */ + + .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 /* CONFIG_USE_IRQ */ + +/****************************************************************************/ +/* */ +/* Reset function: the PXA250 doesn't have a reset function, so we have to */ +/* perform a watchdog timeout for a soft reset. */ +/* */ +/****************************************************************************/ + + .align 5 +.globl reset_cpu + + /* FIXME: this code is PXA250 specific. How is this handled on */ + /* other XScale processors? */ + +reset_cpu: + + /* We set OWE:WME (watchdog enable) and wait until timeout happens */ + + ldr r0, OSTIMER_BASE + ldr r1, [r0, #OWER] + orr r1, r1, #0x0001 /* bit0: WME */ + str r1, [r0, #OWER] + + /* OS timer does only wrap every 1165 seconds, so we have to set */ + /* the match register as well. */ + + ldr r1, [r0, #OSCR] /* read OS timer */ + add r1, r1, #0x800 /* let OSMR3 match after */ + add r1, r1, #0x800 /* 4096*(1/3.6864MHz)=1ms */ + str r1, [r0, #OSMR3] + +reset_endless: + + b reset_endless diff --git a/arch/arm/cpu/pxa/timer.c b/arch/arm/cpu/pxa/timer.c new file mode 100644 index 0000000000..8d0f82679b --- /dev/null +++ b/arch/arm/cpu/pxa/timer.c @@ -0,0 +1,128 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +#ifdef CONFIG_USE_IRQ +#error: interrupts not implemented yet +#endif + +#if defined(CONFIG_PXA27X) || defined(CONFIG_CPU_MONAHANS) +#define TIMER_FREQ_HZ 3250000 +#elif defined(CONFIG_PXA250) +#define TIMER_FREQ_HZ 3686400 +#else +#error "Timer frequency unknown - please config PXA CPU type" +#endif + +static inline unsigned long long tick_to_time(unsigned long long tick) +{ + tick *= CONFIG_SYS_HZ; + do_div(tick, TIMER_FREQ_HZ); + return tick; +} + +static inline unsigned long long us_to_tick(unsigned long long us) +{ + us = us * TIMER_FREQ_HZ + 999999; + do_div(us, 1000000); + return us; +} + +int timer_init (void) +{ + reset_timer(); + + return 0; +} + +void reset_timer (void) +{ + reset_timer_masked (); +} + +ulong get_timer (ulong base) +{ + return get_timer_masked () - base; +} + +void set_timer (ulong t) +{ + /* nop */ +} + +void __udelay (unsigned long usec) +{ + udelay_masked (usec); +} + + +void reset_timer_masked (void) +{ + OSCR = 0; +} + +ulong get_timer_masked (void) +{ + return tick_to_time(get_ticks()); +} + +void udelay_masked (unsigned long usec) +{ + unsigned long long tmp; + ulong tmo; + + tmo = us_to_tick(usec); + tmp = get_ticks() + tmo; /* get current timestamp */ + + while (get_ticks() < tmp) /* loop till event */ + /*NOP*/; + +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return OSCR; +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk (void) +{ + ulong tbclk; + tbclk = TIMER_FREQ_HZ; + return tbclk; +} diff --git a/arch/arm/cpu/pxa/u-boot.lds b/arch/arm/cpu/pxa/u-boot.lds new file mode 100644 index 0000000000..d4e85ef550 --- /dev/null +++ b/arch/arm/cpu/pxa/u-boot.lds @@ -0,0 +1,56 @@ +/* + * (C) Copyright 2000-2005 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + arch/arm/cpu/pxa/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = ALIGN(4); + __bss_start = .; + .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } + _end = .; +} diff --git a/arch/arm/cpu/pxa/usb.c b/arch/arm/cpu/pxa/usb.c new file mode 100644 index 0000000000..bd718a6fff --- /dev/null +++ b/arch/arm/cpu/pxa/usb.c @@ -0,0 +1,112 @@ +/* + * (C) Copyright 2006 + * Markus Klotzbuecher, DENX Software Engineering + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +#if defined(CONFIG_USB_OHCI_NEW) && defined(CONFIG_SYS_USB_OHCI_CPU_INIT) +# if defined(CONFIG_CPU_MONAHANS) || defined(CONFIG_PXA27X) + +#include +#include + +int usb_cpu_init(void) +{ +#if defined(CONFIG_CPU_MONAHANS) + /* Enable USB host clock. */ + CKENA |= (CKENA_2_USBHOST | CKENA_20_UDC); + udelay(100); +#endif +#if defined(CONFIG_PXA27X) + /* Enable USB host clock. */ + CKEN |= CKEN10_USBHOST; +#endif + +#if defined(CONFIG_CPU_MONAHANS) + /* Configure Port 2 for Host (USB Client Registers) */ + UP2OCR = 0x3000c; +#endif + + UHCHR |= UHCHR_FHR; + wait_ms(11); + UHCHR &= ~UHCHR_FHR; + + UHCHR |= UHCHR_FSBIR; + while (UHCHR & UHCHR_FSBIR) + udelay(1); + +#if defined(CONFIG_CPU_MONAHANS) + UHCHR &= ~UHCHR_SSEP0; +#endif +#if defined(CONFIG_PXA27X) + UHCHR &= ~UHCHR_SSEP2; +#endif + UHCHR &= ~UHCHR_SSEP1; + UHCHR &= ~UHCHR_SSE; + + return 0; +} + +int usb_cpu_stop(void) +{ + UHCHR |= UHCHR_FHR; + udelay(11); + UHCHR &= ~UHCHR_FHR; + + UHCCOMS |= 1; + udelay(10); + +#if defined(CONFIG_CPU_MONAHANS) + UHCHR |= UHCHR_SSEP0; +#endif +#if defined(CONFIG_PXA27X) + UHCHR |= UHCHR_SSEP2; +#endif + UHCHR |= UHCHR_SSEP1; + UHCHR |= UHCHR_SSE; + + return 0; +} + +int usb_cpu_init_fail(void) +{ + UHCHR |= UHCHR_FHR; + udelay(11); + UHCHR &= ~UHCHR_FHR; + + UHCCOMS |= 1; + udelay(10); + +#if defined(CONFIG_CPU_MONAHANS) + UHCHR |= UHCHR_SSEP0; +#endif +#if defined(CONFIG_PXA27X) + UHCHR |= UHCHR_SSEP2; +#endif + UHCHR |= UHCHR_SSEP1; + UHCHR |= UHCHR_SSE; + + return 0; +} + +# endif /* defined(CONFIG_CPU_MONAHANS) || defined(CONFIG_PXA27X) */ +#endif /* defined(CONFIG_USB_OHCI) && defined(CONFIG_SYS_USB_OHCI_CPU_INIT) */ diff --git a/arch/arm/cpu/s3c44b0/Makefile b/arch/arm/cpu/s3c44b0/Makefile new file mode 100644 index 0000000000..6da2016f66 --- /dev/null +++ b/arch/arm/cpu/s3c44b0/Makefile @@ -0,0 +1,50 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(CPU).a + +START = start.o + +COBJS += cache.o +COBJS += cpu.o +COBJS += timer.o + +SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/s3c44b0/cache.c b/arch/arm/cpu/s3c44b0/cache.c new file mode 100644 index 0000000000..66974f61a6 --- /dev/null +++ b/arch/arm/cpu/s3c44b0/cache.c @@ -0,0 +1,90 @@ +/* + * (C) Copyright 2004 + * DAVE Srl + * http://www.dave-tech.it + * http://www.wawnet.biz + * mailto:info@wawnet.biz + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +static void s3c44b0_flush_cache(void) +{ + volatile int i; + /* flush cycle */ + for(i=0x10002000;i<0x10004800;i+=16) + { + *((int *)i)=0x0; + } +} + +void icache_enable (void) +{ + ulong reg; + + s3c44b0_flush_cache(); + + /* + Init cache + Non-cacheable area (everything outside RAM) + 0x0000:0000 - 0x0C00:0000 + */ + NCACHBE0 = 0xC0000000; + NCACHBE1 = 0x00000000; + + /* + Enable chache + */ + reg = SYSCFG; + reg |= 0x00000006; /* 8kB */ + SYSCFG = reg; +} + +void icache_disable (void) +{ + ulong reg; + + reg = SYSCFG; + reg &= ~0x00000006; /* 8kB */ + SYSCFG = reg; +} + +int icache_status (void) +{ + return 0; +} + +void dcache_enable (void) +{ + icache_enable(); +} + +void dcache_disable (void) +{ + icache_disable(); +} + +int dcache_status (void) +{ + return dcache_status(); +} diff --git a/arch/arm/cpu/s3c44b0/config.mk b/arch/arm/cpu/s3c44b0/config.mk new file mode 100644 index 0000000000..7454d728a5 --- /dev/null +++ b/arch/arm/cpu/s3c44b0/config.mk @@ -0,0 +1,33 @@ +# +# (C) Copyright 2002 +# Sysgo Real-Time Solutions, GmbH +# Marius Groeger +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float + +PLATFORM_CPPFLAGS += -march=armv4 -mtune=arm7tdmi -msoft-float +# ========================================================================= +# +# Supply options according to compiler version +# +# ======================================================================== +PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/arch/arm/cpu/s3c44b0/cpu.c b/arch/arm/cpu/s3c44b0/cpu.c new file mode 100644 index 0000000000..bca38f81d3 --- /dev/null +++ b/arch/arm/cpu/s3c44b0/cpu.c @@ -0,0 +1,74 @@ +/* + * (C) Copyright 2004 + * DAVE Srl + * http://www.dave-tech.it + * http://www.wawnet.biz + * mailto:info@wawnet.biz + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * S3C44B0 CPU specific code + */ + +#include +#include +#include + +int arch_cpu_init (void) +{ + icache_enable(); + + return 0; +} + +int cleanup_before_linux (void) +{ + /* + cache memory should be enabled before calling + Linux to make the kernel uncompression faster + */ + icache_enable(); + + disable_interrupts (); + + return 0; +} + +void reset_cpu (ulong addr) +{ + /* + reset the cpu using watchdog + */ + + /* Disable the watchdog.*/ + WTCON&=~(1<<5); + + /* set the timeout value to a short time... */ + WTCNT = 0x1; + + /* Enable the watchdog. */ + WTCON|=1; + WTCON|=(1<<5); + + while(1) { + /*NOP*/ + } +} diff --git a/arch/arm/cpu/s3c44b0/start.S b/arch/arm/cpu/s3c44b0/start.S new file mode 100644 index 0000000000..f5a3d3ac38 --- /dev/null +++ b/arch/arm/cpu/s3c44b0/start.S @@ -0,0 +1,272 @@ +/* + * Startup Code for S3C44B0 CPU-core + * + * (C) Copyright 2004 + * DAVE Srl + * + * http://www.dave-tech.it + * http://www.wawnet.biz + * mailto:info@wawnet.biz + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + +#include +#include + + +/* + * Jump vector table + */ + + +.globl _start +_start: b reset + add pc, pc, #0x0c000000 + add pc, pc, #0x0c000000 + add pc, pc, #0x0c000000 + add pc, pc, #0x0c000000 + add pc, pc, #0x0c000000 + add pc, pc, #0x0c000000 + add pc, pc, #0x0c000000 + + .balignl 16,0xdeadbeef + + +/* + ************************************************************************* + * + * Startup Code (reset vector) + * + * do important init only if we don't start from memory! + * relocate u-boot to ram + * setup stack + * jump to second stage + * + ************************************************************************* + */ + +_TEXT_BASE: + .word TEXT_BASE + +.globl _armboot_start +_armboot_start: + .word _start + +/* + * These are defined in the board-specific linker script. + */ +.globl _bss_start +_bss_start: + .word __bss_start + +.globl _bss_end +_bss_end: + .word _end + +#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 + + +/* + * the actual reset code + */ + +reset: + /* + * set the cpu to SVC32 mode + */ + mrs r0,cpsr + bic r0,r0,#0x1f + orr r0,r0,#0x13 + msr cpsr,r0 + + /* + * we do sys-critical inits only at reboot, + * not when booting from ram! + */ + +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl cpu_init_crit + /* + * before relocating, we have to setup RAM timing + * because memory timing is board-dependend, you will + * find a lowlevel_init.S in your board directory. + */ + bl lowlevel_init +#endif + +#ifndef CONFIG_SKIP_RELOCATE_UBOOT +relocate: /* relocate U-Boot to RAM */ + adr r0, _start /* r0 <- current position of code */ + ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ + cmp r0, r1 /* don't reloc during debug */ + beq stack_setup + + ldr r2, _armboot_start + ldr r3, _bss_start + sub r2, r3, r2 /* r2 <- size of armboot */ + add r2, r0, r2 /* r2 <- source end address */ + +copy_loop: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end addreee [r2] */ + ble copy_loop + +/* + now copy to sram the interrupt vector +*/ + adr r0, real_vectors + add r2, r0, #1024 + ldr r1, =0x0c000000 + add r1, r1, #0x08 +vector_copy_loop: + ldmia r0!, {r3-r10} + stmia r1!, {r3-r10} + cmp r0, r2 + ble vector_copy_loop +#endif /* CONFIG_SKIP_RELOCATE_UBOOT */ + + /* Set up the stack */ +stack_setup: + ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ + sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */ + sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ +#ifdef CONFIG_USE_IRQ + sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) +#endif + sub sp, r0, #12 /* leave 3 words for abort-stack */ + + ldr pc, _start_armboot + +_start_armboot: .word start_armboot + + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + ************************************************************************* + */ + +#define INTCON (0x01c00000+0x200000) +#define INTMSK (0x01c00000+0x20000c) +#define LOCKTIME (0x01c00000+0x18000c) +#define PLLCON (0x01c00000+0x180000) +#define CLKCON (0x01c00000+0x180004) +#define WTCON (0x01c00000+0x130000) +cpu_init_crit: + /* disable watch dog */ + ldr r0, =WTCON + ldr r1, =0x0 + str r1, [r0] + + /* + * mask all IRQs by clearing all bits in the INTMRs + */ + ldr r1,=INTMSK + ldr r0, =0x03fffeff + str r0, [r1] + + ldr r1, =INTCON + ldr r0, =0x05 + str r0, [r1] + + /* Set Clock Control Register */ + ldr r1, =LOCKTIME + ldrb r0, =800 + strb r0, [r1] + + ldr r1, =PLLCON + +#if CONFIG_S3C44B0_CLOCK_SPEED==66 + ldr r0, =0x34031 /* 66MHz (Quartz=11MHz) */ +#elif CONFIG_S3C44B0_CLOCK_SPEED==75 + ldr r0, =0x610c1 /*B2: Xtal=20mhz Fclk=75MHz */ +#else +# error CONFIG_S3C44B0_CLOCK_SPEED undefined +#endif + + str r0, [r1] + + ldr r1,=CLKCON + ldr r0, =0x7ff8 + str r0, [r1] + + mov pc, lr + + +/*************************************************/ +/* interrupt vectors */ +/*************************************************/ +real_vectors: + b reset + b undefined_instruction + b software_interrupt + b prefetch_abort + b data_abort + b not_used + b irq + b fiq + +/*************************************************/ + +undefined_instruction: + mov r6, #3 + b reset + +software_interrupt: + mov r6, #4 + b reset + +prefetch_abort: + mov r6, #5 + b reset + +data_abort: + mov r6, #6 + b reset + +not_used: + /* we *should* never reach this */ + mov r6, #7 + b reset + +irq: + mov r6, #8 + b reset + +fiq: + mov r6, #9 + b reset diff --git a/arch/arm/cpu/s3c44b0/timer.c b/arch/arm/cpu/s3c44b0/timer.c new file mode 100644 index 0000000000..6f1d8f677a --- /dev/null +++ b/arch/arm/cpu/s3c44b0/timer.c @@ -0,0 +1,136 @@ +/* + * (C) Copyright 2004 + * DAVE Srl + * http://www.dave-tech.it + * http://www.wawnet.biz + * mailto:info@wawnet.biz + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +/* we always count down the max. */ +#define TIMER_LOAD_VAL 0xffff + +/* macro to read the 16 bit timer */ +#define READ_TIMER (TCNTO1 & 0xffff) + +#ifdef CONFIG_USE_IRQ +#error CONFIG_USE_IRQ NOT supported +#endif + +static ulong timestamp; +static ulong lastdec; + +int timer_init (void) +{ + TCFG0 = 0x000000E9; + TCFG1 = 0x00000004; + TCON = 0x00000900; + TCNTB1 = TIMER_LOAD_VAL; + TCMPB1 = 0; + TCON = 0x00000B00; + TCON = 0x00000900; + + + lastdec = TCNTB1 = TIMER_LOAD_VAL; + timestamp = 0; + return 0; +} + +/* + * timer without interrupts + */ + +void reset_timer (void) +{ + reset_timer_masked (); +} + +ulong get_timer (ulong base) +{ + return get_timer_masked () - base; +} + +void set_timer (ulong t) +{ + timestamp = t; +} + +void __udelay (unsigned long usec) +{ + ulong tmo; + + tmo = usec / 1000; + tmo *= CONFIG_SYS_HZ; + tmo /= 8; + + tmo += get_timer (0); + + while (get_timer_masked () < tmo) + /*NOP*/; +} + +void reset_timer_masked (void) +{ + /* reset time */ + lastdec = READ_TIMER; + timestamp = 0; +} + +ulong get_timer_masked (void) +{ + ulong now = READ_TIMER; + + if (lastdec >= now) { + /* normal mode */ + timestamp += lastdec - now; + } else { + /* we have an overflow ... */ + timestamp += lastdec + TIMER_LOAD_VAL - now; + } + lastdec = now; + + return timestamp; +} + +void udelay_masked (unsigned long usec) +{ + ulong tmo; + ulong endtime; + signed long diff; + + if (usec >= 1000) { + tmo = usec / 1000; + tmo *= CONFIG_SYS_HZ; + tmo /= 8; + } else { + tmo = usec * CONFIG_SYS_HZ; + tmo /= (1000*8); + } + + endtime = get_timer(0) + tmo; + + do { + ulong now = get_timer_masked (); + diff = endtime - now; + } while (diff >= 0); +} diff --git a/arch/arm/cpu/s3c44b0/u-boot.lds b/arch/arm/cpu/s3c44b0/u-boot.lds new file mode 100644 index 0000000000..267d94c083 --- /dev/null +++ b/arch/arm/cpu/s3c44b0/u-boot.lds @@ -0,0 +1,56 @@ +/* + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + arch/arm/cpu/s3c44b0/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = ALIGN(4); + __bss_start = .; + .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } + _end = .; +} diff --git a/arch/arm/cpu/sa1100/Makefile b/arch/arm/cpu/sa1100/Makefile new file mode 100644 index 0000000000..28b668267c --- /dev/null +++ b/arch/arm/cpu/sa1100/Makefile @@ -0,0 +1,49 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(CPU).a + +START = start.o + +COBJS += cpu.o +COBJS += timer.o + +SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/sa1100/config.mk b/arch/arm/cpu/sa1100/config.mk new file mode 100644 index 0000000000..6f21f410be --- /dev/null +++ b/arch/arm/cpu/sa1100/config.mk @@ -0,0 +1,33 @@ +# +# (C) Copyright 2002 +# Sysgo Real-Time Solutions, GmbH +# Marius Groeger +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float + +PLATFORM_CPPFLAGS += -march=armv4 -mtune=strongarm1100 +# ========================================================================= +# +# Supply options according to compiler version +# +# ======================================================================== +PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/arch/arm/cpu/sa1100/cpu.c b/arch/arm/cpu/sa1100/cpu.c new file mode 100644 index 0000000000..58e90dc9f6 --- /dev/null +++ b/arch/arm/cpu/sa1100/cpu.c @@ -0,0 +1,70 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * CPU specific code + */ + +#include +#include +#include + +#ifdef CONFIG_USE_IRQ +DECLARE_GLOBAL_DATA_PTR; +#endif + +static void cache_flush(void); + +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)); +} diff --git a/arch/arm/cpu/sa1100/start.S b/arch/arm/cpu/sa1100/start.S new file mode 100644 index 0000000000..278c5008fb --- /dev/null +++ b/arch/arm/cpu/sa1100/start.S @@ -0,0 +1,419 @@ +/* + * armboot - Startup Code for SA1100 CPU + * + * Copyright (C) 1998 Dan Malek + * Copyright (C) 1999 Magnus Damm + * Copyright (C) 2000 Wolfgang Denk + * Copyright (c) 2001 Alex Züpke + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + +#include +#include + + +/* + ************************************************************************* + * + * Jump vector table as in table 3.1 in [1] + * + ************************************************************************* + */ + + +.globl _start +_start: b 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 + +_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 + * + ************************************************************************* + */ + +_TEXT_BASE: + .word TEXT_BASE + +.globl _armboot_start +_armboot_start: + .word _start + +/* + * These are defined in the board-specific linker script. + */ +.globl _bss_start +_bss_start: + .word __bss_start + +.globl _bss_end +_bss_end: + .word _end + +#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 + + +/* + * the actual reset code + */ + +reset: + /* + * set the cpu to SVC32 mode + */ + mrs r0,cpsr + bic r0,r0,#0x1f + orr r0,r0,#0x13 + msr cpsr,r0 + + /* + * we do sys-critical inits only at reboot, + * not when booting from ram! + */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl cpu_init_crit +#endif + +#ifndef CONFIG_SKIP_RELOCATE_UBOOT +relocate: /* relocate U-Boot to RAM */ + adr r0, _start /* r0 <- current position of code */ + ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ + cmp r0, r1 /* don't reloc during debug */ + beq stack_setup + + ldr r2, _armboot_start + ldr r3, _bss_start + sub r2, r3, r2 /* r2 <- size of armboot */ + add r2, r0, r2 /* r2 <- source end address */ + +copy_loop: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end addreee [r2] */ + ble copy_loop +#endif /* CONFIG_SKIP_RELOCATE_UBOOT */ + + /* Set up the stack */ +stack_setup: + ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ + sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */ + sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ +#ifdef CONFIG_USE_IRQ + sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) +#endif + sub sp, r0, #12 /* leave 3 words for abort-stack */ + +clear_bss: + ldr r0, _bss_start /* find start of bss segment */ + ldr r1, _bss_end /* stop here */ + mov r2, #0x00000000 /* clear */ + +clbss_l:str r2, [r0] /* clear loop... */ + add r0, r0, #4 + cmp r0, r1 + ble clbss_l + + ldr pc, _start_armboot + +_start_armboot: .word start_armboot + + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + ************************************************************************* + */ + + +/* Interupt-Controller base address */ +IC_BASE: .word 0x90050000 +#define ICMR 0x04 + + +/* Reset-Controller */ +RST_BASE: .word 0x90030000 +#define RSRR 0x00 +#define RCSR 0x04 + + +/* PWR */ +PWR_BASE: .word 0x90020000 +#define PSPR 0x08 +#define PPCR 0x14 +cpuspeed: .word CONFIG_SYS_CPUSPEED + + +cpu_init_crit: + /* + * mask all IRQs + */ + ldr r0, IC_BASE + mov r1, #0x00 + str r1, [r0, #ICMR] + + /* set clock speed */ + ldr r0, PWR_BASE + ldr r1, cpuspeed + str r1, [r0, #PPCR] + + /* + * before relocating, we have to setup RAM timing + * because memory timing is board-dependend, you will + * find a lowlevel_init.S in your board directory. + */ + mov ip, lr + bl lowlevel_init + mov lr, ip + + /* + * disable MMU stuff and enable I-cache + */ + mrc p15,0,r0,c1,c0 + bic r0, r0, #0x00002000 @ clear bit 13 (X) + bic r0, r0, #0x0000000f @ clear bits 3-0 (WCAM) + orr r0, r0, #0x00001000 @ set bit 12 (I) Icache + orr r0, r0, #0x00000002 @ set bit 2 (A) Align + mcr p15,0,r0,c1,c0 + + /* + * flush v4 I/D caches + */ + mov r0, #0 + mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ + mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ + + mov pc, 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 +#define I_BIT 0x80 + +/* + * use bad_save_user_regs for abort/prefetch/undef/swi ... + * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling + */ + + .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, _armboot_start + sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) + sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack + 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 + + .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, _armboot_start @ setup our mode stack + sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) + sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort 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 + /* someone ought to write a more effiction fiq_save_user_regs */ + irq_save_user_regs + bl do_fiq + 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 + + .align 5 +.globl reset_cpu +reset_cpu: + ldr r0, RST_BASE + mov r1, #0x0 @ set bit 3-0 ... + str r1, [r0, #RCSR] @ ... to clear in RCSR + mov r1, #0x1 + str r1, [r0, #RSRR] @ and perform reset + b reset_cpu @ silly, but repeat endlessly diff --git a/arch/arm/cpu/sa1100/timer.c b/arch/arm/cpu/sa1100/timer.c new file mode 100644 index 0000000000..020750125a --- /dev/null +++ b/arch/arm/cpu/sa1100/timer.c @@ -0,0 +1,110 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +int timer_init (void) +{ + return 0; +} + +void reset_timer (void) +{ + reset_timer_masked (); +} + +ulong get_timer (ulong base) +{ + return get_timer_masked (); +} + +void set_timer (ulong t) +{ + /* nop */ +} + +void __udelay (unsigned long usec) +{ + udelay_masked (usec); +} + + +void reset_timer_masked (void) +{ + OSCR = 0; +} + +ulong get_timer_masked (void) +{ + return OSCR; +} + +void udelay_masked (unsigned long usec) +{ + ulong tmo; + ulong endtime; + signed long diff; + + if (usec >= 1000) { + tmo = usec / 1000; + tmo *= CONFIG_SYS_HZ; + tmo /= 1000; + } else { + tmo = usec * CONFIG_SYS_HZ; + tmo /= (1000*1000); + } + + endtime = get_timer_masked () + tmo; + + do { + ulong now = get_timer_masked (); + diff = endtime - now; + } while (diff >= 0); +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk (void) +{ + ulong tbclk; + + tbclk = CONFIG_SYS_HZ; + return tbclk; +} diff --git a/arch/arm/cpu/sa1100/u-boot.lds b/arch/arm/cpu/sa1100/u-boot.lds new file mode 100644 index 0000000000..f6197acd81 --- /dev/null +++ b/arch/arm/cpu/sa1100/u-boot.lds @@ -0,0 +1,59 @@ +/* + * (C) Copyright 2003-2004 + * MontaVista Software, Inc. + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + arch/arm/cpu/sa1100/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = ALIGN(4); + __bss_start = .; + .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } + _end = .; +} diff --git a/arch/arm/include/asm/arch-mx51/asm-offsets.h b/arch/arm/include/asm/arch-mx51/asm-offsets.h index 3a83fa07a1..fbba412aab 100644 --- a/arch/arm/include/asm/arch-mx51/asm-offsets.h +++ b/arch/arm/include/asm/arch-mx51/asm-offsets.h @@ -1,5 +1,5 @@ /* - * needed for cpu/arm_cortexa8/mx51/lowlevel_init.S + * needed for arch/arm/cpu/arm_cortexa8/mx51/lowlevel_init.S * * These should be auto-generated */ diff --git a/board/actux1/config.mk b/board/actux1/config.mk index 119140d8c3..a0dbe0bc48 100644 --- a/board/actux1/config.mk +++ b/board/actux1/config.mk @@ -1,6 +1,6 @@ TEXT_BASE = 0x00e00000 # include NPE ethernet driver -BOARDLIBS = cpu/ixp/npe/libnpe.a +BOARDLIBS = arch/arm/cpu/ixp/npe/libnpe.a LDSCRIPT := $(SRCTREE)/board/$(BOARDDIR)/u-boot.lds diff --git a/board/actux1/u-boot.lds b/board/actux1/u-boot.lds index 40b5ef3bd1..5c1ece79c8 100644 --- a/board/actux1/u-boot.lds +++ b/board/actux1/u-boot.lds @@ -30,12 +30,12 @@ SECTIONS . = ALIGN (4); .text : { - cpu/ixp/start.o(.text) + arch/arm/cpu/ixp/start.o(.text) lib/string.o(.text) lib/vsprintf.o(.text) arch/arm/lib/board.o(.text) common/dlmalloc.o(.text) - cpu/ixp/cpu.o(.text) + arch/arm/cpu/ixp/cpu.o(.text) . = env_offset; common/env_embedded.o(.ppcenv) * (.text) diff --git a/board/actux2/config.mk b/board/actux2/config.mk index 119140d8c3..a0dbe0bc48 100644 --- a/board/actux2/config.mk +++ b/board/actux2/config.mk @@ -1,6 +1,6 @@ TEXT_BASE = 0x00e00000 # include NPE ethernet driver -BOARDLIBS = cpu/ixp/npe/libnpe.a +BOARDLIBS = arch/arm/cpu/ixp/npe/libnpe.a LDSCRIPT := $(SRCTREE)/board/$(BOARDDIR)/u-boot.lds diff --git a/board/actux2/u-boot.lds b/board/actux2/u-boot.lds index f9ab281bc0..707c027ab5 100644 --- a/board/actux2/u-boot.lds +++ b/board/actux2/u-boot.lds @@ -30,12 +30,12 @@ SECTIONS . = ALIGN (4); .text : { - cpu/ixp/start.o(.text) + arch/arm/cpu/ixp/start.o(.text) lib/string.o(.text) lib/vsprintf.o(.text) arch/arm/lib/board.o(.text) common/dlmalloc.o(.text) - cpu/ixp/cpu.o(.text) + arch/arm/cpu/ixp/cpu.o(.text) . = env_offset; common/env_embedded.o (.ppcenv) diff --git a/board/actux3/config.mk b/board/actux3/config.mk index 119140d8c3..a0dbe0bc48 100644 --- a/board/actux3/config.mk +++ b/board/actux3/config.mk @@ -1,6 +1,6 @@ TEXT_BASE = 0x00e00000 # include NPE ethernet driver -BOARDLIBS = cpu/ixp/npe/libnpe.a +BOARDLIBS = arch/arm/cpu/ixp/npe/libnpe.a LDSCRIPT := $(SRCTREE)/board/$(BOARDDIR)/u-boot.lds diff --git a/board/actux3/u-boot.lds b/board/actux3/u-boot.lds index 2fc3796150..497ab97690 100644 --- a/board/actux3/u-boot.lds +++ b/board/actux3/u-boot.lds @@ -30,12 +30,12 @@ SECTIONS . = ALIGN (4); .text : { - cpu/ixp/start.o (.text) + arch/arm/cpu/ixp/start.o (.text) lib/string.o (.text) lib/vsprintf.o (.text) arch/arm/lib/board.o (.text) common/dlmalloc.o (.text) - cpu/ixp/cpu.o (.text) + arch/arm/cpu/ixp/cpu.o (.text) . = env_offset; common/env_embedded.o (.ppcenv) diff --git a/board/actux4/config.mk b/board/actux4/config.mk index 9a634cdffa..f2b5fc911a 100644 --- a/board/actux4/config.mk +++ b/board/actux4/config.mk @@ -1,4 +1,4 @@ TEXT_BASE = 0x00e00000 # include NPE ethernet driver -BOARDLIBS = cpu/ixp/npe/libnpe.a +BOARDLIBS = arch/arm/cpu/ixp/npe/libnpe.a diff --git a/board/davinci/dvevm/board_init.S b/board/davinci/dvevm/board_init.S index 22d8adc18c..81b23d0436 100644 --- a/board/davinci/dvevm/board_init.S +++ b/board/davinci/dvevm/board_init.S @@ -2,7 +2,7 @@ * Copyright (C) 2007 Sergey Kubushyn * * Board-specific low level initialization code. Called at the very end - * of cpu/arm926ejs/davinci/lowlevel_init.S. Just returns if there is no + * of arch/arm/cpu/arm926ejs/davinci/lowlevel_init.S. Just returns if there is no * initialization required. * * This program is free software; you can redistribute it and/or diff --git a/board/davinci/schmoogie/board_init.S b/board/davinci/schmoogie/board_init.S index 22d8adc18c..81b23d0436 100644 --- a/board/davinci/schmoogie/board_init.S +++ b/board/davinci/schmoogie/board_init.S @@ -2,7 +2,7 @@ * Copyright (C) 2007 Sergey Kubushyn * * Board-specific low level initialization code. Called at the very end - * of cpu/arm926ejs/davinci/lowlevel_init.S. Just returns if there is no + * of arch/arm/cpu/arm926ejs/davinci/lowlevel_init.S. Just returns if there is no * initialization required. * * This program is free software; you can redistribute it and/or diff --git a/board/davinci/sffsdr/board_init.S b/board/davinci/sffsdr/board_init.S index 22d8adc18c..81b23d0436 100644 --- a/board/davinci/sffsdr/board_init.S +++ b/board/davinci/sffsdr/board_init.S @@ -2,7 +2,7 @@ * Copyright (C) 2007 Sergey Kubushyn * * Board-specific low level initialization code. Called at the very end - * of cpu/arm926ejs/davinci/lowlevel_init.S. Just returns if there is no + * of arch/arm/cpu/arm926ejs/davinci/lowlevel_init.S. Just returns if there is no * initialization required. * * This program is free software; you can redistribute it and/or diff --git a/board/davinci/sonata/board_init.S b/board/davinci/sonata/board_init.S index fbb9ea73e9..3e4c7a2c54 100644 --- a/board/davinci/sonata/board_init.S +++ b/board/davinci/sonata/board_init.S @@ -2,7 +2,7 @@ * Copyright (C) 2007 Sergey Kubushyn * * Board-specific low level initialization code. Called at the very end - * of cpu/arm926ejs/davinci/lowlevel_init.S. Just returns if there is no + * of arch/arm/cpu/arm926ejs/davinci/lowlevel_init.S. Just returns if there is no * initialization required. * * For _OLDER_ Sonata boards sets up GPIO4 to control NAND WP line. Newer diff --git a/board/edb93xx/config.mk b/board/edb93xx/config.mk index b2fc6fac31..b627869c25 100644 --- a/board/edb93xx/config.mk +++ b/board/edb93xx/config.mk @@ -1,4 +1,4 @@ -LDSCRIPT := $(SRCTREE)/cpu/arm920t/ep93xx/u-boot.lds +LDSCRIPT := $(SRCTREE)/arch/arm/cpu/arm920t/ep93xx/u-boot.lds ifdef CONFIG_EDB9301 TEXT_BASE = 0x05700000 diff --git a/board/freescale/mx31ads/u-boot.lds b/board/freescale/mx31ads/u-boot.lds index 6f5bda4572..273129457b 100644 --- a/board/freescale/mx31ads/u-boot.lds +++ b/board/freescale/mx31ads/u-boot.lds @@ -37,7 +37,7 @@ SECTIONS /* WARNING - the following is hand-optimized to fit within */ /* the sector layout of our flash chips! XXX FIXME XXX */ - cpu/arm1136/start.o (.text) + arch/arm/cpu/arm1136/start.o (.text) board/freescale/mx31ads/libmx31ads.a (.text) arch/arm/lib/libarm.a (.text) net/libnet.a (.text) diff --git a/board/logicpd/zoom2/zoom2.c b/board/logicpd/zoom2/zoom2.c index 387ed2d396..6455d1dc3c 100644 --- a/board/logicpd/zoom2/zoom2.c +++ b/board/logicpd/zoom2/zoom2.c @@ -46,7 +46,7 @@ /* * This the the zoom2, board specific, gpmc configuration for the * quad uart on the debug board. The more general gpmc configurations - * are setup at the cpu level in cpu/arm_cortexa8/omap3/mem.c + * are setup at the cpu level in arch/arm/cpu/arm_cortexa8/omap3/mem.c * * The details of the setting of the serial gpmc setup are not available. * The values were provided by another party. diff --git a/board/lpc2292sodimm/flash.c b/board/lpc2292sodimm/flash.c index a7e175d8ed..fd5389fb98 100644 --- a/board/lpc2292sodimm/flash.c +++ b/board/lpc2292sodimm/flash.c @@ -1,7 +1,7 @@ /* * (C) Copyright 2006 Embedded Artists AB * - * Modified to use the routines in cpu/arm720t/lpc2292/flash.c by + * Modified to use the routines in arch/arm/cpu/arm720t/lpc2292/flash.c by * Gary Jennejohn * * This program is free software; you can redistribute it and/or diff --git a/board/samsung/smdk6400/u-boot-nand.lds b/board/samsung/smdk6400/u-boot-nand.lds index a074420c15..29a4f61e36 100644 --- a/board/samsung/smdk6400/u-boot-nand.lds +++ b/board/samsung/smdk6400/u-boot-nand.lds @@ -34,8 +34,8 @@ SECTIONS . = ALIGN(4); .text : { - cpu/arm1176/start.o (.text) - cpu/arm1176/s3c64xx/cpu_init.o (.text) + arch/arm/cpu/arm1176/start.o (.text) + arch/arm/cpu/arm1176/s3c64xx/cpu_init.o (.text) *(.text) } diff --git a/board/siemens/SMN42/flash.c b/board/siemens/SMN42/flash.c index 8cf17b8576..fc91574f85 100644 --- a/board/siemens/SMN42/flash.c +++ b/board/siemens/SMN42/flash.c @@ -2,7 +2,7 @@ * (C) Copyright 2006 Embedded Artists AB * * (C) Copyright 2007 Gary Jennejohn garyj@denx.de - * Modified to use the routines in cpu/arm720t/lpc2292/flash.c. + * Modified to use the routines in arch/arm/cpu/arm720t/lpc2292/flash.c. * Heavily modified to support the SMN42 board from Siemens * * This program is free software; you can redistribute it and/or diff --git a/board/trab/rs485.c b/board/trab/rs485.c index ad0c13665e..6a3a4cda9c 100644 --- a/board/trab/rs485.c +++ b/board/trab/rs485.c @@ -2,7 +2,7 @@ * (C) Copyright 2003 * Martin Krause, TQ-Systems GmbH, * - * Based on cpu/arm920t/serial.c, by Gary Jennejohn + * Based on arch/arm/cpu/arm920t/serial.c, by Gary Jennejohn * (C) Copyright 2002 Gary Jennejohn, DENX Software Engineering, * * This program is free software; you can redistribute it and/or modify diff --git a/board/trab/rs485.h b/board/trab/rs485.h index 16d69bbd5c..19e32446c3 100644 --- a/board/trab/rs485.h +++ b/board/trab/rs485.h @@ -2,7 +2,7 @@ * (C) Copyright 2003 * Martin Krause, TQ-Systems GmbH, * - * Based on cpu/arm920t/serial.c, by Gary Jennejohn + * Based on arch/arm/cpu/arm920t/serial.c, by Gary Jennejohn * (C) Copyright 2002 Gary Jennejohn, DENX Software Engineering, * * This program is free software; you can redistribute it and/or modify diff --git a/board/trab/u-boot.lds b/board/trab/u-boot.lds index 05b929f569..cd50e85242 100644 --- a/board/trab/u-boot.lds +++ b/board/trab/u-boot.lds @@ -32,7 +32,7 @@ SECTIONS . = ALIGN(4); .text : { - cpu/arm920t/start.o (.text) + arch/arm/cpu/arm920t/start.o (.text) lib/zlib.o (.text) lib/crc32.o (.text) lib/string.o (.text) diff --git a/cpu/arm1136/Makefile b/cpu/arm1136/Makefile deleted file mode 100644 index 7701b03bbe..0000000000 --- a/cpu/arm1136/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(CPU).a - -START = start.o -COBJS = cpu.o - -SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) -START := $(addprefix $(obj),$(START)) - -all: $(obj).depend $(START) $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/arm1136/config.mk b/cpu/arm1136/config.mk deleted file mode 100644 index 3e685354ab..0000000000 --- a/cpu/arm1136/config.mk +++ /dev/null @@ -1,32 +0,0 @@ -# -# (C) Copyright 2002 -# Gary Jennejohn, DENX Software Engineering, -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# -PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float - -# Make ARMv5 to allow more compilers to work, even though its v6. -PLATFORM_CPPFLAGS += -march=armv5 -# ========================================================================= -# -# Supply options according to compiler version -# -# ========================================================================= -PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/arm1136/cpu.c b/cpu/arm1136/cpu.c deleted file mode 100644 index ade7f46800..0000000000 --- a/cpu/arm1136/cpu.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * (C) Copyright 2004 Texas Insturments - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * CPU specific code - */ - -#include -#include -#include - -static void cache_flush(void); - -int cleanup_before_linux (void) -{ - /* - * this function is called just before we call linux - * it prepares the processor for linux - * - * we turn off caches etc ... - */ - - disable_interrupts (); - -#ifdef CONFIG_LCD - { - extern void lcd_disable(void); - extern void lcd_panel_disable(void); - - lcd_disable(); /* proper disable of lcd & panel */ - lcd_panel_disable(); - } -#endif - - /* turn off I/D-cache */ - icache_disable(); - dcache_disable(); - /* flush I/D-cache */ - cache_flush(); - - return 0; -} - -static void cache_flush(void) -{ - unsigned long i = 0; - - asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); /* invalidate both caches and flush btb */ - asm ("mcr p15, 0, %0, c7, c10, 4": :"r" (i)); /* mem barrier to sync things */ -} diff --git a/cpu/arm1136/mx31/Makefile b/cpu/arm1136/mx31/Makefile deleted file mode 100644 index c8e18f7f02..0000000000 --- a/cpu/arm1136/mx31/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(SOC).a - -COBJS += generic.o -COBJS += timer.o -COBJS += devices.o - -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) - -all: $(obj).depend $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/arm1136/mx31/devices.c b/cpu/arm1136/mx31/devices.c deleted file mode 100644 index 1f4ca7eb44..0000000000 --- a/cpu/arm1136/mx31/devices.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * - * (C) Copyright 2009 Magnus Lilja - * - * (c) 2007 Pengutronix, Sascha Hauer - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -#ifdef CONFIG_SYS_MX31_UART1 -void mx31_uart1_hw_init(void) -{ - /* setup pins for UART1 */ - mx31_gpio_mux(MUX_RXD1__UART1_RXD_MUX); - mx31_gpio_mux(MUX_TXD1__UART1_TXD_MUX); - mx31_gpio_mux(MUX_RTS1__UART1_RTS_B); - mx31_gpio_mux(MUX_CTS1__UART1_CTS_B); -} -#endif - -#ifdef CONFIG_MXC_SPI -void mx31_spi2_hw_init(void) -{ - /* SPI2 */ - mx31_gpio_mux(MUX_CSPI2_SS2__CSPI2_SS2_B); - mx31_gpio_mux(MUX_CSPI2_SCLK__CSPI2_CLK); - mx31_gpio_mux(MUX_CSPI2_SPI_RDY__CSPI2_DATAREADY_B); - mx31_gpio_mux(MUX_CSPI2_MOSI__CSPI2_MOSI); - mx31_gpio_mux(MUX_CSPI2_MISO__CSPI2_MISO); - mx31_gpio_mux(MUX_CSPI2_SS0__CSPI2_SS0_B); - mx31_gpio_mux(MUX_CSPI2_SS1__CSPI2_SS1_B); - - /* start SPI2 clock */ - __REG(CCM_CGR2) = __REG(CCM_CGR2) | (3 << 4); -} -#endif diff --git a/cpu/arm1136/mx31/generic.c b/cpu/arm1136/mx31/generic.c deleted file mode 100644 index 1415d6c2ae..0000000000 --- a/cpu/arm1136/mx31/generic.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * (C) Copyright 2007 - * Sascha Hauer, Pengutronix - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include - -static u32 mx31_decode_pll(u32 reg, u32 infreq) -{ - u32 mfi = (reg >> 10) & 0xf; - u32 mfn = reg & 0x3ff; - u32 mfd = (reg >> 16) & 0x3ff; - u32 pd = (reg >> 26) & 0xf; - - mfi = mfi <= 5 ? 5 : mfi; - mfd += 1; - pd += 1; - - return ((2 * (infreq >> 10) * (mfi * mfd + mfn)) / - (mfd * pd)) << 10; -} - -static u32 mx31_get_mpl_dpdgck_clk(void) -{ - u32 infreq; - - if ((__REG(CCM_CCMR) & CCMR_PRCS_MASK) == CCMR_FPM) - infreq = CONFIG_MX31_CLK32 * 1024; - else - infreq = CONFIG_MX31_HCLK_FREQ; - - return mx31_decode_pll(__REG(CCM_MPCTL), infreq); -} - -static u32 mx31_get_mcu_main_clk(void) -{ - /* For now we assume mpl_dpdgck_clk == mcu_main_clk - * which should be correct for most boards - */ - return mx31_get_mpl_dpdgck_clk(); -} - -u32 mx31_get_ipg_clk(void) -{ - u32 freq = mx31_get_mcu_main_clk(); - u32 pdr0 = __REG(CCM_PDR0); - - freq /= ((pdr0 >> 3) & 0x7) + 1; - freq /= ((pdr0 >> 6) & 0x3) + 1; - - return freq; -} - -void mx31_dump_clocks(void) -{ - u32 cpufreq = mx31_get_mcu_main_clk(); - printf("mx31 cpu clock: %dMHz\n",cpufreq / 1000000); - printf("ipg clock : %dHz\n", mx31_get_ipg_clk()); -} - -void mx31_gpio_mux(unsigned long mode) -{ - unsigned long reg, shift, tmp; - - reg = IOMUXC_BASE + (mode & 0x1fc); - shift = (~mode & 0x3) * 8; - - tmp = __REG(reg); - tmp &= ~(0xff << shift); - tmp |= ((mode >> IOMUX_MODE_POS) & 0xff) << shift; - __REG(reg) = tmp; -} - -#if defined(CONFIG_DISPLAY_CPUINFO) -int print_cpuinfo (void) -{ - printf("CPU: Freescale i.MX31 at %d MHz\n", - mx31_get_mcu_main_clk() / 1000000); - return 0; -} -#endif diff --git a/cpu/arm1136/mx31/timer.c b/cpu/arm1136/mx31/timer.c deleted file mode 100644 index 7972ba0dd7..0000000000 --- a/cpu/arm1136/mx31/timer.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * (C) Copyright 2007 - * Sascha Hauer, Pengutronix - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -#define TIMER_BASE 0x53f90000 /* General purpose timer 1 */ - -/* General purpose timers registers */ -#define GPTCR __REG(TIMER_BASE) /* Control register */ -#define GPTPR __REG(TIMER_BASE + 0x4) /* Prescaler register */ -#define GPTSR __REG(TIMER_BASE + 0x8) /* Status register */ -#define GPTCNT __REG(TIMER_BASE + 0x24) /* Counter register */ - -/* General purpose timers bitfields */ -#define GPTCR_SWR (1 << 15) /* Software reset */ -#define GPTCR_FRR (1 << 9) /* Freerun / restart */ -#define GPTCR_CLKSOURCE_32 (4 << 6) /* Clock source */ -#define GPTCR_TEN 1 /* Timer enable */ - -static ulong timestamp; -static ulong lastinc; - -/* "time" is measured in 1 / CONFIG_SYS_HZ seconds, "tick" is internal timer period */ -#ifdef CONFIG_MX31_TIMER_HIGH_PRECISION -/* ~0.4% error - measured with stop-watch on 100s boot-delay */ -static inline unsigned long long tick_to_time(unsigned long long tick) -{ - tick *= CONFIG_SYS_HZ; - do_div(tick, CONFIG_MX31_CLK32); - return tick; -} - -static inline unsigned long long time_to_tick(unsigned long long time) -{ - time *= CONFIG_MX31_CLK32; - do_div(time, CONFIG_SYS_HZ); - return time; -} - -static inline unsigned long long us_to_tick(unsigned long long us) -{ - us = us * CONFIG_MX31_CLK32 + 999999; - do_div(us, 1000000); - return us; -} -#else -/* ~2% error */ -#define TICK_PER_TIME ((CONFIG_MX31_CLK32 + CONFIG_SYS_HZ / 2) / CONFIG_SYS_HZ) -#define US_PER_TICK (1000000 / CONFIG_MX31_CLK32) - -static inline unsigned long long tick_to_time(unsigned long long tick) -{ - do_div(tick, TICK_PER_TIME); - return tick; -} - -static inline unsigned long long time_to_tick(unsigned long long time) -{ - return time * TICK_PER_TIME; -} - -static inline unsigned long long us_to_tick(unsigned long long us) -{ - us += US_PER_TICK - 1; - do_div(us, US_PER_TICK); - return us; -} -#endif - -/* The 32768Hz 32-bit timer overruns in 131072 seconds */ -int timer_init (void) -{ - int i; - - /* setup GP Timer 1 */ - GPTCR = GPTCR_SWR; - for (i = 0; i < 100; i++) - GPTCR = 0; /* We have no udelay by now */ - GPTPR = 0; /* 32Khz */ - /* Freerun Mode, PERCLK1 input */ - GPTCR |= GPTCR_CLKSOURCE_32 | GPTCR_TEN; - - return 0; -} - -void reset_timer_masked (void) -{ - /* reset time */ - lastinc = GPTCNT; /* capture current incrementer value time */ - timestamp = 0; /* start "advancing" time stamp from 0 */ -} - -void reset_timer(void) -{ - reset_timer_masked(); -} - -unsigned long long get_ticks (void) -{ - ulong now = GPTCNT; /* current tick value */ - - if (now >= lastinc) /* normal mode (non roll) */ - /* move stamp forward with absolut diff ticks */ - timestamp += (now - lastinc); - else /* we have rollover of incrementer */ - timestamp += (0xFFFFFFFF - lastinc) + now; - lastinc = now; - return timestamp; -} - -ulong get_timer_masked (void) -{ - /* - * get_ticks() returns a long long (64 bit), it wraps in - * 2^64 / CONFIG_MX31_CLK32 = 2^64 / 2^15 = 2^49 ~ 5 * 10^14 (s) ~ - * 5 * 10^9 days... and get_ticks() * CONFIG_SYS_HZ wraps in - * 5 * 10^6 days - long enough. - */ - return tick_to_time(get_ticks()); -} - -ulong get_timer (ulong base) -{ - return get_timer_masked () - base; -} - -void set_timer (ulong t) -{ - timestamp = time_to_tick(t); -} - -/* delay x useconds AND perserve advance timstamp value */ -void __udelay (unsigned long usec) -{ - unsigned long long tmp; - ulong tmo; - - tmo = us_to_tick(usec); - tmp = get_ticks() + tmo; /* get current timestamp */ - - while (get_ticks() < tmp) /* loop till event */ - /*NOP*/; -} - -void reset_cpu (ulong addr) -{ - __REG16(WDOG_BASE) = 4; -} diff --git a/cpu/arm1136/omap24xx/Makefile b/cpu/arm1136/omap24xx/Makefile deleted file mode 100644 index 48dc7e3283..0000000000 --- a/cpu/arm1136/omap24xx/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(SOC).a - -SOBJS = reset.o - -COBJS = timer.o - -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) - -all: $(obj).depend $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/arm1136/omap24xx/reset.S b/cpu/arm1136/omap24xx/reset.S deleted file mode 100644 index 5f8343fe62..0000000000 --- a/cpu/arm1136/omap24xx/reset.S +++ /dev/null @@ -1,42 +0,0 @@ -/* - * armboot - Startup Code for OMP2420/ARM1136 CPU-core - * - * Copyright (c) 2004 Texas Instruments - * - * Copyright (c) 2001 Marius Gröger - * Copyright (c) 2002 Alex Züpke - * Copyright (c) 2002 Gary Jennejohn - * Copyright (c) 2003 Richard Woodruff - * Copyright (c) 2003 Kshitij - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include - -.globl reset_cpu -reset_cpu: - ldr r1, rstctl /* get addr for global reset reg */ - mov r3, #0x2 /* full reset pll+mpu */ - str r3, [r1] /* force reset */ - mov r0, r0 -_loop_forever: - b _loop_forever -rstctl: - .word PM_RSTCTRL_WKUP diff --git a/cpu/arm1136/omap24xx/timer.c b/cpu/arm1136/omap24xx/timer.c deleted file mode 100644 index 67547490fd..0000000000 --- a/cpu/arm1136/omap24xx/timer.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * (C) Copyright 2004 - * Texas Instruments - * Richard Woodruff - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * Alex Zuepke - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -#define TIMER_LOAD_VAL 0 - -/* macro to read the 32 bit timer */ -#define READ_TIMER (*((volatile ulong *)(CONFIG_SYS_TIMERBASE+TCRR))) - -static ulong timestamp; -static ulong lastinc; - -int timer_init (void) -{ - int32_t val; - - /* Start the counter ticking up */ - *((int32_t *) (CONFIG_SYS_TIMERBASE + TLDR)) = TIMER_LOAD_VAL; /* reload value on overflow*/ - val = (CONFIG_SYS_PTV << 2) | BIT5 | BIT1 | BIT0; /* mask to enable timer*/ - *((int32_t *) (CONFIG_SYS_TIMERBASE + TCLR)) = val; /* start timer */ - - reset_timer_masked(); /* init the timestamp and lastinc value */ - - return(0); -} -/* - * timer without interrupts - */ -void reset_timer (void) -{ - reset_timer_masked (); -} - -ulong get_timer (ulong base) -{ - return get_timer_masked () - base; -} - -void set_timer (ulong t) -{ - timestamp = t; -} - -/* delay x useconds AND perserve advance timstamp value */ -void __udelay (unsigned long usec) -{ - ulong tmo, tmp; - - if (usec >= 1000) { /* if "big" number, spread normalization to seconds */ - tmo = usec / 1000; /* start to normalize for usec to ticks per sec */ - tmo *= CONFIG_SYS_HZ; /* find number of "ticks" to wait to achieve target */ - tmo /= 1000; /* finish normalize. */ - } else { /* else small number, don't kill it prior to HZ multiply */ - tmo = usec * CONFIG_SYS_HZ; - tmo /= (1000*1000); - } - - tmp = get_timer (0); /* get current timestamp */ - if ( (tmo + tmp + 1) < tmp )/* if setting this forward will roll time stamp */ - reset_timer_masked (); /* reset "advancing" timestamp to 0, set lastinc value */ - else - tmo += tmp; /* else, set advancing stamp wake up time */ - while (get_timer_masked () < tmo)/* loop till event */ - /*NOP*/; -} - -void reset_timer_masked (void) -{ - /* reset time */ - lastinc = READ_TIMER; /* capture current incrementer value time */ - timestamp = 0; /* start "advancing" time stamp from 0 */ -} - -ulong get_timer_masked (void) -{ - ulong now = READ_TIMER; /* current tick value */ - - if (now >= lastinc) /* normal mode (non roll) */ - timestamp += (now - lastinc); /* move stamp fordward with absoulte diff ticks */ - else /* we have rollover of incrementer */ - timestamp += (0xFFFFFFFF - lastinc) + now; - lastinc = now; - return timestamp; -} - -/* waits specified delay value and resets timestamp */ -void udelay_masked (unsigned long usec) -{ - ulong tmo; - ulong endtime; - signed long diff; - - if (usec >= 1000) { /* if "big" number, spread normalization to seconds */ - tmo = usec / 1000; /* start to normalize for usec to ticks per sec */ - tmo *= CONFIG_SYS_HZ; /* find number of "ticks" to wait to achieve target */ - tmo /= 1000; /* finish normalize. */ - } else { /* else small number, don't kill it prior to HZ multiply */ - tmo = usec * CONFIG_SYS_HZ; - tmo /= (1000*1000); - } - endtime = get_timer_masked () + tmo; - - do { - ulong now = get_timer_masked (); - diff = endtime - now; - } while (diff >= 0); -} - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return get_timer(0); -} -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk (void) -{ - ulong tbclk; - tbclk = CONFIG_SYS_HZ; - return tbclk; -} diff --git a/cpu/arm1136/start.S b/cpu/arm1136/start.S deleted file mode 100644 index 957f4389b2..0000000000 --- a/cpu/arm1136/start.S +++ /dev/null @@ -1,443 +0,0 @@ -/* - * armboot - Startup Code for OMP2420/ARM1136 CPU-core - * - * Copyright (c) 2004 Texas Instruments - * - * Copyright (c) 2001 Marius Gröger - * Copyright (c) 2002 Alex Züpke - * Copyright (c) 2002 Gary Jennejohn - * Copyright (c) 2003 Richard Woodruff - * Copyright (c) 2003 Kshitij - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -.globl _start -_start: b reset -#ifdef CONFIG_PRELOADER - ldr pc, _hang - ldr pc, _hang - ldr pc, _hang - ldr pc, _hang - ldr pc, _hang - ldr pc, _hang - ldr pc, _hang - -_hang: - .word do_hang - .word 0x12345678 - .word 0x12345678 - .word 0x12345678 - .word 0x12345678 - .word 0x12345678 - .word 0x12345678 - .word 0x12345678 /* now 16*4=64 */ -#else - 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 - -_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 -_pad: .word 0x12345678 /* now 16*4=64 */ -#endif /* CONFIG_PRELOADER */ -.global _end_vect -_end_vect: - - .balignl 16,0xdeadbeef -/* - ************************************************************************* - * - * Startup Code (reset vector) - * - * do important init only if we don't start from memory! - * setup Memory and board specific bits prior to relocation. - * relocate armboot to ram - * setup stack - * - ************************************************************************* - */ - -_TEXT_BASE: - .word TEXT_BASE - -.globl _armboot_start -_armboot_start: - .word _start - -/* - * These are defined in the board-specific linker script. - */ -.globl _bss_start -_bss_start: - .word __bss_start - -.globl _bss_end -_bss_end: - .word _end - -#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 - -/* - * the actual reset code - */ - -reset: - /* - * set the cpu to SVC32 mode - */ - mrs r0,cpsr - bic r0,r0,#0x1f - orr r0,r0,#0xd3 - msr cpsr,r0 - -#ifdef CONFIG_OMAP2420H4 - /* Copy vectors to mask ROM indirect addr */ - adr r0, _start /* r0 <- current position of code */ - add r0, r0, #4 /* skip reset vector */ - mov r2, #64 /* r2 <- size to copy */ - add r2, r0, r2 /* r2 <- source end address */ - mov r1, #SRAM_OFFSET0 /* build vect addr */ - mov r3, #SRAM_OFFSET1 - add r1, r1, r3 - mov r3, #SRAM_OFFSET2 - add r1, r1, r3 -next: - ldmia r0!, {r3-r10} /* copy from source address [r0] */ - stmia r1!, {r3-r10} /* copy to target address [r1] */ - cmp r0, r2 /* until source end address [r2] */ - bne next /* loop until equal */ - bl cpy_clk_code /* put dpll adjust code behind vectors */ -#endif - /* the mask ROM code should have PLL and others stable */ -#ifndef CONFIG_SKIP_LOWLEVEL_INIT - bl cpu_init_crit -#endif - -#ifndef CONFIG_SKIP_RELOCATE_UBOOT -relocate: /* relocate U-Boot to RAM */ - adr r0, _start /* r0 <- current position of code */ - ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ - cmp r0, r1 /* don't reloc during debug */ -#ifndef CONFIG_PRELOADER - beq stack_setup -#endif /* CONFIG_PRELOADER */ - - ldr r2, _armboot_start - ldr r3, _bss_start - sub r2, r3, r2 /* r2 <- size of armboot */ - add r2, r0, r2 /* r2 <- source end address */ - -copy_loop: - ldmia r0!, {r3-r10} /* copy from source address [r0] */ - stmia r1!, {r3-r10} /* copy to target address [r1] */ - cmp r0, r2 /* until source end addreee [r2] */ - ble copy_loop -#endif /* CONFIG_SKIP_RELOCATE_UBOOT */ - - /* Set up the stack */ -stack_setup: - ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ -#ifdef CONFIG_PRELOADER - sub sp, r0, #128 /* leave 32 words for abort-stack */ -#else - sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */ - sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ -#ifdef CONFIG_USE_IRQ - sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) -#endif - sub sp, r0, #12 /* leave 3 words for abort-stack */ -#endif /* CONFIG_PRELOADER */ - -clear_bss: - ldr r0, _bss_start /* find start of bss segment */ - ldr r1, _bss_end /* stop here */ - mov r2, #0x00000000 /* clear */ - -#ifndef CONFIG_PRELOADER -clbss_l:str r2, [r0] /* clear loop... */ - add r0, r0, #4 - cmp r0, r1 - bne clbss_l -#endif - - ldr pc, _start_armboot - -#ifdef CONFIG_NAND_SPL -_start_armboot: .word nand_boot -#else -#ifdef CONFIG_ONENAND_IPL -_start_armboot: .word start_oneboot -#else -_start_armboot: .word start_armboot -#endif /* CONFIG_ONENAND_IPL */ -#endif /* CONFIG_NAND_SPL */ - -/* - ************************************************************************* - * - * CPU_init_critical registers - * - * setup important registers - * setup memory timing - * - ************************************************************************* - */ -#ifndef CONFIG_SKIP_LOWLEVEL_INIT -cpu_init_crit: - /* - * flush v4 I/D caches - */ - mov r0, #0 - mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ - mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ - - /* - * disable MMU stuff and caches - */ - mrc p15, 0, r0, c1, c0, 0 - bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) - bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) - orr r0, r0, #0x00000002 @ set bit 2 (A) Align - orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache - mcr p15, 0, r0, c1, c0, 0 - - /* - * Jump to board specific initialization... The Mask ROM will have already initialized - * basic memory. Go here to bump up clock rate and handle wake up conditions. - */ - mov ip, lr /* persevere link reg across call */ - bl lowlevel_init /* go setup pll,mux,memory */ - mov lr, ip /* restore link */ - mov pc, lr /* back to my caller */ -#endif /* CONFIG_SKIP_LOWLEVEL_INIT */ - -#ifndef CONFIG_PRELOADER -/* - ************************************************************************* - * - * 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 -#define I_BIT 0x80 - -/* - * use bad_save_user_regs for abort/prefetch/undef/swi ... - * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling - */ - - .macro bad_save_user_regs - sub sp, sp, #S_FRAME_SIZE @ carve out a frame on current user stack - stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12 - - ldr r2, _armboot_start - sub r2, r2, #(CONFIG_SYS_MALLOC_LEN) - sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack - ldmia r2, {r2 - r3} @ get values for "aborted" pc and cpsr (into parm regs) - add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack - - add r5, sp, #S_SP - mov r1, lr - stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr - mov r0, sp @ save current stack into r0 (param register) - .endm - - .macro irq_save_user_regs - sub sp, sp, #S_FRAME_SIZE - stmia sp, {r0 - r12} @ Calling r0-r12 - add r8, sp, #S_PC @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good. - 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, _armboot_start @ setup our mode stack (enter in banked mode) - sub r13, r13, #(CONFIG_SYS_MALLOC_LEN) @ move past malloc pool - sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ move to reserved a couple spots for abort stack - - str lr, [r13] @ save caller lr in position 0 of saved stack - mrs lr, spsr @ get the spsr - str lr, [r13, #4] @ save spsr in position 1 of saved stack - - mov r13, #MODE_SVC @ prepare SVC-Mode - @ msr spsr_c, r13 - msr spsr, r13 @ switch modes, make sure moves will execute - mov lr, pc @ capture return pc - movs pc, lr @ jump to next instruction & switch modes. - .endm - - .macro get_bad_stack_swi - sub r13, r13, #4 @ space on current stack for scratch reg. - str r0, [r13] @ save R0's value. - ldr r0, _armboot_start @ get data regions start - sub r0, r0, #(CONFIG_SYS_MALLOC_LEN) @ move past malloc pool - sub r0, r0, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ move past gbl and a couple spots for abort stack - str lr, [r0] @ save caller lr in position 0 of saved stack - mrs r0, spsr @ get the spsr - str lr, [r0, #4] @ save spsr in position 1 of saved stack - ldr r0, [r13] @ restore r0 - add r13, r13, #4 @ pop stack entry - .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 -#endif /* CONFIG_PRELOADER */ - -/* - * exception handlers - */ -#ifdef CONFIG_PRELOADER - .align 5 -do_hang: - ldr sp, _TEXT_BASE /* use 32 words about stack */ - bl hang /* hang and never return */ -#else /* !CONFIG_PRELOADER */ - .align 5 -undefined_instruction: - get_bad_stack - bad_save_user_regs - bl do_undefined_instruction - - .align 5 -software_interrupt: - get_bad_stack_swi - 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 - /* someone ought to write a more effiction fiq_save_user_regs */ - irq_save_user_regs - bl do_fiq - 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 - .align 5 -.global arm1136_cache_flush -arm1136_cache_flush: - mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache - mov pc, lr @ back to caller -#endif /* CONFIG_PRELOADER */ diff --git a/cpu/arm1136/u-boot.lds b/cpu/arm1136/u-boot.lds deleted file mode 100644 index 7181a569ea..0000000000 --- a/cpu/arm1136/u-boot.lds +++ /dev/null @@ -1,64 +0,0 @@ -/* - * (C) Copyright 2009 - * Ilya Yanok, Emcraft Systems Ltd, - * - * Copyright (C) 2005-2007 Samsung Electronics - * Kyungin Park - * - * Copyright (c) 2004 Texas Instruments - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -ENTRY(_start) -SECTIONS -{ - . = 0x00000000; - - . = ALIGN(4); - .text : - { - cpu/arm1136/start.o (.text) - *(.text) - } - - . = ALIGN(4); - .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } - - . = ALIGN(4); - .data : { *(.data) } - - . = ALIGN(4); - .got : { *(.got) } - - . = .; - __u_boot_cmd_start = .; - .u_boot_cmd : { *(.u_boot_cmd) } - __u_boot_cmd_end = .; - - . = ALIGN(4); - __bss_start = .; - .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } - _end = .; -} diff --git a/cpu/arm1176/Makefile b/cpu/arm1176/Makefile deleted file mode 100644 index 1ca9199a64..0000000000 --- a/cpu/arm1176/Makefile +++ /dev/null @@ -1,50 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# (C) Copyright 2008 -# Guennadi Liakhovetki, DENX Software Engineering, -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(CPU).a - -START = start.o -COBJS = cpu.o - -SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) -START := $(addprefix $(obj),$(START)) - -all: $(obj).depend $(START) $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/arm1176/config.mk b/cpu/arm1176/config.mk deleted file mode 100644 index 14346cfff3..0000000000 --- a/cpu/arm1176/config.mk +++ /dev/null @@ -1,32 +0,0 @@ -# -# (C) Copyright 2002 -# Gary Jennejohn, DENX Software Engineering, -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# -PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float - -# Make ARMv5 to allow more compilers to work, even though its v6. -PLATFORM_CPPFLAGS += -march=armv5t -# ========================================================================= -# -# Supply options according to compiler version -# -# ========================================================================= -PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/arm1176/cpu.c b/cpu/arm1176/cpu.c deleted file mode 100644 index befa0cdcc4..0000000000 --- a/cpu/arm1176/cpu.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * (C) Copyright 2004 Texas Insturments - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * CPU specific code - */ - -#include -#include -#ifdef CONFIG_S3C64XX -#include -#endif -#include - -static void cache_flush (void); - -int cleanup_before_linux (void) -{ - /* - * this function is called just before we call linux - * it prepares the processor for linux - * - * we turn off caches etc ... - */ - - disable_interrupts (); - - /* turn off I/D-cache */ - icache_disable(); - dcache_disable(); - /* flush I/D-cache */ - cache_flush(); - - return 0; -} - -/* flush I/D-cache */ -static void cache_flush (void) -{ - /* invalidate both caches and flush btb */ - asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (0)); - /* mem barrier to sync things */ - asm ("mcr p15, 0, %0, c7, c10, 4": :"r" (0)); -} diff --git a/cpu/arm1176/s3c64xx/Makefile b/cpu/arm1176/s3c64xx/Makefile deleted file mode 100644 index b527939137..0000000000 --- a/cpu/arm1176/s3c64xx/Makefile +++ /dev/null @@ -1,50 +0,0 @@ -# -# (C) Copyright 2000-2003 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# (C) Copyright 2008 -# Guennadi Liakhovetki, DENX Software Engineering, -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(SOC).a - -SOBJS = reset.o - -COBJS-$(CONFIG_S3C6400) += cpu_init.o speed.o -COBJS-y += timer.o - -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y)) - -all: $(obj).depend $(START) $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/arm1176/s3c64xx/config.mk b/cpu/arm1176/s3c64xx/config.mk deleted file mode 100644 index 14346cfff3..0000000000 --- a/cpu/arm1176/s3c64xx/config.mk +++ /dev/null @@ -1,32 +0,0 @@ -# -# (C) Copyright 2002 -# Gary Jennejohn, DENX Software Engineering, -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# -PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float - -# Make ARMv5 to allow more compilers to work, even though its v6. -PLATFORM_CPPFLAGS += -march=armv5t -# ========================================================================= -# -# Supply options according to compiler version -# -# ========================================================================= -PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/arm1176/s3c64xx/cpu_init.S b/cpu/arm1176/s3c64xx/cpu_init.S deleted file mode 100644 index df88cba342..0000000000 --- a/cpu/arm1176/s3c64xx/cpu_init.S +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Originates from Samsung's u-boot 1.1.6 port to S3C6400 / SMDK6400 - * - * Copyright (C) 2008 - * Guennadi Liakhovetki, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include - - .globl mem_ctrl_asm_init -mem_ctrl_asm_init: - /* DMC1 base address 0x7e001000 */ - ldr r0, =ELFIN_DMC1_BASE - - ldr r1, =0x4 - str r1, [r0, #INDEX_DMC_MEMC_CMD] - - ldr r1, =DMC_DDR_REFRESH_PRD - str r1, [r0, #INDEX_DMC_REFRESH_PRD] - - ldr r1, =DMC_DDR_CAS_LATENCY - str r1, [r0, #INDEX_DMC_CAS_LATENCY] - - ldr r1, =DMC_DDR_t_DQSS - str r1, [r0, #INDEX_DMC_T_DQSS] - - ldr r1, =DMC_DDR_t_MRD - str r1, [r0, #INDEX_DMC_T_MRD] - - ldr r1, =DMC_DDR_t_RAS - str r1, [r0, #INDEX_DMC_T_RAS] - - ldr r1, =DMC_DDR_t_RC - str r1, [r0, #INDEX_DMC_T_RC] - - ldr r1, =DMC_DDR_t_RCD - ldr r2, =DMC_DDR_schedule_RCD - orr r1, r1, r2 - str r1, [r0, #INDEX_DMC_T_RCD] - - ldr r1, =DMC_DDR_t_RFC - ldr r2, =DMC_DDR_schedule_RFC - orr r1, r1, r2 - str r1, [r0, #INDEX_DMC_T_RFC] - - ldr r1, =DMC_DDR_t_RP - ldr r2, =DMC_DDR_schedule_RP - orr r1, r1, r2 - str r1, [r0, #INDEX_DMC_T_RP] - - ldr r1, =DMC_DDR_t_RRD - str r1, [r0, #INDEX_DMC_T_RRD] - - ldr r1, =DMC_DDR_t_WR - str r1, [r0, #INDEX_DMC_T_WR] - - ldr r1, =DMC_DDR_t_WTR - str r1, [r0, #INDEX_DMC_T_WTR] - - ldr r1, =DMC_DDR_t_XP - str r1, [r0, #INDEX_DMC_T_XP] - - ldr r1, =DMC_DDR_t_XSR - str r1, [r0, #INDEX_DMC_T_XSR] - - ldr r1, =DMC_DDR_t_ESR - str r1, [r0, #INDEX_DMC_T_ESR] - - ldr r1, =DMC1_MEM_CFG - str r1, [r0, #INDEX_DMC_MEMORY_CFG] - - ldr r1, =DMC1_MEM_CFG2 - str r1, [r0, #INDEX_DMC_MEMORY_CFG2] - - ldr r1, =DMC1_CHIP0_CFG - str r1, [r0, #INDEX_DMC_CHIP_0_CFG] - - ldr r1, =DMC_DDR_32_CFG - str r1, [r0, #INDEX_DMC_USER_CONFIG] - - /* DMC0 DDR Chip 0 configuration direct command reg */ - ldr r1, =DMC_NOP0 - str r1, [r0, #INDEX_DMC_DIRECT_CMD] - - /* Precharge All */ - ldr r1, =DMC_PA0 - str r1, [r0, #INDEX_DMC_DIRECT_CMD] - - /* Auto Refresh 2 time */ - ldr r1, =DMC_AR0 - str r1, [r0, #INDEX_DMC_DIRECT_CMD] - str r1, [r0, #INDEX_DMC_DIRECT_CMD] - - /* MRS */ - ldr r1, =DMC_mDDR_EMR0 - str r1, [r0, #INDEX_DMC_DIRECT_CMD] - - /* Mode Reg */ - ldr r1, =DMC_mDDR_MR0 - str r1, [r0, #INDEX_DMC_DIRECT_CMD] - - /* Enable DMC1 */ - mov r1, #0x0 - str r1, [r0, #INDEX_DMC_MEMC_CMD] - -check_dmc1_ready: - ldr r1, [r0, #INDEX_DMC_MEMC_STATUS] - mov r2, #0x3 - and r1, r1, r2 - cmp r1, #0x1 - bne check_dmc1_ready - nop - - mov pc, lr - - .ltorg diff --git a/cpu/arm1176/s3c64xx/reset.S b/cpu/arm1176/s3c64xx/reset.S deleted file mode 100644 index eae572e4fd..0000000000 --- a/cpu/arm1176/s3c64xx/reset.S +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2009 Samsung Electronics. - * Minkyu Kang - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include - -.globl reset_cpu -reset_cpu: - ldr r1, =ELFIN_CLOCK_POWER_BASE - ldr r2, [r1, #SYS_ID_OFFSET] - ldr r3, =0xffff - and r2, r3, r2, lsr #12 - str r2, [r1, #SW_RST_OFFSET] -_loop_forever: - b _loop_forever diff --git a/cpu/arm1176/s3c64xx/speed.c b/cpu/arm1176/s3c64xx/speed.c deleted file mode 100644 index 11962acade..0000000000 --- a/cpu/arm1176/s3c64xx/speed.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * (C) Copyright 2001-2004 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * (C) Copyright 2002 - * David Mueller, ELSOFT AG, d.mueller@elsoft.ch - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * This code should work for both the S3C2400 and the S3C2410 - * as they seem to have the same PLL and clock machinery inside. - * The different address mapping is handled by the s3c24xx.h files below. - */ - -#include -#include - -#define APLL 0 -#define MPLL 1 -#define EPLL 2 - -/* ------------------------------------------------------------------------- */ -/* - * NOTE: This describes the proper use of this file. - * - * CONFIG_SYS_CLK_FREQ should be defined as the input frequency of the PLL. - * - * get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of - * the specified bus in HZ. - */ -/* ------------------------------------------------------------------------- */ - -static ulong get_PLLCLK(int pllreg) -{ - ulong r, m, p, s; - - switch (pllreg) { - case APLL: - r = APLL_CON_REG; - break; - case MPLL: - r = MPLL_CON_REG; - break; - case EPLL: - r = EPLL_CON0_REG; - break; - default: - hang(); - } - - m = (r >> 16) & 0x3ff; - p = (r >> 8) & 0x3f; - s = r & 0x7; - - return m * (CONFIG_SYS_CLK_FREQ / (p * (1 << s))); -} - -/* return ARMCORE frequency */ -ulong get_ARMCLK(void) -{ - ulong div; - - div = CLK_DIV0_REG; - - return get_PLLCLK(APLL) / ((div & 0x7) + 1); -} - -/* return FCLK frequency */ -ulong get_FCLK(void) -{ - return get_PLLCLK(APLL); -} - -/* return HCLK frequency */ -ulong get_HCLK(void) -{ - ulong fclk; - - uint hclkx2_div = ((CLK_DIV0_REG >> 9) & 0x7) + 1; - uint hclk_div = ((CLK_DIV0_REG >> 8) & 0x1) + 1; - - /* - * Bit 7 exists on s3c6410, and not on s3c6400, it is reserved on - * s3c6400 and is always 0, and it is indeed running in ASYNC mode - */ - if (OTHERS_REG & 0x80) - fclk = get_FCLK(); /* SYNC Mode */ - else - fclk = get_PLLCLK(MPLL); /* ASYNC Mode */ - - return fclk / (hclk_div * hclkx2_div); -} - -/* return PCLK frequency */ -ulong get_PCLK(void) -{ - ulong fclk; - uint hclkx2_div = ((CLK_DIV0_REG >> 9) & 0x7) + 1; - uint pre_div = ((CLK_DIV0_REG >> 12) & 0xf) + 1; - - if (OTHERS_REG & 0x80) - fclk = get_FCLK(); /* SYNC Mode */ - else - fclk = get_PLLCLK(MPLL); /* ASYNC Mode */ - - return fclk / (hclkx2_div * pre_div); -} - -/* return UCLK frequency */ -ulong get_UCLK(void) -{ - return get_PLLCLK(EPLL); -} - -int print_cpuinfo(void) -{ - printf("\nCPU: S3C6400@%luMHz\n", get_ARMCLK() / 1000000); - printf(" Fclk = %luMHz, Hclk = %luMHz, Pclk = %luMHz ", - get_FCLK() / 1000000, get_HCLK() / 1000000, - get_PCLK() / 1000000); - - if (OTHERS_REG & 0x80) - printf("(SYNC Mode) \n"); - else - printf("(ASYNC Mode) \n"); - return 0; -} diff --git a/cpu/arm1176/s3c64xx/timer.c b/cpu/arm1176/s3c64xx/timer.c deleted file mode 100644 index 9768319efa..0000000000 --- a/cpu/arm1176/s3c64xx/timer.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * (C) Copyright 2003 - * Texas Instruments - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * (C) Copyright 2002-2004 - * Gary Jennejohn, DENX Software Engineering, - * - * (C) Copyright 2004 - * Philippe Robin, ARM Ltd. - * - * (C) Copyright 2008 - * Guennadi Liakhovetki, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include - -static ulong timer_load_val; - -#define PRESCALER 167 - -static s3c64xx_timers *s3c64xx_get_base_timers(void) -{ - return (s3c64xx_timers *)ELFIN_TIMER_BASE; -} - -/* macro to read the 16 bit timer */ -static inline ulong read_timer(void) -{ - s3c64xx_timers *const timers = s3c64xx_get_base_timers(); - - return timers->TCNTO4; -} - -/* Internal tick units */ -/* Last decremneter snapshot */ -static unsigned long lastdec; -/* Monotonic incrementing timer */ -static unsigned long long timestamp; - -int timer_init(void) -{ - s3c64xx_timers *const timers = s3c64xx_get_base_timers(); - - /* use PWM Timer 4 because it has no output */ - /* - * We use the following scheme for the timer: - * Prescaler is hard fixed at 167, divider at 1/4. - * This gives at PCLK frequency 66MHz approx. 10us ticks - * The timer is set to wrap after 100s, at 66MHz this obviously - * happens after 10,000,000 ticks. A long variable can thus - * keep values up to 40,000s, i.e., 11 hours. This should be - * enough for most uses:-) Possible optimizations: select a - * binary-friendly frequency, e.g., 1ms / 128. Also calculate - * the prescaler automatically for other PCLK frequencies. - */ - timers->TCFG0 = PRESCALER << 8; - if (timer_load_val == 0) { - timer_load_val = get_PCLK() / PRESCALER * (100 / 4); /* 100s */ - timers->TCFG1 = (timers->TCFG1 & ~0xf0000) | 0x20000; - } - - /* load value for 10 ms timeout */ - lastdec = timers->TCNTB4 = timer_load_val; - /* auto load, manual update of Timer 4 */ - timers->TCON = (timers->TCON & ~0x00700000) | TCON_4_AUTO | - TCON_4_UPDATE; - - /* auto load, start Timer 4 */ - timers->TCON = (timers->TCON & ~0x00700000) | TCON_4_AUTO | COUNT_4_ON; - timestamp = 0; - - return 0; -} - -/* - * timer without interrupts - */ - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - ulong now = read_timer(); - - if (lastdec >= now) { - /* normal mode */ - timestamp += lastdec - now; - } else { - /* we have an overflow ... */ - timestamp += lastdec + timer_load_val - now; - } - lastdec = now; - - return timestamp; -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk(void) -{ - /* We overrun in 100s */ - return (ulong)(timer_load_val / 100); -} - -void reset_timer_masked(void) -{ - /* reset time */ - lastdec = read_timer(); - timestamp = 0; -} - -void reset_timer(void) -{ - reset_timer_masked(); -} - -ulong get_timer_masked(void) -{ - unsigned long long res = get_ticks(); - do_div (res, (timer_load_val / (100 * CONFIG_SYS_HZ))); - return res; -} - -ulong get_timer(ulong base) -{ - return get_timer_masked() - base; -} - -void set_timer(ulong t) -{ - timestamp = t * (timer_load_val / (100 * CONFIG_SYS_HZ)); -} - -void __udelay(unsigned long usec) -{ - unsigned long long tmp; - ulong tmo; - - tmo = (usec + 9) / 10; - tmp = get_ticks() + tmo; /* get current timestamp */ - - while (get_ticks() < tmp)/* loop till event */ - /*NOP*/; -} diff --git a/cpu/arm1176/start.S b/cpu/arm1176/start.S deleted file mode 100644 index e2b6c9b08d..0000000000 --- a/cpu/arm1176/start.S +++ /dev/null @@ -1,468 +0,0 @@ -/* - * armboot - Startup Code for S3C6400/ARM1176 CPU-core - * - * Copyright (c) 2007 Samsung Electronics - * - * Copyright (C) 2008 - * Guennadi Liakhovetki, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - * 2007-09-21 - Restructured codes by jsgood (jsgood.yang@samsung.com) - * 2007-09-21 - Added MoviNAND and OneNAND boot codes by - * jsgood (jsgood.yang@samsung.com) - * Base codes by scsuh (sc.suh) - */ - -#include -#include -#ifdef CONFIG_ENABLE_MMU -#include -#endif -#ifdef CONFIG_S3C64XX -#include -#endif - -#if !defined(CONFIG_ENABLE_MMU) && !defined(CONFIG_SYS_PHY_UBOOT_BASE) -#define CONFIG_SYS_PHY_UBOOT_BASE CONFIG_SYS_UBOOT_BASE -#endif - -/* - ************************************************************************* - * - * Jump vector table as in table 3.1 in [1] - * - ************************************************************************* - */ - -.globl _start -_start: b reset -#ifndef CONFIG_NAND_SPL - 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 - -_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 -_pad: - .word 0x12345678 /* now 16*4=64 */ -#else - . = _start + 64 -#endif - -.global _end_vect -_end_vect: - .balignl 16,0xdeadbeef -/* - ************************************************************************* - * - * Startup Code (reset vector) - * - * do important init only if we don't start from memory! - * setup Memory and board specific bits prior to relocation. - * relocate armboot to ram - * setup stack - * - ************************************************************************* - */ - -_TEXT_BASE: - .word TEXT_BASE - -/* - * Below variable is very important because we use MMU in U-Boot. - * Without it, we cannot run code correctly before MMU is ON. - * by scsuh. - */ -_TEXT_PHY_BASE: - .word CONFIG_SYS_PHY_UBOOT_BASE - -.globl _armboot_start -_armboot_start: - .word _start - -/* - * These are defined in the board-specific linker script. - */ -.globl _bss_start -_bss_start: - .word __bss_start - -.globl _bss_end -_bss_end: - .word _end - -/* - * the actual reset code - */ - -reset: - /* - * set the cpu to SVC32 mode - */ - mrs r0, cpsr - bic r0, r0, #0x3f - orr r0, r0, #0xd3 - msr cpsr, r0 - -/* - ************************************************************************* - * - * CPU_init_critical registers - * - * setup important registers - * setup memory timing - * - ************************************************************************* - */ - /* - * we do sys-critical inits only at reboot, - * not when booting from ram! - */ -cpu_init_crit: - /* - * When booting from NAND - it has definitely been a reset, so, no need - * to flush caches and disable the MMU - */ -#ifndef CONFIG_NAND_SPL - /* - * flush v4 I/D caches - */ - mov r0, #0 - mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ - mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ - - /* - * disable MMU stuff and caches - */ - mrc p15, 0, r0, c1, c0, 0 - bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) - bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) - orr r0, r0, #0x00000002 @ set bit 2 (A) Align - orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache - /* Prepare to disable the MMU */ - adr r1, mmu_disable_phys - /* We presume we're within the first 1024 bytes */ - and r1, r1, #0x3fc - ldr r2, _TEXT_PHY_BASE - ldr r3, =0xfff00000 - and r2, r2, r3 - orr r2, r2, r1 - b mmu_disable - - .align 5 - /* Run in a single cache-line */ -mmu_disable: - mcr p15, 0, r0, c1, c0, 0 - nop - nop - mov pc, r2 -#endif - -mmu_disable_phys: -#ifdef CONFIG_S3C64XX - /* Peri port setup */ - ldr r0, =0x70000000 - orr r0, r0, #0x13 - mcr p15,0,r0,c15,c2,4 @ 256M (0x70000000 - 0x7fffffff) -#endif - - /* - * Go setup Memory and board specific bits prior to relocation. - */ - bl lowlevel_init /* go setup pll,mux,memory */ - -after_copy: -#ifdef CONFIG_ENABLE_MMU -enable_mmu: - /* enable domain access */ - ldr r5, =0x0000ffff - mcr p15, 0, r5, c3, c0, 0 /* load domain access register */ - - /* Set the TTB register */ - ldr r0, _mmu_table_base - ldr r1, =CONFIG_SYS_PHY_UBOOT_BASE - ldr r2, =0xfff00000 - bic r0, r0, r2 - orr r1, r0, r1 - mcr p15, 0, r1, c2, c0, 0 - - /* Enable the MMU */ - mrc p15, 0, r0, c1, c0, 0 - orr r0, r0, #1 /* Set CR_M to enable MMU */ - - /* Prepare to enable the MMU */ - adr r1, skip_hw_init - and r1, r1, #0x3fc - ldr r2, _TEXT_BASE - ldr r3, =0xfff00000 - and r2, r2, r3 - orr r2, r2, r1 - b mmu_enable - - .align 5 - /* Run in a single cache-line */ -mmu_enable: - - mcr p15, 0, r0, c1, c0, 0 - nop - nop - mov pc, r2 -#endif - -skip_hw_init: - /* Set up the stack */ -stack_setup: - ldr r0, =CONFIG_SYS_UBOOT_BASE /* base of copy in DRAM */ - sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */ - sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ - sub sp, r0, #12 /* leave 3 words for abort-stack */ - -clear_bss: - ldr r0, _bss_start /* find start of bss segment */ - ldr r1, _bss_end /* stop here */ - mov r2, #0 /* clear */ - -clbss_l: - str r2, [r0] /* clear loop... */ - add r0, r0, #4 - cmp r0, r1 - ble clbss_l - -#ifndef CONFIG_NAND_SPL - ldr pc, _start_armboot - -_start_armboot: - .word start_armboot -#else - b nand_boot -/* .word nand_boot*/ -#endif - -#ifdef CONFIG_ENABLE_MMU -_mmu_table_base: - .word mmu_table -#endif - -#ifndef CONFIG_NAND_SPL -/* - * we assume that cache operation is done before. (eg. cleanup_before_linux()) - * actually, we don't need to do anything about cache if not use d-cache in - * U-Boot. So, in this function we clean only MMU. by scsuh - * - * void theLastJump(void *kernel, int arch_num, uint boot_params); - */ -#ifdef CONFIG_ENABLE_MMU - .globl theLastJump -theLastJump: - mov r9, r0 - ldr r3, =0xfff00000 - ldr r4, _TEXT_PHY_BASE - adr r5, phy_last_jump - bic r5, r5, r3 - orr r5, r5, r4 - mov pc, r5 -phy_last_jump: - /* - * disable MMU stuff - */ - mrc p15, 0, r0, c1, c0, 0 - bic r0, r0, #0x00002300 /* clear bits 13, 9:8 (--V- --RS) */ - bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */ - orr r0, r0, #0x00000002 /* set bit 2 (A) Align */ - orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */ - mcr p15, 0, r0, c1, c0, 0 - - mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ - - mov r0, #0 - mov pc, r9 -#endif -/* - ************************************************************************* - * - * 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 -#define I_BIT 0x80 - -/* - * use bad_save_user_regs for abort/prefetch/undef/swi ... - */ - - .macro bad_save_user_regs - /* carve out a frame on current user stack */ - sub sp, sp, #S_FRAME_SIZE - /* Save user registers (now in svc mode) r0-r12 */ - stmia sp, {r0 - r12} - - ldr r2, _armboot_start - sub r2, r2, #(CONFIG_SYS_MALLOC_LEN) - /* set base 2 words into abort stack */ - sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) - /* get values for "aborted" pc and cpsr (into parm regs) */ - ldmia r2, {r2 - r3} - /* grab pointer to old stack */ - add r0, sp, #S_FRAME_SIZE - - add r5, sp, #S_SP - mov r1, lr - /* save sp_SVC, lr_SVC, pc, cpsr */ - stmia r5, {r0 - r3} - /* save current stack into r0 (param register) */ - mov r0, sp - .endm - - .macro get_bad_stack - /* setup our mode stack (enter in banked mode) */ - ldr r13, _armboot_start - /* move past malloc pool */ - sub r13, r13, #(CONFIG_SYS_MALLOC_LEN) - /* move to reserved a couple spots for abort stack */ - sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE + 8) - - /* save caller lr in position 0 of saved stack */ - str lr, [r13] - /* get the spsr */ - mrs lr, spsr - /* save spsr in position 1 of saved stack */ - str lr, [r13, #4] - - /* prepare SVC-Mode */ - mov r13, #MODE_SVC - @ msr spsr_c, r13 - /* switch modes, make sure moves will execute */ - msr spsr, r13 - /* capture return pc */ - mov lr, pc - /* jump to next instruction & switch modes. */ - movs pc, lr - .endm - - .macro get_bad_stack_swi - /* space on current stack for scratch reg. */ - sub r13, r13, #4 - /* save R0's value. */ - str r0, [r13] - /* get data regions start */ - ldr r0, _armboot_start - /* move past malloc pool */ - sub r0, r0, #(CONFIG_SYS_MALLOC_LEN) - /* move past gbl and a couple spots for abort stack */ - sub r0, r0, #(CONFIG_SYS_GBL_DATA_SIZE + 8) - /* save caller lr in position 0 of saved stack */ - str lr, [r0] - /* get the spsr */ - mrs r0, spsr - /* save spsr in position 1 of saved stack */ - str lr, [r0, #4] - /* restore r0 */ - ldr r0, [r13] - /* pop stack entry */ - add r13, r13, #4 - .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_swi - 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 - - .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 /* CONFIG_NAND_SPL */ diff --git a/cpu/arm1176/u-boot.lds b/cpu/arm1176/u-boot.lds deleted file mode 100644 index cc682f54df..0000000000 --- a/cpu/arm1176/u-boot.lds +++ /dev/null @@ -1,56 +0,0 @@ -/* - * (C) Copyright 2002-2004 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -ENTRY(_start) -SECTIONS -{ - . = 0x00000000; - - . = ALIGN(4); - .text : - { - cpu/arm1176/start.o (.text) - *(.text) - } - - . = ALIGN(4); - .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } - - . = ALIGN(4); - .data : { *(.data) } - - . = ALIGN(4); - .got : { *(.got) } - - . = .; - __u_boot_cmd_start = .; - .u_boot_cmd : { *(.u_boot_cmd) } - __u_boot_cmd_end = .; - - . = ALIGN(4); - __bss_start = .; - .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } - _end = .; -} diff --git a/cpu/arm720t/Makefile b/cpu/arm720t/Makefile deleted file mode 100644 index d5ac7d3fd9..0000000000 --- a/cpu/arm720t/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(CPU).a - -START = start.o -COBJS = interrupts.o cpu.o - -SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) -START := $(addprefix $(obj),$(START)) - -all: $(obj).depend $(START) $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/arm720t/config.mk b/cpu/arm720t/config.mk deleted file mode 100644 index 3844c626af..0000000000 --- a/cpu/arm720t/config.mk +++ /dev/null @@ -1,33 +0,0 @@ -# -# (C) Copyright 2002 -# Sysgo Real-Time Solutions, GmbH -# Marius Groeger -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float - -PLATFORM_CPPFLAGS += -march=armv4 -mtune=arm7tdmi -# ========================================================================= -# -# Supply options according to compiler version -# -# ========================================================================= -PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/arm720t/cpu.c b/cpu/arm720t/cpu.c deleted file mode 100644 index 88c71bfe18..0000000000 --- a/cpu/arm720t/cpu.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * CPU specific code - */ - -#include -#include -#include -#include -#include - -#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO) -static void cache_flush(void); -#endif - -int cleanup_before_linux (void) -{ - /* - * this function is called just before we call linux - * it prepares the processor for linux - * - * we turn off caches etc ... - * and we set the CPU-speed to 73 MHz - see start.S for details - */ - -#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO) - disable_interrupts (); - - /* turn off I-cache */ - icache_disable(); - dcache_disable(); - - /* flush I-cache */ - cache_flush(); -#ifdef CONFIG_ARM7_REVD - /* go to high speed */ - IO_SYSCON3 = (IO_SYSCON3 & ~CLKCTL) | CLKCTL_73; -#endif -#elif defined(CONFIG_NETARM) || defined(CONFIG_S3C4510B) || defined(CONFIG_LPC2292) - disable_interrupts (); - /* Nothing more needed */ -#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR) - /* No cleanup before linux for IntegratorAP/CM720T as yet */ -#else -#error No cleanup_before_linux() defined for this CPU type -#endif - return 0; -} - -#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO) -/* flush I/D-cache */ -static void cache_flush (void) -{ - unsigned long i = 0; - - asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (i)); -} -#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR) - /* No specific cache setup for IntegratorAP/CM720T as yet */ - void icache_enable (void) - { - } -#endif diff --git a/cpu/arm720t/interrupts.c b/cpu/arm720t/interrupts.c deleted file mode 100644 index eb8d425318..0000000000 --- a/cpu/arm720t/interrupts.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include - -#ifndef CONFIG_NETARM -/* we always count down the max. */ -#define TIMER_LOAD_VAL 0xffff -/* macro to read the 16 bit timer */ -#define READ_TIMER (IO_TC1D & 0xffff) - -#ifdef CONFIG_LPC2292 -#undef READ_TIMER -#define READ_TIMER (0xFFFFFFFF - GET32(T0TC)) -#endif - -#else -#define IRQEN (*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_INTR_ENABLE)) -#define TM2CTRL (*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_TIMER2_CONTROL)) -#define TM2STAT (*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_TIMER2_STATUS)) -#define TIMER_LOAD_VAL NETARM_GEN_TSTAT_CTC_MASK -#define READ_TIMER (TM2STAT & NETARM_GEN_TSTAT_CTC_MASK) -#endif - -#ifdef CONFIG_S3C4510B -/* require interrupts for the S3C4510B */ -# ifndef CONFIG_USE_IRQ -# error CONFIG_USE_IRQ _must_ be defined when using CONFIG_S3C4510B -# else -static struct _irq_handler IRQ_HANDLER[N_IRQS]; -# endif -#endif /* CONFIG_S3C4510B */ - -#ifdef CONFIG_USE_IRQ -void do_irq (struct pt_regs *pt_regs) -{ -#if defined(CONFIG_S3C4510B) - unsigned int pending; - - while ( (pending = GET_REG( REG_INTOFFSET)) != 0x54) { /* sentinal value for no pending interrutps */ - IRQ_HANDLER[pending>>2].m_func( IRQ_HANDLER[pending>>2].m_data); - - /* clear pending interrupt */ - PUT_REG( REG_INTPEND, (1<<(pending>>2))); - } -#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR) - /* No do_irq() for IntegratorAP/CM720T as yet */ -#elif defined(CONFIG_LPC2292) - - void (*pfnct)(void); - - pfnct = (void (*)(void))VICVectAddr; - - (*pfnct)(); -#else -#error do_irq() not defined for this CPU type -#endif -} -#endif - -#ifdef CONFIG_S3C4510B -static void default_isr( void *data) { - printf ("default_isr(): called for IRQ %d\n", (int)data); -} - -static void timer_isr( void *data) { - unsigned int *pTime = (unsigned int *)data; - - (*pTime)++; - if ( !(*pTime % (CONFIG_SYS_HZ/4))) { - /* toggle LED 0 */ - PUT_REG( REG_IOPDATA, GET_REG(REG_IOPDATA) ^ 0x1); - } - -} -#endif - -#if defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR) - /* Use IntegratorAP routines in board/integratorap.c */ -#else - -static ulong timestamp; -static ulong lastdec; - -#if defined(CONFIG_USE_IRQ) && defined(CONFIG_S3C4510B) -int arch_interrupt_init (void) -{ - int i; - - /* install default interrupt handlers */ - for ( i = 0; i < N_IRQS; i++) { - IRQ_HANDLER[i].m_data = (void *)i; - IRQ_HANDLER[i].m_func = default_isr; - } - - /* configure interrupts for IRQ mode */ - PUT_REG( REG_INTMODE, 0x0); - /* clear any pending interrupts */ - PUT_REG( REG_INTPEND, 0x1FFFFF); - - lastdec = 0; - - /* install interrupt handler for timer */ - IRQ_HANDLER[INT_TIMER0].m_data = (void *)×tamp; - IRQ_HANDLER[INT_TIMER0].m_func = timer_isr; - - return 0; -} -#endif - -int timer_init (void) -{ -#if defined(CONFIG_NETARM) - /* disable all interrupts */ - IRQEN = 0; - - /* operate timer 2 in non-prescale mode */ - TM2CTRL = ( NETARM_GEN_TIMER_SET_HZ(CONFIG_SYS_HZ) | - NETARM_GEN_TCTL_ENABLE | - NETARM_GEN_TCTL_INIT_COUNT(TIMER_LOAD_VAL)); - - /* set timer 2 counter */ - lastdec = TIMER_LOAD_VAL; -#elif defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO) - /* disable all interrupts */ - IO_INTMR1 = 0; - - /* operate timer 1 in prescale mode */ - IO_SYSCON1 |= SYSCON1_TC1M; - - /* select 2kHz clock source for timer 1 */ - IO_SYSCON1 &= ~SYSCON1_TC1S; - - /* set timer 1 counter */ - lastdec = IO_TC1D = TIMER_LOAD_VAL; -#elif defined(CONFIG_S3C4510B) - /* configure free running timer 0 */ - PUT_REG( REG_TMOD, 0x0); - /* Stop timer 0 */ - CLR_REG( REG_TMOD, TM0_RUN); - - /* Configure for interval mode */ - CLR_REG( REG_TMOD, TM1_TOGGLE); - - /* - * Load Timer data register with count down value. - * count_down_val = CONFIG_SYS_SYS_CLK_FREQ/CONFIG_SYS_HZ - */ - PUT_REG( REG_TDATA0, (CONFIG_SYS_SYS_CLK_FREQ / CONFIG_SYS_HZ)); - - /* - * Enable global interrupt - * Enable timer0 interrupt - */ - CLR_REG( REG_INTMASK, ((1<= now) { - /* normal mode */ - timestamp += lastdec - now; - } else { - /* we have an overflow ... */ - timestamp += lastdec + TIMER_LOAD_VAL - now; - } - lastdec = now; - - return timestamp; -} - -void udelay_masked (unsigned long usec) -{ - ulong tmo; - ulong endtime; - signed long diff; - - if (usec >= 1000) { - tmo = usec / 1000; - tmo *= CONFIG_SYS_HZ; - tmo /= 1000; - } else { - tmo = usec * CONFIG_SYS_HZ; - tmo /= (1000*1000); - } - - endtime = get_timer_masked () + tmo; - - do { - ulong now = get_timer_masked (); - diff = endtime - now; - } while (diff >= 0); -} - -#elif defined(CONFIG_S3C4510B) - -ulong get_timer (ulong base) -{ - return timestamp - base; -} - -void __udelay (unsigned long usec) -{ - u32 ticks; - - ticks = (usec * CONFIG_SYS_HZ) / 1000000; - - ticks += get_timer (0); - - while (get_timer (0) < ticks) - /*NOP*/; - -} - -#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR) - /* No timer routines for IntegratorAP/CM720T as yet */ -#else -#error Timer routines not defined for this CPU type -#endif diff --git a/cpu/arm720t/lpc2292/Makefile b/cpu/arm720t/lpc2292/Makefile deleted file mode 100644 index 240f1e3b3b..0000000000 --- a/cpu/arm720t/lpc2292/Makefile +++ /dev/null @@ -1,50 +0,0 @@ -# -# (C) Copyright 2000-2007 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(SOC).a - -COBJS = flash.o mmc.o mmc_hw.o spi.o -SOBJS = $(obj)iap_entry.o - -SRCS := $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS)) - -all: $(obj).depend $(LIB) - -$(LIB): $(OBJS) $(SOBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS) - -# this MUST be compiled as thumb code! -$(SOBJS): - $(CC) $(AFLAGS) -march=armv4t -c -o $(SOBJS) iap_entry.S - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/arm720t/lpc2292/flash.c b/cpu/arm720t/lpc2292/flash.c deleted file mode 100644 index 3d2dc32231..0000000000 --- a/cpu/arm720t/lpc2292/flash.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - * (C) Copyright 2006 Embedded Artists AB - * - * Modified to remove all but the IAP-command related code by - * Gary Jennejohn - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include - -/* IAP commands use 32 bytes at the top of CPU internal sram, we - use 512 bytes below that */ -#define COPY_BUFFER_LOCATION 0x40003de0 - -#define IAP_LOCATION 0x7ffffff1 -#define IAP_CMD_PREPARE 50 -#define IAP_CMD_COPY 51 -#define IAP_CMD_ERASE 52 -#define IAP_CMD_CHECK 53 -#define IAP_CMD_ID 54 -#define IAP_CMD_VERSION 55 -#define IAP_CMD_COMPARE 56 - -#define IAP_RET_CMD_SUCCESS 0 - -static unsigned long command[5]; -static unsigned long result[2]; - -extern void iap_entry(unsigned long * command, unsigned long * result); - -/*----------------------------------------------------------------------- - * - */ -static int get_flash_sector(flash_info_t * info, ulong flash_addr) -{ - int i; - - for(i = 1; i < (info->sector_count); i++) { - if (flash_addr < (info->start[i])) - break; - } - - return (i-1); -} - -/*----------------------------------------------------------------------- - * This function assumes that flash_addr is aligned on 512 bytes boundary - * in flash. This function also assumes that prepare have been called - * for the sector in question. - */ -int lpc2292_copy_buffer_to_flash(flash_info_t * info, ulong flash_addr) -{ - int first_sector; - int last_sector; - - first_sector = get_flash_sector(info, flash_addr); - last_sector = get_flash_sector(info, flash_addr + 512 - 1); - - /* prepare sectors for write */ - command[0] = IAP_CMD_PREPARE; - command[1] = first_sector; - command[2] = last_sector; - iap_entry(command, result); - if (result[0] != IAP_RET_CMD_SUCCESS) { - printf("IAP prepare failed\n"); - return ERR_PROG_ERROR; - } - - command[0] = IAP_CMD_COPY; - command[1] = flash_addr; - command[2] = COPY_BUFFER_LOCATION; - command[3] = 512; - command[4] = CONFIG_SYS_SYS_CLK_FREQ >> 10; - iap_entry(command, result); - if (result[0] != IAP_RET_CMD_SUCCESS) { - printf("IAP copy failed\n"); - return 1; - } - - return 0; -} - -/*----------------------------------------------------------------------- - */ - -int lpc2292_flash_erase (flash_info_t * info, int s_first, int s_last) -{ - int flag; - int prot; - int sect; - - prot = 0; - for (sect = s_first; sect <= s_last; ++sect) { - if (info->protect[sect]) { - prot++; - } - } - if (prot) - return ERR_PROTECTED; - - - flag = disable_interrupts(); - - printf ("Erasing %d sectors starting at sector %2d.\n" - "This make take some time ... ", - s_last - s_first + 1, s_first); - - command[0] = IAP_CMD_PREPARE; - command[1] = s_first; - command[2] = s_last; - iap_entry(command, result); - if (result[0] != IAP_RET_CMD_SUCCESS) { - printf("IAP prepare failed\n"); - return ERR_PROTECTED; - } - - command[0] = IAP_CMD_ERASE; - command[1] = s_first; - command[2] = s_last; - command[3] = CONFIG_SYS_SYS_CLK_FREQ >> 10; - iap_entry(command, result); - if (result[0] != IAP_RET_CMD_SUCCESS) { - printf("IAP erase failed\n"); - return ERR_PROTECTED; - } - - if (flag) - enable_interrupts(); - - return ERR_OK; -} - -int lpc2292_write_buff (flash_info_t * info, uchar * src, ulong addr, - ulong cnt) -{ - int first_copy_size; - int last_copy_size; - int first_block; - int last_block; - int nbr_mid_blocks; - uchar memmap_value; - ulong i; - uchar* src_org; - uchar* dst_org; - int ret = ERR_OK; - - src_org = src; - dst_org = (uchar*)addr; - - first_block = addr / 512; - last_block = (addr + cnt) / 512; - nbr_mid_blocks = last_block - first_block - 1; - - first_copy_size = 512 - (addr % 512); - last_copy_size = (addr + cnt) % 512; - - debug("\ncopy first block: (1) %lX -> %lX 0x200 bytes, " - "(2) %lX -> %lX 0x%X bytes, (3) %lX -> %lX 0x200 bytes\n", - (ulong)(first_block * 512), - (ulong)COPY_BUFFER_LOCATION, - (ulong)src, - (ulong)(COPY_BUFFER_LOCATION + 512 - first_copy_size), - first_copy_size, - (ulong)COPY_BUFFER_LOCATION, - (ulong)(first_block * 512)); - - /* copy first block */ - memcpy((void*)COPY_BUFFER_LOCATION, - (void*)(first_block * 512), 512); - memcpy((void*)(COPY_BUFFER_LOCATION + 512 - first_copy_size), - src, first_copy_size); - lpc2292_copy_buffer_to_flash(info, first_block * 512); - src += first_copy_size; - addr += first_copy_size; - - /* copy middle blocks */ - for (i = 0; i < nbr_mid_blocks; i++) { - debug("copy middle block: %lX -> %lX 512 bytes, " - "%lX -> %lX 512 bytes\n", - (ulong)src, - (ulong)COPY_BUFFER_LOCATION, - (ulong)COPY_BUFFER_LOCATION, - (ulong)addr); - - memcpy((void*)COPY_BUFFER_LOCATION, src, 512); - lpc2292_copy_buffer_to_flash(info, addr); - src += 512; - addr += 512; - } - - - if (last_copy_size > 0) { - debug("copy last block: (1) %lX -> %lX 0x200 bytes, " - "(2) %lX -> %lX 0x%X bytes, (3) %lX -> %lX x200 bytes\n", - (ulong)(last_block * 512), - (ulong)COPY_BUFFER_LOCATION, - (ulong)src, - (ulong)(COPY_BUFFER_LOCATION), - last_copy_size, - (ulong)COPY_BUFFER_LOCATION, - (ulong)addr); - - /* copy last block */ - memcpy((void*)COPY_BUFFER_LOCATION, - (void*)(last_block * 512), 512); - memcpy((void*)COPY_BUFFER_LOCATION, - src, last_copy_size); - lpc2292_copy_buffer_to_flash(info, addr); - } - - /* verify write */ - memmap_value = GET8(MEMMAP); - - disable_interrupts(); - - PUT8(MEMMAP, 01); /* we must make sure that initial 64 - bytes are taken from flash when we - do the compare */ - - for (i = 0; i < cnt; i++) { - if (*dst_org != *src_org){ - printf("Write failed. Byte %lX differs\n", i); - ret = ERR_PROG_ERROR; - break; - } - dst_org++; - src_org++; - } - - PUT8(MEMMAP, memmap_value); - enable_interrupts(); - - return ret; -} diff --git a/cpu/arm720t/lpc2292/iap_entry.S b/cpu/arm720t/lpc2292/iap_entry.S deleted file mode 100644 index c31d5190bd..0000000000 --- a/cpu/arm720t/lpc2292/iap_entry.S +++ /dev/null @@ -1,7 +0,0 @@ -IAP_ADDRESS: .word 0x7FFFFFF1 - -.globl iap_entry -iap_entry: - ldr r2, IAP_ADDRESS - bx r2 - mov pc, lr diff --git a/cpu/arm720t/lpc2292/mmc.c b/cpu/arm720t/lpc2292/mmc.c deleted file mode 100644 index beaffe944c..0000000000 --- a/cpu/arm720t/lpc2292/mmc.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include "mmc_hw.h" -#include - -#ifdef CONFIG_MMC - -#undef MMC_DEBUG - -static block_dev_desc_t mmc_dev; - -/* these are filled out by a call to mmc_hw_get_parameters */ -static int hw_size; /* in kbytes */ -static int hw_nr_sects; -static int hw_sect_size; /* in bytes */ - -block_dev_desc_t * mmc_get_dev(int dev) -{ - return (block_dev_desc_t *)(&mmc_dev); -} - -unsigned long mmc_block_read(int dev, - unsigned long start, - lbaint_t blkcnt, - void *buffer) -{ - unsigned long rc = 0; - unsigned char *p = (unsigned char *)buffer; - unsigned long i; - unsigned long addr = start; - -#ifdef MMC_DEBUG - printf("mmc_block_read: start=%lu, blkcnt=%lu\n", start, - (unsigned long)blkcnt); -#endif - - for(i = 0; i < (unsigned long)blkcnt; i++) { -#ifdef MMC_DEBUG - printf("mmc_read_sector: addr=%lu, buffer=%p\n", addr, p); -#endif - (void)mmc_read_sector(addr, p); - rc++; - addr++; - p += hw_sect_size; - } - - return rc; -} - -/*----------------------------------------------------------------------------- - * Read hardware paramterers (sector size, size, number of sectors) - */ -static int mmc_hw_get_parameters(void) -{ - unsigned char csddata[16]; - unsigned int sizemult; - unsigned int size; - - mmc_read_csd(csddata); - hw_sect_size = 1<<(csddata[5] & 0x0f); - size = ((csddata[6]&0x03)<<10)+(csddata[7]<<2)+(csddata[8]&0xc0); - sizemult = ((csddata[10] & 0x80)>>7)+((csddata[9] & 0x03)<<1); - hw_nr_sects = (size+1)*(1<<(sizemult+2)); - hw_size = hw_nr_sects*hw_sect_size/1024; - -#ifdef MMC_DEBUG - printf("mmc_hw_get_parameters: hw_sect_size=%d, hw_nr_sects=%d, " - "hw_size=%d\n", hw_sect_size, hw_nr_sects, hw_size); -#endif - - return 0; -} - -int mmc_legacy_init(int verbose) -{ - int ret = -ENODEV; - - if (verbose) - printf("mmc_legacy_init\n"); - - spi_init(); - /* this meeds to be done twice */ - mmc_hw_init(); - udelay(1000); - mmc_hw_init(); - - mmc_hw_get_parameters(); - - mmc_dev.if_type = IF_TYPE_MMC; - mmc_dev.part_type = PART_TYPE_DOS; - mmc_dev.dev = 0; - mmc_dev.lun = 0; - mmc_dev.type = 0; - mmc_dev.blksz = hw_sect_size; - mmc_dev.lba = hw_nr_sects; - sprintf((char*)mmc_dev.vendor, "Unknown vendor"); - sprintf((char*)mmc_dev.product, "Unknown product"); - sprintf((char*)mmc_dev.revision, "N/A"); - mmc_dev.removable = 0; /* should be true??? */ - mmc_dev.block_read = mmc_block_read; - - fat_register_device(&mmc_dev, 1); - - ret = 0; - - return ret; -} - -#endif /* CONFIG_MMC */ diff --git a/cpu/arm720t/lpc2292/mmc_hw.c b/cpu/arm720t/lpc2292/mmc_hw.c deleted file mode 100644 index b4dc4a6e2f..0000000000 --- a/cpu/arm720t/lpc2292/mmc_hw.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - This code was original written by Ulrich Radig and modified by - Embedded Artists AB (www.embeddedartists.com). - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include -#include -#include -#include - -#define MMC_Enable() PUT32(IO1CLR, 1l << 22) -#define MMC_Disable() PUT32(IO1SET, 1l << 22) -#define mmc_spi_cfg() spi_set_clock(8); spi_set_cfg(0, 1, 0); - -static unsigned char Write_Command_MMC (unsigned char *CMD); -static void MMC_Read_Block(unsigned char *CMD, unsigned char *Buffer, - unsigned short int Bytes); - -/* initialize the hardware */ -int mmc_hw_init(void) -{ - unsigned long a; - unsigned short int Timeout = 0; - unsigned char b; - unsigned char CMD[] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x95}; - - /* set-up GPIO and SPI */ - (*((volatile unsigned long *)PINSEL2)) &= ~(1l << 3); /* clear bit 3 */ - (*((volatile unsigned long *)IO1DIR)) |= (1l << 22); /* set bit 22 (output) */ - - MMC_Disable(); - - spi_lock(); - spi_set_clock(248); - spi_set_cfg(0, 1, 0); - MMC_Enable(); - - /* waste some time */ - for(a=0; a < 20000; a++) - asm("nop"); - - /* Put the MMC/SD-card into SPI-mode */ - for (b = 0; b < 10; b++) /* Sends min 74+ clocks to the MMC/SD-card */ - spi_write(0xff); - - /* Sends command CMD0 to MMC/SD-card */ - while (Write_Command_MMC(CMD) != 1) { - if (Timeout++ > 200) { - MMC_Disable(); - spi_unlock(); - return(1); /* Abort with command 1 (return 1) */ - } - } - /* Sends Command CMD1 an MMC/SD-card */ - Timeout = 0; - CMD[0] = 0x41;/* Command 1 */ - CMD[5] = 0xFF; - - while (Write_Command_MMC(CMD) != 0) { - if (Timeout++ > 200) { - MMC_Disable(); - spi_unlock(); - return (2); /* Abort with command 2 (return 2) */ - } - } - - MMC_Disable(); - spi_unlock(); - - return 0; -} - -/* ############################################################################ - Sends a command to the MMC/SD-card - ######################################################################### */ -static unsigned char Write_Command_MMC (unsigned char *CMD) -{ - unsigned char a, tmp = 0xff; - unsigned short int Timeout = 0; - - MMC_Disable(); - spi_write(0xFF); - MMC_Enable(); - - for (a = 0; a < 0x06; a++) - spi_write(*CMD++); - - while (tmp == 0xff) { - tmp = spi_read(); - if (Timeout++ > 5000) - break; - } - - return (tmp); -} - -/* ############################################################################ - Routine to read the CID register from the MMC/SD-card (16 bytes) - ######################################################################### */ -void MMC_Read_Block(unsigned char *CMD, unsigned char *Buffer, unsigned short - int Bytes) -{ - unsigned short int a; - - spi_lock(); - mmc_spi_cfg(); - MMC_Enable(); - - if (Write_Command_MMC(CMD) != 0) { - MMC_Disable(); - spi_unlock(); - return; - } - - while (spi_read() != 0xfe) {}; - for (a = 0; a < Bytes; a++) - *Buffer++ = spi_read(); - - /* Read the CRC-byte */ - spi_read(); /* CRC - byte is discarded */ - spi_read(); /* CRC - byte is discarded */ - /* set MMC_Chip_Select to high (MMC/SD-card Inaktiv) */ - MMC_Disable(); - spi_unlock(); - - return; -} - -/* ############################################################################ - Routine to read a block (512 bytes) from the MMC/SD-card - ######################################################################### */ -unsigned char mmc_read_sector (unsigned long addr,unsigned char *Buffer) -{ - /* Command 16 to read aBlocks from the MMC/SD - caed */ - unsigned char CMD[] = {0x51,0x00,0x00,0x00,0x00,0xFF}; - - /* The addres on the MMC/SD-card is in bytes, - addr is transformed from blocks to bytes and the result is - placed into the command */ - - addr = addr << 9; /* addr = addr * 512 */ - - CMD[1] = ((addr & 0xFF000000) >> 24); - CMD[2] = ((addr & 0x00FF0000) >> 16); - CMD[3] = ((addr & 0x0000FF00) >> 8 ); - - MMC_Read_Block(CMD, Buffer, 512); - - return (0); -} - -/* ############################################################################ - Routine to write a block (512 byte) to the MMC/SD-card - ######################################################################### */ -unsigned char mmc_write_sector (unsigned long addr,unsigned char *Buffer) -{ - unsigned char tmp, a; - unsigned short int b; - /* Command 24 to write a block to the MMC/SD - card */ - unsigned char CMD[] = {0x58, 0x00, 0x00, 0x00, 0x00, 0xFF}; - - /* The addres on the MMC/SD-card is in bytes, - addr is transformed from blocks to bytes and the result is - placed into the command */ - - addr = addr << 9; /* addr = addr * 512 */ - - CMD[1] = ((addr & 0xFF000000) >> 24); - CMD[2] = ((addr & 0x00FF0000) >> 16); - CMD[3] = ((addr & 0x0000FF00) >> 8 ); - - spi_lock(); - mmc_spi_cfg(); - MMC_Enable(); - - /* Send command CMD24 to the MMC/SD-card (Write 1 Block/512 Bytes) */ - tmp = Write_Command_MMC(CMD); - if (tmp != 0) { - MMC_Disable(); - spi_unlock(); - return(tmp); - } - - /* Do a short delay and send a clock-pulse to the MMC/SD-card */ - for (a = 0; a < 100; a++) - spi_read(); - - /* Send a start byte to the MMC/SD-card */ - spi_write(0xFE); - - /* Write the block (512 bytes) to the MMC/SD-card */ - for (b = 0; b < 512; b++) - spi_write(*Buffer++); - - /* write the CRC-Byte */ - spi_write(0xFF); /* write a dummy CRC */ - spi_write(0xFF); /* CRC code is not used */ - - /* Wait for MMC/SD-card busy */ - while (spi_read() != 0xff) {}; - - /* set MMC_Chip_Select to high (MMC/SD-card inactive) */ - MMC_Disable(); - spi_unlock(); - return (0); -} - -/* ######################################################################### - Routine to read the CSD register from the MMC/SD-card (16 bytes) - ######################################################################### */ -unsigned char mmc_read_csd (unsigned char *Buffer) -{ - /* Command to read the CSD register */ - unsigned char CMD[] = {0x49, 0x00, 0x00, 0x00, 0x00, 0xFF}; - - MMC_Read_Block(CMD, Buffer, 16); - - return (0); -} diff --git a/cpu/arm720t/lpc2292/mmc_hw.h b/cpu/arm720t/lpc2292/mmc_hw.h deleted file mode 100644 index 3687dbf696..0000000000 --- a/cpu/arm720t/lpc2292/mmc_hw.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - This module implements a linux character device driver for the 24c256 chip. - Copyright (C) 2006 Embedded Artists AB (www.embeddedartists.com) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#ifndef _MMC_HW_ -#define _MMC_HW_ - -unsigned char mmc_read_csd(unsigned char *Buffer); -unsigned char mmc_read_sector (unsigned long addr, - unsigned char *Buffer); -unsigned char mmc_write_sector (unsigned long addr,unsigned char *Buffer); -int mmc_hw_init(void); - -#endif /* _MMC_HW_ */ diff --git a/cpu/arm720t/lpc2292/spi.c b/cpu/arm720t/lpc2292/spi.c deleted file mode 100644 index d296bdac68..0000000000 --- a/cpu/arm720t/lpc2292/spi.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - This module implements an interface to the SPI on the lpc22xx. - Copyright (C) 2006 Embedded Artists AB (www.embeddedartists.com) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include -#include -#include -#include -#include - -unsigned long spi_flags; -unsigned char spi_idle = 0x00; - -int spi_init(void) -{ - unsigned long pinsel0_value; - - /* activate spi pins */ - pinsel0_value = GET32(PINSEL0); - pinsel0_value &= ~(0xFFl << 8); - pinsel0_value |= (0x55l << 8); - PUT32(PINSEL0, pinsel0_value); - - return 0; -} diff --git a/cpu/arm720t/s3c4510b/Makefile b/cpu/arm720t/s3c4510b/Makefile deleted file mode 100644 index c099036351..0000000000 --- a/cpu/arm720t/s3c4510b/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -# -# (C) Copyright 2000-2008 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(SOC).a - -COBJS-y += cache.o - -SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y)) - -all: $(obj).depend $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/arm720t/s3c4510b/cache.c b/cpu/arm720t/s3c4510b/cache.c deleted file mode 100644 index 104d287b26..0000000000 --- a/cpu/arm720t/s3c4510b/cache.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include - -void icache_enable (void) -{ - s32 i; - - /* disable all cache bits */ - CLR_REG( REG_SYSCFG, 0x3F); - - /* 8KB cache, write enable */ - SET_REG( REG_SYSCFG, CACHE_WRITE_BUFF | CACHE_MODE_01); - - /* clear TAG RAM bits */ - for ( i = 0; i < 256; i++) - PUT_REG( CACHE_TAG_RAM + 4*i, 0x00000000); - - /* clear SET0 RAM */ - for(i=0; i < 1024; i++) - PUT_REG( CACHE_SET0_RAM + 4*i, 0x00000000); - - /* clear SET1 RAM */ - for(i=0; i < 1024; i++) - PUT_REG( CACHE_SET1_RAM + 4*i, 0x00000000); - - /* enable cache */ - SET_REG( REG_SYSCFG, CACHE_ENABLE); - -} - -void icache_disable (void) -{ - /* disable all cache bits */ - CLR_REG( REG_SYSCFG, 0x3F); -} - -int icache_status (void) -{ - return GET_REG( REG_SYSCFG) & CACHE_ENABLE; -} - -void dcache_enable (void) -{ - /* we don't have seperate instruction/data caches */ - icache_enable(); -} - -void dcache_disable (void) -{ - /* we don't have seperate instruction/data caches */ - icache_disable(); -} - -int dcache_status (void) -{ - /* we don't have seperate instruction/data caches */ - return icache_status(); -} diff --git a/cpu/arm720t/start.S b/cpu/arm720t/start.S deleted file mode 100644 index 022b873e35..0000000000 --- a/cpu/arm720t/start.S +++ /dev/null @@ -1,611 +0,0 @@ -/* - * armboot - Startup Code for ARM720 CPU-core - * - * Copyright (c) 2001 Marius Gröger - * Copyright (c) 2002 Alex Züpke - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - - -#include -#include -#include - -/* - ************************************************************************* - * - * Jump vector table as in table 3.1 in [1] - * - ************************************************************************* - */ - - -.globl _start -_start: b reset - ldr pc, _undefined_instruction - ldr pc, _software_interrupt - ldr pc, _prefetch_abort - ldr pc, _data_abort -#ifdef CONFIG_LPC2292 - .word 0xB4405F76 /* 2's complement of the checksum of the vectors */ -#else - ldr pc, _not_used -#endif - ldr pc, _irq - ldr pc, _fiq - -_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 RAM! - * relocate armboot to ram - * setup stack - * jump to second stage - * - ************************************************************************* - */ - -_TEXT_BASE: - .word TEXT_BASE - -.globl _armboot_start -_armboot_start: - .word _start - -/* - * These are defined in the board-specific linker script. - */ -.globl _bss_start -_bss_start: - .word __bss_start - -.globl _bss_end -_bss_end: - .word _end - -#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 - - -/* - * the actual reset code - */ - -reset: - /* - * set the cpu to SVC32 mode - */ - mrs r0,cpsr - bic r0,r0,#0x1f - orr r0,r0,#0x13 - msr cpsr,r0 - - /* - * we do sys-critical inits only at reboot, - * not when booting from ram! - */ -#ifndef CONFIG_SKIP_LOWLEVEL_INIT - bl cpu_init_crit -#endif - -#ifdef CONFIG_LPC2292 - bl lowlevel_init -#endif - -#ifndef CONFIG_SKIP_RELOCATE_UBOOT -relocate: /* relocate U-Boot to RAM */ - adr r0, _start /* r0 <- current position of code */ - ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ - cmp r0, r1 /* don't reloc during debug */ - beq stack_setup - -#if TEXT_BASE -#ifndef CONFIG_LPC2292 /* already done in lowlevel_init */ - ldr r2, =0x0 /* Relocate the exception vectors */ - cmp r1, r2 /* and associated data to address */ - ldmneia r0!, {r3-r10} /* 0x0. Do nothing if TEXT_BASE is */ - stmneia r2!, {r3-r10} /* 0x0. Copy the first 15 words. */ - ldmneia r0, {r3-r9} - stmneia r2, {r3-r9} - adrne r0, _start /* restore r0 */ -#endif /* !CONFIG_LPC2292 */ -#endif - - ldr r2, _armboot_start - ldr r3, _bss_start - sub r2, r3, r2 /* r2 <- size of armboot */ - add r2, r0, r2 /* r2 <- source end address */ - -copy_loop: - ldmia r0!, {r3-r10} /* copy from source address [r0] */ - stmia r1!, {r3-r10} /* copy to target address [r1] */ - cmp r0, r2 /* until source end addreee [r2] */ - ble copy_loop - -#endif /* CONFIG_SKIP_RELOCATE_UBOOT */ - - /* Set up the stack */ -stack_setup: - ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ - sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */ - sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ -#ifdef CONFIG_USE_IRQ - sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) -#endif - sub sp, r0, #12 /* leave 3 words for abort-stack */ - -clear_bss: - ldr r0, _bss_start /* find start of bss segment */ - ldr r1, _bss_end /* stop here */ - mov r2, #0x00000000 /* clear */ - -clbss_l:str r2, [r0] /* clear loop... */ - add r0, r0, #4 - cmp r0, r1 - ble clbss_l - - ldr pc, _start_armboot - -_start_armboot: .word start_armboot - -/* - ************************************************************************* - * - * CPU_init_critical registers - * - * setup important registers - * setup memory timing - * - ************************************************************************* - */ - -#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO) - -/* Interupt-Controller base addresses */ -INTMR1: .word 0x80000280 @ 32 bit size -INTMR2: .word 0x80001280 @ 16 bit size -INTMR3: .word 0x80002280 @ 8 bit size - -/* SYSCONs */ -SYSCON1: .word 0x80000100 -SYSCON2: .word 0x80001100 -SYSCON3: .word 0x80002200 - -#define CLKCTL 0x6 /* mask */ -#define CLKCTL_18 0x0 /* 18.432 MHz */ -#define CLKCTL_36 0x2 /* 36.864 MHz */ -#define CLKCTL_49 0x4 /* 49.152 MHz */ -#define CLKCTL_73 0x6 /* 73.728 MHz */ - -#elif defined(CONFIG_LPC2292) -PLLCFG_ADR: .word PLLCFG -PLLFEED_ADR: .word PLLFEED -PLLCON_ADR: .word PLLCON -PLLSTAT_ADR: .word PLLSTAT -VPBDIV_ADR: .word VPBDIV -MEMMAP_ADR: .word MEMMAP - -#endif - -cpu_init_crit: -#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO) - - /* - * mask all IRQs by clearing all bits in the INTMRs - */ - mov r1, #0x00 - ldr r0, INTMR1 - str r1, [r0] - ldr r0, INTMR2 - str r1, [r0] - ldr r0, INTMR3 - str r1, [r0] - - /* - * flush v4 I/D caches - */ - mov r0, #0 - mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ - mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ - - /* - * disable MMU stuff and caches - */ - mrc p15,0,r0,c1,c0 - bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) - bic r0, r0, #0x0000008f @ clear bits 7, 3:0 (B--- WCAM) - orr r0, r0, #0x00000002 @ set bit 2 (A) Align - mcr p15,0,r0,c1,c0 -#elif defined(CONFIG_NETARM) - /* - * prior to software reset : need to set pin PORTC4 to be *HRESET - */ - ldr r0, =NETARM_GEN_MODULE_BASE - ldr r1, =(NETARM_GEN_PORT_MODE(0x10) | \ - NETARM_GEN_PORT_DIR(0x10)) - str r1, [r0, #+NETARM_GEN_PORTC] - /* - * software reset : see HW Ref. Guide 8.2.4 : Software Service register - * for an explanation of this process - */ - ldr r0, =NETARM_GEN_MODULE_BASE - ldr r1, =NETARM_GEN_SW_SVC_RESETA - str r1, [r0, #+NETARM_GEN_SOFTWARE_SERVICE] - ldr r1, =NETARM_GEN_SW_SVC_RESETB - str r1, [r0, #+NETARM_GEN_SOFTWARE_SERVICE] - ldr r1, =NETARM_GEN_SW_SVC_RESETA - str r1, [r0, #+NETARM_GEN_SOFTWARE_SERVICE] - ldr r1, =NETARM_GEN_SW_SVC_RESETB - str r1, [r0, #+NETARM_GEN_SOFTWARE_SERVICE] - /* - * setup PLL and System Config - */ - ldr r0, =NETARM_GEN_MODULE_BASE - - ldr r1, =( NETARM_GEN_SYS_CFG_LENDIAN | \ - NETARM_GEN_SYS_CFG_BUSFULL | \ - NETARM_GEN_SYS_CFG_USER_EN | \ - NETARM_GEN_SYS_CFG_ALIGN_ABORT | \ - NETARM_GEN_SYS_CFG_BUSARB_INT | \ - NETARM_GEN_SYS_CFG_BUSMON_EN ) - - str r1, [r0, #+NETARM_GEN_SYSTEM_CONTROL] - -#ifndef CONFIG_NETARM_PLL_BYPASS - ldr r1, =( NETARM_GEN_PLL_CTL_PLLCNT(NETARM_PLL_COUNT_VAL) | \ - NETARM_GEN_PLL_CTL_POLTST_DEF | \ - NETARM_GEN_PLL_CTL_INDIV(1) | \ - NETARM_GEN_PLL_CTL_ICP_DEF | \ - NETARM_GEN_PLL_CTL_OUTDIV(2) ) - str r1, [r0, #+NETARM_GEN_PLL_CONTROL] -#endif - - /* - * mask all IRQs by clearing all bits in the INTMRs - */ - mov r1, #0 - ldr r0, =NETARM_GEN_MODULE_BASE - str r1, [r0, #+NETARM_GEN_INTR_ENABLE] - -#elif defined(CONFIG_S3C4510B) - - /* - * Mask off all IRQ sources - */ - ldr r1, =REG_INTMASK - ldr r0, =0x3FFFFF - str r0, [r1] - - /* - * Disable Cache - */ - ldr r0, =REG_SYSCFG - ldr r1, =0x83ffffa0 /* cache-disabled */ - str r1, [r0] - -#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR) - /* No specific initialisation for IntegratorAP/CM720T as yet */ -#elif defined(CONFIG_LPC2292) - /* Set-up PLL */ - mov r3, #0xAA - mov r4, #0x55 - /* First disconnect and disable the PLL */ - ldr r0, PLLCON_ADR - mov r1, #0x00 - str r1, [r0] - ldr r0, PLLFEED_ADR /* start feed sequence */ - str r3, [r0] - str r4, [r0] /* feed sequence done */ - /* Set new M and P values */ - ldr r0, PLLCFG_ADR - mov r1, #0x23 /* M=4 and P=2 */ - str r1, [r0] - ldr r0, PLLFEED_ADR /* start feed sequence */ - str r3, [r0] - str r4, [r0] /* feed sequence done */ - /* Then enable the PLL */ - ldr r0, PLLCON_ADR - mov r1, #0x01 /* PLL enable bit */ - str r1, [r0] - ldr r0, PLLFEED_ADR /* start feed sequence */ - str r3, [r0] - str r4, [r0] /* feed sequence done */ - /* Wait for the lock */ - ldr r0, PLLSTAT_ADR - mov r1, #0x400 /* lock bit */ -lock_loop: - ldr r2, [r0] - and r2, r1, r2 - cmp r2, #0 - beq lock_loop - /* And finally connect the PLL */ - ldr r0, PLLCON_ADR - mov r1, #0x03 /* PLL enable bit and connect bit */ - str r1, [r0] - ldr r0, PLLFEED_ADR /* start feed sequence */ - str r3, [r0] - str r4, [r0] /* feed sequence done */ - /* Set-up VPBDIV register */ - ldr r0, VPBDIV_ADR - mov r1, #0x01 /* VPB clock is same as process clock */ - str r1, [r0] -#else -#error No cpu_init_crit() defined for current CPU type -#endif - -#ifdef CONFIG_ARM7_REVD - /* set clock speed */ - /* !!! we run @ 36 MHz due to a hardware flaw in Rev. D processors */ - /* !!! not doing DRAM refresh properly! */ - ldr r0, SYSCON3 - ldr r1, [r0] - bic r1, r1, #CLKCTL - orr r1, r1, #CLKCTL_36 - str r1, [r0] -#endif - -#ifndef CONFIG_LPC2292 - mov ip, lr - /* - * before relocating, we have to setup RAM timing - * because memory timing is board-dependent, you will - * find a lowlevel_init.S in your board directory. - */ - bl lowlevel_init - mov lr, ip -#endif - - mov pc, 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 -#define I_BIT 0x80 - -/* - * use bad_save_user_regs for abort/prefetch/undef/swi ... - * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling - */ - - .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, _armboot_start - sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) - sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack - 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 - - .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, _armboot_start @ setup our mode stack - sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) - sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort 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 - /* someone ought to write a more effiction fiq_save_user_regs */ - irq_save_user_regs - bl do_fiq - 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 - -#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO) - .align 5 -.globl reset_cpu -reset_cpu: - mov ip, #0 - mcr p15, 0, ip, c7, c7, 0 @ invalidate cache - mcr p15, 0, ip, c8, c7, 0 @ flush TLB (v4) - mrc p15, 0, ip, c1, c0, 0 @ get ctrl register - bic ip, ip, #0x000f @ ............wcam - bic ip, ip, #0x2100 @ ..v....s........ - mcr p15, 0, ip, c1, c0, 0 @ ctrl register - mov pc, r0 -#elif defined(CONFIG_NETARM) - .align 5 -.globl reset_cpu -reset_cpu: - ldr r1, =NETARM_MEM_MODULE_BASE - ldr r0, [r1, #+NETARM_MEM_CS0_BASE_ADDR] - ldr r1, =0xFFFFF000 - and r0, r1, r0 - ldr r1, =(relocate-TEXT_BASE) - add r0, r1, r0 - ldr r4, =NETARM_GEN_MODULE_BASE - ldr r1, =NETARM_GEN_SW_SVC_RESETA - str r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE] - ldr r1, =NETARM_GEN_SW_SVC_RESETB - str r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE] - ldr r1, =NETARM_GEN_SW_SVC_RESETA - str r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE] - ldr r1, =NETARM_GEN_SW_SVC_RESETB - str r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE] - mov pc, r0 -#elif defined(CONFIG_S3C4510B) -/* Nothing done here as reseting the CPU is board specific, depending - * on external peripherals such as watchdog timers, etc. */ -#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR) - /* No specific reset actions for IntegratorAP/CM720T as yet */ -#elif defined(CONFIG_LPC2292) - .align 5 -.globl reset_cpu -reset_cpu: - mov pc, r0 -#else -#error No reset_cpu() defined for current CPU type -#endif diff --git a/cpu/arm720t/u-boot.lds b/cpu/arm720t/u-boot.lds deleted file mode 100644 index 111c3f5a6a..0000000000 --- a/cpu/arm720t/u-boot.lds +++ /dev/null @@ -1,56 +0,0 @@ -/* - * (C) Copyright 2000-2004 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -ENTRY(_start) -SECTIONS -{ - . = 0x00000000; - - . = ALIGN(4); - .text : - { - cpu/arm720t/start.o (.text) - *(.text) - } - - . = ALIGN(4); - .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } - - . = ALIGN(4); - .data : { *(.data) } - - . = ALIGN(4); - .got : { *(.got) } - - . = .; - __u_boot_cmd_start = .; - .u_boot_cmd : { *(.u_boot_cmd) } - __u_boot_cmd_end = .; - - . = ALIGN(4); - __bss_start = .; - .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } - _end = .; -} diff --git a/cpu/arm920t/Makefile b/cpu/arm920t/Makefile deleted file mode 100644 index cbb13b2a4c..0000000000 --- a/cpu/arm920t/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(CPU).a - -START = start.o - -COBJS-y += cpu.o -COBJS-$(CONFIG_USE_IRQ) += interrupts.o - -SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS-y:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS-y) $(SOBJS)) -START := $(addprefix $(obj),$(START)) - -all: $(obj).depend $(START) $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/arm920t/a320/Makefile b/cpu/arm920t/a320/Makefile deleted file mode 100644 index f030c53626..0000000000 --- a/cpu/arm920t/a320/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(SOC).a - -SOBJS += reset.o -COBJS += timer.o -COBJS += ftsmc020.o - -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) - -all: $(obj).depend $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/arm920t/a320/ftsmc020.c b/cpu/arm920t/a320/ftsmc020.c deleted file mode 100644 index 76465373ec..0000000000 --- a/cpu/arm920t/a320/ftsmc020.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * (C) Copyright 2009 Faraday Technology - * Po-Yu Chuang - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include - -struct ftsmc020_config { - unsigned int config; - unsigned int timing; -}; - -static struct ftsmc020_config config[] = CONFIG_SYS_FTSMC020_CONFIGS; - -static struct ftsmc020 *smc = (struct ftsmc020 *)CONFIG_FTSMC020_BASE; - -static void ftsmc020_setup_bank(unsigned int bank, struct ftsmc020_config *cfg) -{ - if (bank > 3) { - printf("bank # %u invalid\n", bank); - return; - } - - writel(cfg->config, &smc->bank[bank].cr); - writel(cfg->timing, &smc->bank[bank].tpr); -} - -void ftsmc020_init(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(config); i++) - ftsmc020_setup_bank(i, &config[i]); -} diff --git a/cpu/arm920t/a320/reset.S b/cpu/arm920t/a320/reset.S deleted file mode 100644 index 12ca527c5d..0000000000 --- a/cpu/arm920t/a320/reset.S +++ /dev/null @@ -1,22 +0,0 @@ -/* - * (C) Copyright 2009 Faraday Technology - * Po-Yu Chuang - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -.global reset_cpu -reset_cpu: - b reset_cpu diff --git a/cpu/arm920t/a320/timer.c b/cpu/arm920t/a320/timer.c deleted file mode 100644 index bb655930de..0000000000 --- a/cpu/arm920t/a320/timer.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * (C) Copyright 2009 Faraday Technology - * Po-Yu Chuang - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include - -static ulong timestamp; -static ulong lastdec; - -static struct fttmr010 *tmr = (struct fttmr010 *)CONFIG_FTTMR010_BASE; -static struct ftpmu010 *pmu = (struct ftpmu010 *)CONFIG_FTPMU010_BASE; - -#define TIMER_CLOCK 32768 -#define TIMER_LOAD_VAL 0xffffffff - -int timer_init(void) -{ - unsigned int oscc; - unsigned int cr; - - debug("%s()\n", __func__); - - /* disable timers */ - writel(0, &tmr->cr); - - /* - * use 32768Hz oscillator for RTC, WDT, TIMER - */ - - /* enable the 32768Hz oscillator */ - oscc = readl(&pmu->OSCC); - oscc &= ~(FTPMU010_OSCC_OSCL_OFF | FTPMU010_OSCC_OSCL_TRI); - writel(oscc, &pmu->OSCC); - - /* wait until ready */ - while (!(readl(&pmu->OSCC) & FTPMU010_OSCC_OSCL_STABLE)) - ; - - /* select 32768Hz oscillator */ - oscc = readl(&pmu->OSCC); - oscc |= FTPMU010_OSCC_OSCL_RTCLSEL; - writel(oscc, &pmu->OSCC); - - /* setup timer */ - writel(TIMER_LOAD_VAL, &tmr->timer3_load); - writel(TIMER_LOAD_VAL, &tmr->timer3_counter); - writel(0, &tmr->timer3_match1); - writel(0, &tmr->timer3_match2); - - /* we don't want timer to issue interrupts */ - writel(FTTMR010_TM3_MATCH1 | - FTTMR010_TM3_MATCH2 | - FTTMR010_TM3_OVERFLOW, - &tmr->interrupt_mask); - - cr = readl(&tmr->cr); - cr |= FTTMR010_TM3_CLOCK; /* use external clock */ - cr |= FTTMR010_TM3_ENABLE; - writel(cr, &tmr->cr); - - /* init the timestamp and lastdec value */ - reset_timer_masked(); - - return 0; -} - -/* - * timer without interrupts - */ - -/* - * reset time - */ -void reset_timer_masked(void) -{ - /* capure current decrementer value time */ - lastdec = readl(&tmr->timer3_counter) / (TIMER_CLOCK / CONFIG_SYS_HZ); - timestamp = 0; /* start "advancing" time stamp from 0 */ - - debug("%s(): lastdec = %lx\n", __func__, lastdec); -} - -void reset_timer(void) -{ - debug("%s()\n", __func__); - reset_timer_masked(); -} - -/* - * return timer ticks - */ -ulong get_timer_masked(void) -{ - /* current tick value */ - ulong now = readl(&tmr->timer3_counter) / (TIMER_CLOCK / CONFIG_SYS_HZ); - - debug("%s(): now = %lx, lastdec = %lx\n", __func__, now, lastdec); - - if (lastdec >= now) { - /* - * normal mode (non roll) - * move stamp fordward with absoulte diff ticks - */ - timestamp += lastdec - now; - } else { - /* - * we have overflow of the count down timer - * - * nts = ts + ld + (TLV - now) - * ts=old stamp, ld=time that passed before passing through -1 - * (TLV-now) amount of time after passing though -1 - * nts = new "advancing time stamp"...it could also roll and - * cause problems. - */ - timestamp += lastdec + TIMER_LOAD_VAL - now; - } - - lastdec = now; - - debug("%s() returns %lx\n", __func__, timestamp); - - return timestamp; -} - -/* - * return difference between timer ticks and base - */ -ulong get_timer(ulong base) -{ - debug("%s(%lx)\n", __func__, base); - return get_timer_masked() - base; -} - -void set_timer(ulong t) -{ - debug("%s(%lx)\n", __func__, t); - timestamp = t; -} - -/* delay x useconds AND perserve advance timstamp value */ -void udelay(unsigned long usec) -{ - long tmo = usec * (TIMER_CLOCK / 1000) / 1000; - unsigned long now, last = readl(&tmr->timer3_counter); - - debug("%s(%lu)\n", __func__, usec); - while (tmo > 0) { - now = readl(&tmr->timer3_counter); - if (now > last) /* count down timer overflow */ - tmo -= TIMER_LOAD_VAL + last - now; - else - tmo -= last - now; - last = now; - } -} - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - debug("%s()\n", __func__); - return get_timer(0); -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk(void) -{ - debug("%s()\n", __func__); - return CONFIG_SYS_HZ; -} diff --git a/cpu/arm920t/at91/Makefile b/cpu/arm920t/at91/Makefile deleted file mode 100644 index d8a4383650..0000000000 --- a/cpu/arm920t/at91/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(SOC).a - -SOBJS += lowlevel_init.o -COBJS += reset.o -COBJS += timer.o - -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) - -all: $(obj).depend $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/arm920t/at91/lowlevel_init.S b/cpu/arm920t/at91/lowlevel_init.S deleted file mode 100644 index 22fc86cd5b..0000000000 --- a/cpu/arm920t/at91/lowlevel_init.S +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and - * Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl) - * - * Modified for the at91rm9200dk board by - * (C) Copyright 2004 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include - -#ifndef CONFIG_SKIP_LOWLEVEL_INIT - -#include -#include -#include -#include - -#define ARM920T_CONTROL 0xC0000000 /* @ set bit 31 (iA) and 30 (nF) */ - -_MTEXT_BASE: -#undef START_FROM_MEM -#ifdef START_FROM_MEM - .word TEXT_BASE-PHYS_FLASH_1 -#else - .word TEXT_BASE -#endif - -.globl lowlevel_init -lowlevel_init: - ldr r1, =AT91_ASM_PMC_MOR - /* Main oscillator Enable register */ -#ifdef CONFIG_SYS_USE_MAIN_OSCILLATOR - ldr r0, =0x0000FF01 /* Enable main oscillator */ -#else - ldr r0, =0x0000FF00 /* Disable main oscillator */ -#endif - str r0, [r1] /*AT91C_CKGR_MOR] */ - /* Add loop to compensate Main Oscillator startup time */ - ldr r0, =0x00000010 -LoopOsc: - subs r0, r0, #1 - bhi LoopOsc - - /* memory control configuration */ - /* this isn't very elegant, but what the heck */ - ldr r0, =SMRDATA - ldr r1, _MTEXT_BASE - sub r0, r0, r1 - add r2, r0, #80 -pllloop: - /* the address */ - ldr r1, [r0], #4 - /* the value */ - ldr r3, [r0], #4 - str r3, [r1] - cmp r2, r0 - bne pllloop - /* delay - this is all done by guess */ - ldr r0, =0x00010000 - /* (vs reading PMC_SR for LOCKA, LOCKB ... or MOSCS earlier) */ -lock: - subs r0, r0, #1 - bhi lock - ldr r0, =SMRDATA1 - ldr r1, _MTEXT_BASE - sub r0, r0, r1 - add r2, r0, #176 -sdinit: - /* the address */ - ldr r1, [r0], #4 - /* the value */ - ldr r3, [r0], #4 - str r3, [r1] - cmp r2, r0 - bne sdinit - - /* switch from FastBus to Asynchronous clock mode */ - mrc p15, 0, r0, c1, c0, 0 - orr r0, r0, #ARM920T_CONTROL - mcr p15, 0, r0, c1, c0, 0 - - /* everything is fine now */ - mov pc, lr - - .ltorg - -SMRDATA: - .word AT91_ASM_MC_EBI_CFG - .word CONFIG_SYS_EBI_CFGR_VAL - .word AT91_ASM_MC_SMC_CSR0 - .word CONFIG_SYS_SMC_CSR0_VAL - .word AT91_ASM_PMC_PLLAR - .word CONFIG_SYS_PLLAR_VAL - .word AT91_ASM_PMC_PLLBR - .word CONFIG_SYS_PLLBR_VAL - .word AT91_ASM_PMC_MCKR - .word CONFIG_SYS_MCKR_VAL - /* here there's a delay */ -SMRDATA1: - .word AT91_ASM_PIOC_ASR - .word CONFIG_SYS_PIOC_ASR_VAL - .word AT91_ASM_PIOC_BSR - .word CONFIG_SYS_PIOC_BSR_VAL - .word AT91_ASM_PIOC_PDR - .word CONFIG_SYS_PIOC_PDR_VAL - .word AT91_ASM_MC_EBI_CSA - .word CONFIG_SYS_EBI_CSA_VAL - .word AT91_ASM_MC_SDRAMC_CR - .word CONFIG_SYS_SDRC_CR_VAL - .word AT91_ASM_MC_SDRAMC_MR - .word CONFIG_SYS_SDRC_MR_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word AT91_ASM_MC_SDRAMC_MR - .word CONFIG_SYS_SDRC_MR_VAL1 - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word AT91_ASM_MC_SDRAMC_MR - .word CONFIG_SYS_SDRC_MR_VAL2 - .word CONFIG_SYS_SDRAM1 - .word CONFIG_SYS_SDRAM_VAL - .word AT91_ASM_MC_SDRAMC_TR - .word CONFIG_SYS_SDRC_TR_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word AT91_ASM_MC_SDRAMC_MR - .word CONFIG_SYS_SDRC_MR_VAL3 - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - /* SMRDATA1 is 176 bytes long */ -#endif /* CONFIG_SKIP_LOWLEVEL_INIT */ diff --git a/cpu/arm920t/at91/reset.c b/cpu/arm920t/at91/reset.c deleted file mode 100644 index ce9c156154..0000000000 --- a/cpu/arm920t/at91/reset.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * (C) Copyright 2002 - * Lineo, Inc. - * Bernhard Kuhn - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include - -void board_reset(void) __attribute__((__weak__)); - -void reset_cpu(ulong ignored) -{ - at91_st_t *st = (at91_st_t *) AT91_ST_BASE; -#if defined(CONFIG_AT91RM9200_USART) - /*shutdown the console to avoid strange chars during reset */ - serial_exit(); -#endif - - if (board_reset) - board_reset(); - - /* Reset the cpu by setting up the watchdog timer */ - writel(AT91_ST_WDMR_RSTEN | AT91_ST_WDMR_EXTEN | AT91_ST_WDMR_WDV(2), - &st->wdmr); - writel(AT91_ST_CR_WDRST, &st->cr); - /* and let it timeout */ - while (1) - ; - /* Never reached */ -} diff --git a/cpu/arm920t/at91/timer.c b/cpu/arm920t/at91/timer.c deleted file mode 100644 index 91377d47a6..0000000000 --- a/cpu/arm920t/at91/timer.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * (C) Copyright 2002 - * Lineo, Inc. - * Bernhard Kuhn - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include - -#include -#include -#include -#include - -/* the number of clocks per CONFIG_SYS_HZ */ -#define TIMER_LOAD_VAL (CONFIG_SYS_HZ_CLOCK/CONFIG_SYS_HZ) - -static u32 timestamp; -static u32 lastinc; - -int timer_init(void) -{ - at91_tc_t *tc = (at91_tc_t *) AT91_TC_BASE; - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - /* enables TC1.0 clock */ - writel(1 << AT91_ID_TC0, &pmc->pcer); /* enable clock */ - - writel(0, &tc->bcr); - writel(AT91_TC_BMR_TC0XC0S_NONE | AT91_TC_BMR_TC1XC1S_NONE | - AT91_TC_BMR_TC2XC2S_NONE , &tc->bmr); - - writel(AT91_TC_CCR_CLKDIS, &tc->tc[0].ccr); - /* set to MCLK/2 and restart the timer - when the value in TC_RC is reached */ - writel(AT91_TC_CMR_TCCLKS_CLOCK1 | AT91_TC_CMR_CPCTRG, &tc->tc[0].cmr); - - writel(0xFFFFFFFF, &tc->tc[0].idr); /* disable interupts */ - writel(TIMER_LOAD_VAL, &tc->tc[0].rc); - - writel(AT91_TC_CCR_SWTRG | AT91_TC_CCR_CLKEN, &tc->tc[0].ccr); - lastinc = 0; - timestamp = 0; - - return 0; -} - -/* - * timer without interrupts - */ - -void reset_timer(void) -{ - reset_timer_masked(); -} - -ulong get_timer(ulong base) -{ - return get_timer_masked() - base; -} - -void set_timer(ulong t) -{ - timestamp = t; -} - -void __udelay(unsigned long usec) -{ - udelay_masked(usec); -} - -void reset_timer_masked(void) -{ - /* reset time */ - at91_tc_t *tc = (at91_tc_t *) AT91_TC_BASE; - lastinc = readl(&tc->tc[0].cv) & 0x0000ffff; - timestamp = 0; -} - -ulong get_timer_raw(void) -{ - at91_tc_t *tc = (at91_tc_t *) AT91_TC_BASE; - u32 now; - - now = readl(&tc->tc[0].cv) & 0x0000ffff; - - if (now >= lastinc) { - /* normal mode */ - timestamp += now - lastinc; - } else { - /* we have an overflow ... */ - timestamp += now + TIMER_LOAD_VAL - lastinc; - } - lastinc = now; - - return timestamp; -} - -ulong get_timer_masked(void) -{ - return get_timer_raw()/TIMER_LOAD_VAL; -} - -void udelay_masked(unsigned long usec) -{ - u32 tmo; - u32 endtime; - signed long diff; - - tmo = CONFIG_SYS_HZ_CLOCK / 1000; - tmo *= usec; - tmo /= 1000; - - endtime = get_timer_raw() + tmo; - - do { - u32 now = get_timer_raw(); - diff = endtime - now; - } while (diff >= 0); -} - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return get_timer(0); -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk(void) -{ - return CONFIG_SYS_HZ; -} diff --git a/cpu/arm920t/at91rm9200/Makefile b/cpu/arm920t/at91rm9200/Makefile deleted file mode 100644 index 114d8adeb2..0000000000 --- a/cpu/arm920t/at91rm9200/Makefile +++ /dev/null @@ -1,56 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(SOC).a - -SOBJS += lowlevel_init.o - -COBJS += bcm5221.o -COBJS += dm9161.o -COBJS += ether.o -COBJS += i2c.o -COBJS-$(CONFIG_KS8721_PHY) += ks8721.o -COBJS += lxt972.o -COBJS += reset.o -COBJS += spi.o -COBJS += timer.o -COBJS += usb.o - -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) $(COBJS-y:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS) $(COBJS-y)) - -all: $(obj).depend $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/arm920t/at91rm9200/bcm5221.c b/cpu/arm920t/at91rm9200/bcm5221.c deleted file mode 100644 index 8de3cba738..0000000000 --- a/cpu/arm920t/at91rm9200/bcm5221.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Broadcom BCM5221 Ethernet PHY - * - * (C) Copyright 2005 REA Elektronik GmbH - * Anders Larsen - * - * (C) Copyright 2003 - * Author : Hamid Ikdoumi (Atmel) - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#ifdef CONFIG_DRIVER_ETHER - -#include - -#if defined(CONFIG_CMD_NET) - -/* - * Name: - * bcm5221_IsPhyConnected - * Description: - * Reads the 2 PHY ID registers - * Arguments: - * p_mac - pointer to AT91S_EMAC struct - * Return value: - * TRUE - if id read successfully - * FALSE- if error - */ -unsigned int bcm5221_IsPhyConnected (AT91PS_EMAC p_mac) -{ - unsigned short Id1, Id2; - - at91rm9200_EmacEnableMDIO (p_mac); - at91rm9200_EmacReadPhy (p_mac, BCM5221_PHYID1, &Id1); - at91rm9200_EmacReadPhy (p_mac, BCM5221_PHYID2, &Id2); - at91rm9200_EmacDisableMDIO (p_mac); - - if ((Id1 == (BCM5221_PHYID1_OUI >> 6)) && - ((Id2 >> 10) == (BCM5221_PHYID1_OUI & BCM5221_LSB_MASK))) - return TRUE; - - return FALSE; -} - -/* - * Name: - * bcm5221_GetLinkSpeed - * Description: - * Link parallel detection status of MAC is checked and set in the - * MAC configuration registers - * Arguments: - * p_mac - pointer to MAC - * Return value: - * TRUE - if link status set succesfully - * FALSE - if link status not set - */ -unsigned char bcm5221_GetLinkSpeed (AT91PS_EMAC p_mac) -{ - unsigned short stat1, stat2; - - if (!at91rm9200_EmacReadPhy (p_mac, BCM5221_BMSR, &stat1)) - return FALSE; - - if (!(stat1 & BCM5221_LINK_STATUS)) /* link status up? */ - return FALSE; - - if (!at91rm9200_EmacReadPhy (p_mac, BCM5221_ACSR, &stat2)) - return FALSE; - - if ((stat1 & BCM5221_100BASE_TX_FD) && (stat2 & BCM5221_100) && (stat2 & BCM5221_FDX)) { - /*set Emac for 100BaseTX and Full Duplex */ - p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD; - return TRUE; - } - - if ((stat1 & BCM5221_10BASE_T_FD) && !(stat2 & BCM5221_100) && (stat2 & BCM5221_FDX)) { - /*set MII for 10BaseT and Full Duplex */ - p_mac->EMAC_CFG = (p_mac->EMAC_CFG & - ~(AT91C_EMAC_SPD | AT91C_EMAC_FD)) - | AT91C_EMAC_FD; - return TRUE; - } - - if ((stat1 & BCM5221_100BASE_TX_HD) && (stat2 & BCM5221_100) && !(stat2 & BCM5221_FDX)) { - /*set MII for 100BaseTX and Half Duplex */ - p_mac->EMAC_CFG = (p_mac->EMAC_CFG & - ~(AT91C_EMAC_SPD | AT91C_EMAC_FD)) - | AT91C_EMAC_SPD; - return TRUE; - } - - if ((stat1 & BCM5221_10BASE_T_HD) && !(stat2 & BCM5221_100) && !(stat2 & BCM5221_FDX)) { - /*set MII for 10BaseT and Half Duplex */ - p_mac->EMAC_CFG &= ~(AT91C_EMAC_SPD | AT91C_EMAC_FD); - return TRUE; - } - return FALSE; -} - - -/* - * Name: - * bcm5221_InitPhy - * Description: - * MAC starts checking its link by using parallel detection and - * Autonegotiation and the same is set in the MAC configuration registers - * Arguments: - * p_mac - pointer to struct AT91S_EMAC - * Return value: - * TRUE - if link status set succesfully - * FALSE - if link status not set - */ -unsigned char bcm5221_InitPhy (AT91PS_EMAC p_mac) -{ - unsigned char ret = TRUE; - unsigned short IntValue; - - at91rm9200_EmacEnableMDIO (p_mac); - - if (!bcm5221_GetLinkSpeed (p_mac)) { - /* Try another time */ - ret = bcm5221_GetLinkSpeed (p_mac); - } - - /* Disable PHY Interrupts */ - at91rm9200_EmacReadPhy (p_mac, BCM5221_INTR, &IntValue); - /* clear FDX LED and INTR Enable */ - IntValue &= ~(BCM5221_FDX_LED | BCM5221_INTR_ENABLE); - /* set FDX, SPD, Link, INTR masks */ - IntValue |= (BCM5221_FDX_MASK | BCM5221_SPD_MASK | - BCM5221_LINK_MASK | BCM5221_INTR_MASK); - at91rm9200_EmacWritePhy (p_mac, BCM5221_INTR, &IntValue); - at91rm9200_EmacDisableMDIO (p_mac); - - return (ret); -} - - -/* - * Name: - * bcm5221_AutoNegotiate - * Description: - * MAC Autonegotiates with the partner status of same is set in the - * MAC configuration registers - * Arguments: - * dev - pointer to struct net_device - * Return value: - * TRUE - if link status set successfully - * FALSE - if link status not set - */ -unsigned char bcm5221_AutoNegotiate (AT91PS_EMAC p_mac, int *status) -{ - unsigned short value; - unsigned short PhyAnar; - unsigned short PhyAnalpar; - - /* Set bcm5221 control register */ - if (!at91rm9200_EmacReadPhy (p_mac, BCM5221_BMCR, &value)) - return FALSE; - value &= ~BCM5221_AUTONEG; /* remove autonegotiation enable */ - value |= BCM5221_ISOLATE; /* Electrically isolate PHY */ - if (!at91rm9200_EmacWritePhy (p_mac, BCM5221_BMCR, &value)) - return FALSE; - - /* Set the Auto_negotiation Advertisement Register */ - /* MII advertising for 100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3 */ - PhyAnar = BCM5221_TX_FDX | BCM5221_TX_HDX | - BCM5221_10_FDX | BCM5221_10_HDX | BCM5221_AN_IEEE_802_3; - if (!at91rm9200_EmacWritePhy (p_mac, BCM5221_ANAR, &PhyAnar)) - return FALSE; - - /* Read the Control Register */ - if (!at91rm9200_EmacReadPhy (p_mac, BCM5221_BMCR, &value)) - return FALSE; - - value |= BCM5221_SPEED_SELECT | BCM5221_AUTONEG | BCM5221_DUPLEX_MODE; - if (!at91rm9200_EmacWritePhy (p_mac, BCM5221_BMCR, &value)) - return FALSE; - /* Restart Auto_negotiation */ - value |= BCM5221_RESTART_AUTONEG; - value &= ~BCM5221_ISOLATE; - if (!at91rm9200_EmacWritePhy (p_mac, BCM5221_BMCR, &value)) - return FALSE; - - /*check AutoNegotiate complete */ - udelay (10000); - at91rm9200_EmacReadPhy (p_mac, BCM5221_BMSR, &value); - if (!(value & BCM5221_AUTONEG_COMP)) - return FALSE; - - /* Get the AutoNeg Link partner base page */ - if (!at91rm9200_EmacReadPhy (p_mac, BCM5221_ANLPAR, &PhyAnalpar)) - return FALSE; - - if ((PhyAnar & BCM5221_TX_FDX) && (PhyAnalpar & BCM5221_TX_FDX)) { - /*set MII for 100BaseTX and Full Duplex */ - p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD; - return TRUE; - } - - if ((PhyAnar & BCM5221_10_FDX) && (PhyAnalpar & BCM5221_10_FDX)) { - /*set MII for 10BaseT and Full Duplex */ - p_mac->EMAC_CFG = (p_mac->EMAC_CFG & - ~(AT91C_EMAC_SPD | AT91C_EMAC_FD)) - | AT91C_EMAC_FD; - return TRUE; - } - return FALSE; -} - -#endif - -#endif /* CONFIG_DRIVER_ETHER */ diff --git a/cpu/arm920t/at91rm9200/dm9161.c b/cpu/arm920t/at91rm9200/dm9161.c deleted file mode 100644 index 6d4384f41a..0000000000 --- a/cpu/arm920t/at91rm9200/dm9161.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * (C) Copyright 2003 - * Author : Hamid Ikdoumi (Atmel) - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#ifdef CONFIG_DRIVER_ETHER -#include - -#if defined(CONFIG_CMD_NET) - -/* - * Name: - * dm9161_IsPhyConnected - * Description: - * Reads the 2 PHY ID registers - * Arguments: - * p_mac - pointer to AT91S_EMAC struct - * Return value: - * TRUE - if id read successfully - * FALSE- if error - */ -unsigned int dm9161_IsPhyConnected (AT91PS_EMAC p_mac) -{ - unsigned short Id1, Id2; - - at91rm9200_EmacEnableMDIO (p_mac); - at91rm9200_EmacReadPhy (p_mac, DM9161_PHYID1, &Id1); - at91rm9200_EmacReadPhy (p_mac, DM9161_PHYID2, &Id2); - at91rm9200_EmacDisableMDIO (p_mac); - - if ((Id1 == (DM9161_PHYID1_OUI >> 6)) && - ((Id2 >> 10) == (DM9161_PHYID1_OUI & DM9161_LSB_MASK))) - return TRUE; - - return FALSE; -} - -/* - * Name: - * dm9161_GetLinkSpeed - * Description: - * Link parallel detection status of MAC is checked and set in the - * MAC configuration registers - * Arguments: - * p_mac - pointer to MAC - * Return value: - * TRUE - if link status set succesfully - * FALSE - if link status not set - */ -UCHAR dm9161_GetLinkSpeed (AT91PS_EMAC p_mac) -{ - unsigned short stat1, stat2; - - if (!at91rm9200_EmacReadPhy (p_mac, DM9161_BMSR, &stat1)) - return FALSE; - - if (!(stat1 & DM9161_LINK_STATUS)) /* link status up? */ - return FALSE; - - if (!at91rm9200_EmacReadPhy (p_mac, DM9161_DSCSR, &stat2)) - return FALSE; - - if ((stat1 & DM9161_100BASE_TX_FD) && (stat2 & DM9161_100FDX)) { - /*set Emac for 100BaseTX and Full Duplex */ - p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD; - return TRUE; - } - - if ((stat1 & DM9161_10BASE_T_FD) && (stat2 & DM9161_10FDX)) { - /*set MII for 10BaseT and Full Duplex */ - p_mac->EMAC_CFG = (p_mac->EMAC_CFG & - ~(AT91C_EMAC_SPD | AT91C_EMAC_FD)) - | AT91C_EMAC_FD; - return TRUE; - } - - if ((stat1 & DM9161_100BASE_TX_HD) && (stat2 & DM9161_100HDX)) { - /*set MII for 100BaseTX and Half Duplex */ - p_mac->EMAC_CFG = (p_mac->EMAC_CFG & - ~(AT91C_EMAC_SPD | AT91C_EMAC_FD)) - | AT91C_EMAC_SPD; - return TRUE; - } - - if ((stat1 & DM9161_10BASE_T_HD) && (stat2 & DM9161_10HDX)) { - /*set MII for 10BaseT and Half Duplex */ - p_mac->EMAC_CFG &= ~(AT91C_EMAC_SPD | AT91C_EMAC_FD); - return TRUE; - } - return FALSE; -} - - -/* - * Name: - * dm9161_InitPhy - * Description: - * MAC starts checking its link by using parallel detection and - * Autonegotiation and the same is set in the MAC configuration registers - * Arguments: - * p_mac - pointer to struct AT91S_EMAC - * Return value: - * TRUE - if link status set succesfully - * FALSE - if link status not set - */ -UCHAR dm9161_InitPhy (AT91PS_EMAC p_mac) -{ - UCHAR ret = TRUE; - unsigned short IntValue; - - at91rm9200_EmacEnableMDIO (p_mac); - - if (!dm9161_GetLinkSpeed (p_mac)) { - /* Try another time */ - ret = dm9161_GetLinkSpeed (p_mac); - } - - /* Disable PHY Interrupts */ - at91rm9200_EmacReadPhy (p_mac, DM9161_MDINTR, &IntValue); - /* set FDX, SPD, Link, INTR masks */ - IntValue |= (DM9161_FDX_MASK | DM9161_SPD_MASK | - DM9161_LINK_MASK | DM9161_INTR_MASK); - at91rm9200_EmacWritePhy (p_mac, DM9161_MDINTR, &IntValue); - at91rm9200_EmacDisableMDIO (p_mac); - - return (ret); -} - - -/* - * Name: - * dm9161_AutoNegotiate - * Description: - * MAC Autonegotiates with the partner status of same is set in the - * MAC configuration registers - * Arguments: - * dev - pointer to struct net_device - * Return value: - * TRUE - if link status set successfully - * FALSE - if link status not set - */ -UCHAR dm9161_AutoNegotiate (AT91PS_EMAC p_mac, int *status) -{ - unsigned short value; - unsigned short PhyAnar; - unsigned short PhyAnalpar; - - /* Set dm9161 control register */ - if (!at91rm9200_EmacReadPhy (p_mac, DM9161_BMCR, &value)) - return FALSE; - value &= ~DM9161_AUTONEG; /* remove autonegotiation enable */ - value |= DM9161_ISOLATE; /* Electrically isolate PHY */ - if (!at91rm9200_EmacWritePhy (p_mac, DM9161_BMCR, &value)) - return FALSE; - - /* Set the Auto_negotiation Advertisement Register */ - /* MII advertising for Next page, 100BaseTxFD and HD, */ - /* 10BaseTFD and HD, IEEE 802.3 */ - PhyAnar = DM9161_NP | DM9161_TX_FDX | DM9161_TX_HDX | - DM9161_10_FDX | DM9161_10_HDX | DM9161_AN_IEEE_802_3; - if (!at91rm9200_EmacWritePhy (p_mac, DM9161_ANAR, &PhyAnar)) - return FALSE; - - /* Read the Control Register */ - if (!at91rm9200_EmacReadPhy (p_mac, DM9161_BMCR, &value)) - return FALSE; - - value |= DM9161_SPEED_SELECT | DM9161_AUTONEG | DM9161_DUPLEX_MODE; - if (!at91rm9200_EmacWritePhy (p_mac, DM9161_BMCR, &value)) - return FALSE; - /* Restart Auto_negotiation */ - value |= DM9161_RESTART_AUTONEG; - value &= ~DM9161_ISOLATE; - if (!at91rm9200_EmacWritePhy (p_mac, DM9161_BMCR, &value)) - return FALSE; - - /*check AutoNegotiate complete */ - udelay (10000); - at91rm9200_EmacReadPhy (p_mac, DM9161_BMSR, &value); - if (!(value & DM9161_AUTONEG_COMP)) - return FALSE; - - /* Get the AutoNeg Link partner base page */ - if (!at91rm9200_EmacReadPhy (p_mac, DM9161_ANLPAR, &PhyAnalpar)) - return FALSE; - - if ((PhyAnar & DM9161_TX_FDX) && (PhyAnalpar & DM9161_TX_FDX)) { - /*set MII for 100BaseTX and Full Duplex */ - p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD; - return TRUE; - } - - if ((PhyAnar & DM9161_10_FDX) && (PhyAnalpar & DM9161_10_FDX)) { - /*set MII for 10BaseT and Full Duplex */ - p_mac->EMAC_CFG = (p_mac->EMAC_CFG & - ~(AT91C_EMAC_SPD | AT91C_EMAC_FD)) - | AT91C_EMAC_FD; - return TRUE; - } - return FALSE; -} - -#endif - -#endif /* CONFIG_DRIVER_ETHER */ diff --git a/cpu/arm920t/at91rm9200/ether.c b/cpu/arm920t/at91rm9200/ether.c deleted file mode 100644 index 91eab95eed..0000000000 --- a/cpu/arm920t/at91rm9200/ether.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * (C) Copyright 2003 - * Author : Hamid Ikdoumi (Atmel) - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include - -/* ----- Ethernet Buffer definitions ----- */ - -typedef struct { - unsigned long addr, size; -} rbf_t; - -#define RBF_ADDR 0xfffffffc -#define RBF_OWNER (1<<0) -#define RBF_WRAP (1<<1) -#define RBF_BROADCAST (1<<31) -#define RBF_MULTICAST (1<<30) -#define RBF_UNICAST (1<<29) -#define RBF_EXTERNAL (1<<28) -#define RBF_UNKOWN (1<<27) -#define RBF_SIZE 0x07ff -#define RBF_LOCAL4 (1<<26) -#define RBF_LOCAL3 (1<<25) -#define RBF_LOCAL2 (1<<24) -#define RBF_LOCAL1 (1<<23) - -#define RBF_FRAMEMAX 64 -#define RBF_FRAMELEN 0x600 - -#ifdef CONFIG_DRIVER_ETHER - -#if defined(CONFIG_CMD_NET) - -/* alignment as per Errata #11 (64 bytes) is insufficient! */ -rbf_t rbfdt[RBF_FRAMEMAX] __attribute__((aligned(512))); -rbf_t *rbfp; - -unsigned char rbf_framebuf[RBF_FRAMEMAX][RBF_FRAMELEN] - __attribute__((aligned(4))); - -/* structure to interface the PHY */ -AT91S_PhyOps PhyOps; - -AT91PS_EMAC p_mac; - -/*********** EMAC Phy layer Management functions *************************/ -/* - * Name: - * at91rm9200_EmacEnableMDIO - * Description: - * Enables the MDIO bit in MAC control register - * Arguments: - * p_mac - pointer to struct AT91S_EMAC - * Return value: - * none - */ -void at91rm9200_EmacEnableMDIO (AT91PS_EMAC p_mac) -{ - /* Mac CTRL reg set for MDIO enable */ - p_mac->EMAC_CTL |= AT91C_EMAC_MPE; /* Management port enable */ -} - -/* - * Name: - * at91rm9200_EmacDisableMDIO - * Description: - * Disables the MDIO bit in MAC control register - * Arguments: - * p_mac - pointer to struct AT91S_EMAC - * Return value: - * none - */ -void at91rm9200_EmacDisableMDIO (AT91PS_EMAC p_mac) -{ - /* Mac CTRL reg set for MDIO disable */ - p_mac->EMAC_CTL &= ~AT91C_EMAC_MPE; /* Management port disable */ -} - - -/* - * Name: - * at91rm9200_EmacReadPhy - * Description: - * Reads data from the PHY register - * Arguments: - * dev - pointer to struct net_device - * RegisterAddress - unsigned char - * pInput - pointer to value read from register - * Return value: - * TRUE - if data read successfully - */ -UCHAR at91rm9200_EmacReadPhy (AT91PS_EMAC p_mac, - unsigned char RegisterAddress, - unsigned short *pInput) -{ - p_mac->EMAC_MAN = (AT91C_EMAC_HIGH & ~AT91C_EMAC_LOW) | - (AT91C_EMAC_RW_R) | - (RegisterAddress << 18) | - (AT91C_EMAC_CODE_802_3); - - udelay (10000); - - *pInput = (unsigned short) p_mac->EMAC_MAN; - - return TRUE; -} - - -/* - * Name: - * at91rm9200_EmacWritePhy - * Description: - * Writes data to the PHY register - * Arguments: - * dev - pointer to struct net_device - * RegisterAddress - unsigned char - * pOutput - pointer to value to be written in the register - * Return value: - * TRUE - if data read successfully - */ -UCHAR at91rm9200_EmacWritePhy (AT91PS_EMAC p_mac, - unsigned char RegisterAddress, - unsigned short *pOutput) -{ - p_mac->EMAC_MAN = (AT91C_EMAC_HIGH & ~AT91C_EMAC_LOW) | - AT91C_EMAC_CODE_802_3 | AT91C_EMAC_RW_W | - (RegisterAddress << 18) | *pOutput; - - udelay (10000); - - return TRUE; -} - -int eth_init (bd_t * bd) -{ - int ret; - int i; - uchar enetaddr[6]; - - p_mac = AT91C_BASE_EMAC; - - /* PIO Disable Register */ - *AT91C_PIOA_PDR = AT91C_PA16_EMDIO | AT91C_PA15_EMDC | AT91C_PA14_ERXER | - AT91C_PA13_ERX1 | AT91C_PA12_ERX0 | AT91C_PA11_ECRS_ECRSDV | - AT91C_PA10_ETX1 | AT91C_PA9_ETX0 | AT91C_PA8_ETXEN | - AT91C_PA7_ETXCK_EREFCK; - -#ifdef CONFIG_AT91C_USE_RMII - *AT91C_PIOB_PDR = AT91C_PB19_ERXCK; - *AT91C_PIOB_BSR = AT91C_PB19_ERXCK; -#else - *AT91C_PIOB_PDR = AT91C_PB19_ERXCK | AT91C_PB18_ECOL | AT91C_PB17_ERXDV | - AT91C_PB16_ERX3 | AT91C_PB15_ERX2 | AT91C_PB14_ETXER | - AT91C_PB13_ETX3 | AT91C_PB12_ETX2; - - /* Select B Register */ - *AT91C_PIOB_BSR = AT91C_PB19_ERXCK | AT91C_PB18_ECOL | - AT91C_PB17_ERXDV | AT91C_PB16_ERX3 | AT91C_PB15_ERX2 | - AT91C_PB14_ETXER | AT91C_PB13_ETX3 | AT91C_PB12_ETX2; -#endif - - *AT91C_PMC_PCER = 1 << AT91C_ID_EMAC; /* Peripheral Clock Enable Register */ - - p_mac->EMAC_CFG |= AT91C_EMAC_CSR; /* Clear statistics */ - - /* Init Ethernet buffers */ - for (i = 0; i < RBF_FRAMEMAX; i++) { - rbfdt[i].addr = (unsigned long)rbf_framebuf[i]; - rbfdt[i].size = 0; - } - rbfdt[RBF_FRAMEMAX - 1].addr |= RBF_WRAP; - rbfp = &rbfdt[0]; - - eth_getenv_enetaddr("ethaddr", enetaddr); - - /* The CSB337 originally used a version of the MicroMonitor bootloader - * which saved Ethernet addresses in the "wrong" order. Operating - * systems (like Linux) know this, and apply a workaround. Replicate - * that MicroMonitor behavior so we avoid needing to make such OS code - * care about which bootloader was used. - */ - if (machine_is_csb337()) { - p_mac->EMAC_SA2H = (enetaddr[0] << 8) | (enetaddr[1]); - p_mac->EMAC_SA2L = (enetaddr[2] << 24) | (enetaddr[3] << 16) - | (enetaddr[4] << 8) | (enetaddr[5]); - } else { - p_mac->EMAC_SA2L = (enetaddr[3] << 24) | (enetaddr[2] << 16) - | (enetaddr[1] << 8) | (enetaddr[0]); - p_mac->EMAC_SA2H = (enetaddr[5] << 8) | (enetaddr[4]); - } - - p_mac->EMAC_RBQP = (long) (&rbfdt[0]); - p_mac->EMAC_RSR &= ~(AT91C_EMAC_RSR_OVR | AT91C_EMAC_REC | AT91C_EMAC_BNA); - - p_mac->EMAC_CFG = (p_mac->EMAC_CFG | AT91C_EMAC_CAF | AT91C_EMAC_NBC) - & ~AT91C_EMAC_CLK; - -#ifdef CONFIG_AT91C_USE_RMII - p_mac->EMAC_CFG |= AT91C_EMAC_RMII; -#endif - -#if (AT91C_MASTER_CLOCK > 40000000) - /* MDIO clock must not exceed 2.5 MHz, so enable MCK divider */ - p_mac->EMAC_CFG |= AT91C_EMAC_CLK_HCLK_64; -#endif - - p_mac->EMAC_CTL |= AT91C_EMAC_TE | AT91C_EMAC_RE; - - at91rm9200_GetPhyInterface (& PhyOps); - - if (!PhyOps.IsPhyConnected (p_mac)) - printf ("PHY not connected!!\n\r"); - - /* MII management start from here */ - if (!(p_mac->EMAC_SR & AT91C_EMAC_LINK)) { - if (!(ret = PhyOps.Init (p_mac))) { - printf ("MAC: error during MII initialization\n"); - return 0; - } - } else { - printf ("No link\n\r"); - return 0; - } - - return 0; -} - -int eth_send (volatile void *packet, int length) -{ - while (!(p_mac->EMAC_TSR & AT91C_EMAC_BNQ)); - p_mac->EMAC_TAR = (long) packet; - p_mac->EMAC_TCR = length; - while (p_mac->EMAC_TCR & 0x7ff); - p_mac->EMAC_TSR |= AT91C_EMAC_COMP; - return 0; -} - -int eth_rx (void) -{ - int size; - - if (!(rbfp->addr & RBF_OWNER)) - return 0; - - size = rbfp->size & RBF_SIZE; - NetReceive ((volatile uchar *) (rbfp->addr & RBF_ADDR), size); - - rbfp->addr &= ~RBF_OWNER; - if (rbfp->addr & RBF_WRAP) - rbfp = &rbfdt[0]; - else - rbfp++; - - p_mac->EMAC_RSR |= AT91C_EMAC_REC; - - return size; -} - -void eth_halt (void) -{ -}; - -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) -int at91rm9200_miiphy_read(char *devname, unsigned char addr, - unsigned char reg, unsigned short * value) -{ - at91rm9200_EmacEnableMDIO (p_mac); - at91rm9200_EmacReadPhy (p_mac, reg, value); - at91rm9200_EmacDisableMDIO (p_mac); - return 0; -} - -int at91rm9200_miiphy_write(char *devname, unsigned char addr, - unsigned char reg, unsigned short value) -{ - at91rm9200_EmacEnableMDIO (p_mac); - at91rm9200_EmacWritePhy (p_mac, reg, &value); - at91rm9200_EmacDisableMDIO (p_mac); - return 0; -} - -#endif - -int at91rm9200_miiphy_initialize(bd_t *bis) -{ -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) - miiphy_register("at91rm9200phy", at91rm9200_miiphy_read, at91rm9200_miiphy_write); -#endif - return 0; -} - -#endif - -#endif /* CONFIG_DRIVER_ETHER */ diff --git a/cpu/arm920t/at91rm9200/i2c.c b/cpu/arm920t/at91rm9200/i2c.c deleted file mode 100644 index 1711088ad3..0000000000 --- a/cpu/arm920t/at91rm9200/i2c.c +++ /dev/null @@ -1,192 +0,0 @@ -/* - * i2c Support for Atmel's AT91RM9200 Two-Wire Interface - * - * (c) Rick Bronson - * - * Borrowed heavily from original work by: - * Copyright (c) 2000 Philip Edelbrock - * - * Modified to work with u-boot by (C) 2004 Gary Jennejohn garyj@denx.de - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * -*/ -#include - -#ifdef CONFIG_HARD_I2C - -#include -#include -#include - -#include - -/* define DEBUG */ - -/* - * Poll the i2c status register until the specified bit is set. - * Returns 0 if timed out (100 msec) - */ -static short at91_poll_status(AT91PS_TWI twi, unsigned long bit) { - int loop_cntr = 10000; - do { - udelay(10); - } while (!(twi->TWI_SR & bit) && (--loop_cntr > 0)); - - return (loop_cntr > 0); -} - -/* - * Generic i2c master transfer entrypoint - * - * rw == 1 means that this is a read - */ -static int -at91_xfer(unsigned char chip, unsigned int addr, int alen, - unsigned char *buffer, int len, int rw) -{ - AT91PS_TWI twi = (AT91PS_TWI) AT91_TWI_BASE; - int length; - unsigned char *buf; - /* Set the TWI Master Mode Register */ - twi->TWI_MMR = (chip << 16) | (alen << 8) - | ((rw == 1) ? AT91C_TWI_MREAD : 0); - - /* Set TWI Internal Address Register with first messages data field */ - if (alen > 0) - twi->TWI_IADR = addr; - - length = len; - buf = buffer; - if (length && buf) { /* sanity check */ - if (rw) { - twi->TWI_CR = AT91C_TWI_START; - while (length--) { - if (!length) - twi->TWI_CR = AT91C_TWI_STOP; - /* Wait until transfer is finished */ - if (!at91_poll_status(twi, AT91C_TWI_RXRDY)) { - debug ("at91_i2c: timeout 1\n"); - return 1; - } - *buf++ = twi->TWI_RHR; - } - if (!at91_poll_status(twi, AT91C_TWI_TXCOMP)) { - debug ("at91_i2c: timeout 2\n"); - return 1; - } - } else { - twi->TWI_CR = AT91C_TWI_START; - while (length--) { - twi->TWI_THR = *buf++; - if (!length) - twi->TWI_CR = AT91C_TWI_STOP; - if (!at91_poll_status(twi, AT91C_TWI_TXRDY)) { - debug ("at91_i2c: timeout 3\n"); - return 1; - } - } - /* Wait until transfer is finished */ - if (!at91_poll_status(twi, AT91C_TWI_TXCOMP)) { - debug ("at91_i2c: timeout 4\n"); - return 1; - } - } - } - return 0; -} - -int -i2c_probe(unsigned char chip) -{ - unsigned char buffer[1]; - - return at91_xfer(chip, 0, 0, buffer, 1, 1); -} - -int -i2c_read (unsigned char chip, unsigned int addr, int alen, - unsigned char *buffer, int len) -{ -#ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW - /* we only allow one address byte */ - if (alen > 1) - return 1; - /* XXX assume an ATMEL AT24C16 */ - if (alen == 1) { -#if 0 /* EEPROM code already sets this correctly */ - chip |= (addr >> 8) & 0xff; -#endif - addr = addr & 0xff; - } -#endif - return at91_xfer(chip, addr, alen, buffer, len, 1); -} - -int -i2c_write(unsigned char chip, unsigned int addr, int alen, - unsigned char *buffer, int len) -{ -#ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW - int i; - unsigned char *buf; - - /* we only allow one address byte */ - if (alen > 1) - return 1; - /* XXX assume an ATMEL AT24C16 */ - if (alen == 1) { - buf = buffer; - /* do single byte writes */ - for (i = 0; i < len; i++) { -#if 0 /* EEPROM code already sets this correctly */ - chip |= (addr >> 8) & 0xff; -#endif - addr = addr & 0xff; - if (at91_xfer(chip, addr, alen, buf++, 1, 0)) - return 1; - addr++; - } - return 0; - } -#endif - return at91_xfer(chip, addr, alen, buffer, len, 0); -} - -/* - * Main initialization routine - */ -void -i2c_init(int speed, int slaveaddr) -{ - AT91PS_TWI twi = (AT91PS_TWI) AT91_TWI_BASE; - - *AT91C_PIOA_PDR = AT91C_PA25_TWD | AT91C_PA26_TWCK; - *AT91C_PIOA_ASR = AT91C_PA25_TWD | AT91C_PA26_TWCK; - *AT91C_PIOA_MDER = AT91C_PA25_TWD | AT91C_PA26_TWCK; - *AT91C_PMC_PCER = 1 << AT91C_ID_TWI; /* enable peripheral clock */ - - twi->TWI_IDR = 0x3ff; /* Disable all interrupts */ - twi->TWI_CR = AT91C_TWI_SWRST; /* Reset peripheral */ - twi->TWI_CR = AT91C_TWI_MSEN | AT91C_TWI_SVDIS; /* Set Master mode */ - - /* Here, CKDIV = 1 and CHDIV=CLDIV ==> CLDIV = CHDIV = 1/4*((Fmclk/FTWI) -6) */ - twi->TWI_CWGR = AT91C_TWI_CKDIV1 | AT91C_TWI_CLDIV3 | (AT91C_TWI_CLDIV3 << 8); - - debug ("Found AT91 i2c\n"); - return; -} - -#endif /* CONFIG_HARD_I2C */ diff --git a/cpu/arm920t/at91rm9200/ks8721.c b/cpu/arm920t/at91rm9200/ks8721.c deleted file mode 100644 index 9fe379369a..0000000000 --- a/cpu/arm920t/at91rm9200/ks8721.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - * (C) Copyright 2006 - * Author : Eric Benard (Eukrea Electromatique) - * based on dm9161.c which is : - * (C) Copyright 2003 - * Author : Hamid Ikdoumi (Atmel) - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -#ifdef CONFIG_DRIVER_ETHER - -#if defined(CONFIG_CMD_NET) - -/* - * Name: - * ks8721_isphyconnected - * Description: - * Reads the 2 PHY ID registers - * Arguments: - * p_mac - pointer to AT91S_EMAC struct - * Return value: - * 1 - if id read successfully - * 0 - if error - */ -unsigned int ks8721_isphyconnected(AT91PS_EMAC p_mac) -{ - unsigned short id1, id2; - - at91rm9200_EmacEnableMDIO(p_mac); - at91rm9200_EmacReadPhy(p_mac, - CONFIG_PHY_ADDRESS | KS8721_PHYID1, &id1); - at91rm9200_EmacReadPhy(p_mac, - CONFIG_PHY_ADDRESS | KS8721_PHYID2, &id2); - at91rm9200_EmacDisableMDIO(p_mac); - - if ((id1 == (KS8721_PHYID_OUI >> 6)) && - ((id2 >> 10) == (KS8721_PHYID_OUI & KS8721_LSB_MASK))) { - if ((id2 & KS8721_MODELMASK) == KS8721BL_MODEL) - printf("Micrel KS8721bL PHY detected : "); - else - printf("Unknown Micrel PHY detected : "); - return 1; - } - return 0; -} - -/* - * Name: - * ks8721_getlinkspeed - * Description: - * Link parallel detection status of MAC is checked and set in the - * MAC configuration registers - * Arguments: - * p_mac - pointer to MAC - * Return value: - * 1 - if link status set succesfully - * 0 - if link status not set - */ -unsigned char ks8721_getlinkspeed(AT91PS_EMAC p_mac) -{ - unsigned short stat1; - - if (!at91rm9200_EmacReadPhy(p_mac, KS8721_BMSR, &stat1)) - return 0; - - if (!(stat1 & KS8721_LINK_STATUS)) { - /* link status up? */ - printf("Link Down !\n"); - return 0; - } - - if (stat1 & KS8721_100BASE_TX_FD) { - /* set Emac for 100BaseTX and Full Duplex */ - printf("100BT FD\n"); - p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD; - return 1; - } - - if (stat1 & KS8721_10BASE_T_FD) { - /* set MII for 10BaseT and Full Duplex */ - printf("10BT FD\n"); - p_mac->EMAC_CFG = (p_mac->EMAC_CFG & - ~(AT91C_EMAC_SPD | AT91C_EMAC_FD)) - | AT91C_EMAC_FD; - return 1; - } - - if (stat1 & KS8721_100BASE_T4_HD) { - /* set MII for 100BaseTX and Half Duplex */ - printf("100BT HD\n"); - p_mac->EMAC_CFG = (p_mac->EMAC_CFG & - ~(AT91C_EMAC_SPD | AT91C_EMAC_FD)) - | AT91C_EMAC_SPD; - return 1; - } - - if (stat1 & KS8721_10BASE_T_HD) { - /* set MII for 10BaseT and Half Duplex */ - printf("10BT HD\n"); - p_mac->EMAC_CFG &= ~(AT91C_EMAC_SPD | AT91C_EMAC_FD); - return 1; - } - return 0; -} - -/* - * Name: - * ks8721_initphy - * Description: - * MAC starts checking its link by using parallel detection and - * Autonegotiation and the same is set in the MAC configuration registers - * Arguments: - * p_mac - pointer to struct AT91S_EMAC - * Return value: - * 1 - if link status set succesfully - * 0 - if link status not set - */ -unsigned char ks8721_initphy(AT91PS_EMAC p_mac) -{ - unsigned char ret = 1; - unsigned short intvalue; - - at91rm9200_EmacEnableMDIO(p_mac); - - /* Try another time */ - if (!ks8721_getlinkspeed(p_mac)) - ret = ks8721_getlinkspeed(p_mac); - - /* Disable PHY Interrupts */ - intvalue = 0; - at91rm9200_EmacWritePhy(p_mac, - CONFIG_PHY_ADDRESS | KS8721_MDINTR, &intvalue); - at91rm9200_EmacDisableMDIO(p_mac); - - return ret; -} - -/* - * Name: - * ks8721_autonegotiate - * Description: - * MAC Autonegotiates with the partner status of same is set in the - * MAC configuration registers - * Arguments: - * dev - pointer to struct net_device - * Return value: - * 1 - if link status set successfully - * 0 - if link status not set - */ -unsigned char ks8721_autonegotiate(AT91PS_EMAC p_mac, int *status) -{ - unsigned short value; - unsigned short phyanar; - unsigned short phyanalpar; - - /* Set ks8721 control register */ - if (!at91rm9200_EmacReadPhy(p_mac, - CONFIG_PHY_ADDRESS | KS8721_BMCR, &value)) - return 0; - - /* remove autonegotiation enable */ - value &= ~KS8721_AUTONEG; - /* Electrically isolate PHY */ - value |= KS8721_ISOLATE; - if (!at91rm9200_EmacWritePhy(p_mac, - CONFIG_PHY_ADDRESS | KS8721_BMCR, &value)) { - return 0; - } - /* - * Set the Auto_negotiation Advertisement Register - * MII advertising for Next page, 100BaseTxFD and HD, - * 10BaseTFD and HD, IEEE 802.3 - */ - phyanar = KS8721_NP | KS8721_TX_FDX | KS8721_TX_HDX | - KS8721_10_FDX | KS8721_10_HDX | KS8721_AN_IEEE_802_3; - if (!at91rm9200_EmacWritePhy(p_mac, - CONFIG_PHY_ADDRESS | KS8721_ANAR, &phyanar)) { - return 0; - } - /* Read the Control Register */ - if (!at91rm9200_EmacReadPhy(p_mac, - CONFIG_PHY_ADDRESS | KS8721_BMCR, &value)) { - return 0; - } - value |= KS8721_SPEED_SELECT | KS8721_AUTONEG | KS8721_DUPLEX_MODE; - if (!at91rm9200_EmacWritePhy(p_mac, - CONFIG_PHY_ADDRESS | KS8721_BMCR, &value)) { - return 0; - } - /* Restart Auto_negotiation */ - value |= KS8721_RESTART_AUTONEG; - value &= ~KS8721_ISOLATE; - if (!at91rm9200_EmacWritePhy(p_mac, - CONFIG_PHY_ADDRESS | KS8721_BMCR, &value)) { - return 0; - } - /* Check AutoNegotiate complete */ - udelay(10000); - at91rm9200_EmacReadPhy(p_mac, - CONFIG_PHY_ADDRESS | KS8721_BMSR, &value); - if (!(value & KS8721_AUTONEG_COMP)) - return 0; - - /* Get the AutoNeg Link partner base page */ - if (!at91rm9200_EmacReadPhy(p_mac, - CONFIG_PHY_ADDRESS | KS8721_ANLPAR, &phyanalpar)) { - return 0; - } - - if ((phyanar & KS8721_TX_FDX) && (phyanalpar & KS8721_TX_FDX)) { - /* Set MII for 100BaseTX and Full Duplex */ - p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD; - return 1; - } - - if ((phyanar & KS8721_10_FDX) && (phyanalpar & KS8721_10_FDX)) { - /* Set MII for 10BaseT and Full Duplex */ - p_mac->EMAC_CFG = (p_mac->EMAC_CFG & - ~(AT91C_EMAC_SPD | AT91C_EMAC_FD)) - | AT91C_EMAC_FD; - return 1; - } - return 0; -} - -#endif /* CONFIG_CMD_NET */ - -#endif /* CONFIG_DRIVER_ETHER */ diff --git a/cpu/arm920t/at91rm9200/lowlevel_init.S b/cpu/arm920t/at91rm9200/lowlevel_init.S deleted file mode 100644 index d8bb96004b..0000000000 --- a/cpu/arm920t/at91rm9200/lowlevel_init.S +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Memory Setup stuff - taken from blob memsetup.S - * - * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and - * Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl) - * - * Modified for the at91rm9200dk board by - * (C) Copyright 2004 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include - -#ifndef CONFIG_SKIP_LOWLEVEL_INIT -/* - * some parameters for the board - * - * This is based on rm9200dk.cfg for the BDI2000 from ABATRON which in - * turn is based on the boot.bin code from ATMEL - * - */ -#include - -_MTEXT_BASE: -#undef START_FROM_MEM -#ifdef START_FROM_MEM - .word TEXT_BASE-PHYS_FLASH_1 -#else - .word TEXT_BASE -#endif - -.globl lowlevel_init -lowlevel_init: - /* Get the CKGR Base Address */ - ldr r1, =AT91C_BASE_CKGR - /* Main oscillator Enable register */ -#ifdef CONFIG_SYS_USE_MAIN_OSCILLATOR - ldr r0, =0x0000FF01 /* Enable main oscillator, OSCOUNT = 0xFF */ -#else - ldr r0, =0x0000FF00 /* Disable main oscillator, OSCOUNT = 0xFF */ -#endif - str r0, [r1, #AT91C_CKGR_MOR] - /* Add loop to compensate Main Oscillator startup time */ - ldr r0, =0x00000010 -LoopOsc: - subs r0, r0, #1 - bhi LoopOsc - - /* memory control configuration */ - /* this isn't very elegant, but what the heck */ - ldr r0, =SMRDATA - ldr r1, _MTEXT_BASE - sub r0, r0, r1 - add r2, r0, #80 -0: - /* the address */ - ldr r1, [r0], #4 - /* the value */ - ldr r3, [r0], #4 - str r3, [r1] - cmp r2, r0 - bne 0b - /* delay - this is all done by guess */ - ldr r0, =0x00010000 - /* (vs reading PMC_SR for LOCKA, LOCKB ... or MOSCS earlier) */ -1: - subs r0, r0, #1 - bhi 1b - ldr r0, =SMRDATA1 - ldr r1, _MTEXT_BASE - sub r0, r0, r1 - add r2, r0, #176 -2: - /* the address */ - ldr r1, [r0], #4 - /* the value */ - ldr r3, [r0], #4 - str r3, [r1] - cmp r2, r0 - bne 2b - - /* switch from FastBus to Asynchronous clock mode */ - mrc p15, 0, r0, c1, c0, 0 - orr r0, r0, #0xC0000000 @ set bit 31 (iA) and 30 (nF) - mcr p15, 0, r0, c1, c0, 0 - - /* everything is fine now */ - mov pc, lr - - .ltorg - -SMRDATA: - .word AT91C_EBI_CFGR - .word CONFIG_SYS_EBI_CFGR_VAL - .word AT91C_SMC_CSR0 - .word CONFIG_SYS_SMC_CSR0_VAL - .word AT91C_PLLAR - .word CONFIG_SYS_PLLAR_VAL - .word AT91C_PLLBR - .word CONFIG_SYS_PLLBR_VAL - .word AT91C_MCKR - .word CONFIG_SYS_MCKR_VAL - /* here there's a delay */ -SMRDATA1: - .word AT91C_PIOC_ASR - .word CONFIG_SYS_PIOC_ASR_VAL - .word AT91C_PIOC_BSR - .word CONFIG_SYS_PIOC_BSR_VAL - .word AT91C_PIOC_PDR - .word CONFIG_SYS_PIOC_PDR_VAL - .word AT91C_EBI_CSA - .word CONFIG_SYS_EBI_CSA_VAL - .word AT91C_SDRC_CR - .word CONFIG_SYS_SDRC_CR_VAL - .word AT91C_SDRC_MR - .word CONFIG_SYS_SDRC_MR_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word AT91C_SDRC_MR - .word CONFIG_SYS_SDRC_MR_VAL1 - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word AT91C_SDRC_MR - .word CONFIG_SYS_SDRC_MR_VAL2 - .word CONFIG_SYS_SDRAM1 - .word CONFIG_SYS_SDRAM_VAL - .word AT91C_SDRC_TR - .word CONFIG_SYS_SDRC_TR_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word AT91C_SDRC_MR - .word CONFIG_SYS_SDRC_MR_VAL3 - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - /* SMRDATA1 is 176 bytes long */ -#endif /* CONFIG_SKIP_LOWLEVEL_INIT */ diff --git a/cpu/arm920t/at91rm9200/lxt972.c b/cpu/arm920t/at91rm9200/lxt972.c deleted file mode 100644 index 260d393cf0..0000000000 --- a/cpu/arm920t/at91rm9200/lxt972.c +++ /dev/null @@ -1,192 +0,0 @@ -/* - * - * (C) Copyright 2003 - * Author : Hamid Ikdoumi (Atmel) - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * Adapted for KwikByte KB920x board: 22APR2005 - */ - -#include -#include -#include -#include -#include - -#ifdef CONFIG_DRIVER_ETHER - -#if defined(CONFIG_CMD_NET) - -/* - * Name: - * lxt972_IsPhyConnected - * Description: - * Reads the 2 PHY ID registers - * Arguments: - * p_mac - pointer to AT91S_EMAC struct - * Return value: - * TRUE - if id read successfully - * FALSE- if error - */ -unsigned int lxt972_IsPhyConnected (AT91PS_EMAC p_mac) -{ - unsigned short Id1, Id2; - - at91rm9200_EmacEnableMDIO (p_mac); - at91rm9200_EmacReadPhy(p_mac, PHY_PHYIDR1, &Id1); - at91rm9200_EmacReadPhy(p_mac, PHY_PHYIDR2, &Id2); - at91rm9200_EmacDisableMDIO (p_mac); - - if ((Id1 == (0x0013)) && ((Id2 & 0xFFF0) == 0x78E0)) - return TRUE; - - return FALSE; -} - -/* - * Name: - * lxt972_GetLinkSpeed - * Description: - * Link parallel detection status of MAC is checked and set in the - * MAC configuration registers - * Arguments: - * p_mac - pointer to MAC - * Return value: - * TRUE - if link status set succesfully - * FALSE - if link status not set - */ -UCHAR lxt972_GetLinkSpeed (AT91PS_EMAC p_mac) -{ - unsigned short stat1; - - if (!at91rm9200_EmacReadPhy (p_mac, PHY_LXT971_STAT2, &stat1)) - return FALSE; - - if (!(stat1 & PHY_LXT971_STAT2_LINK)) /* link status up? */ - return FALSE; - - if (stat1 & PHY_LXT971_STAT2_100BTX) { - - if (stat1 & PHY_LXT971_STAT2_DUPLEX_MODE) { - - /*set Emac for 100BaseTX and Full Duplex */ - p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD; - } else { - - /*set Emac for 100BaseTX and Half Duplex */ - p_mac->EMAC_CFG = (p_mac->EMAC_CFG & - ~(AT91C_EMAC_SPD | AT91C_EMAC_FD)) - | AT91C_EMAC_SPD; - } - - return TRUE; - - } else { - - if (stat1 & PHY_LXT971_STAT2_DUPLEX_MODE) { - - /*set MII for 10BaseT and Full Duplex */ - p_mac->EMAC_CFG = (p_mac->EMAC_CFG & - ~(AT91C_EMAC_SPD | AT91C_EMAC_FD)) - | AT91C_EMAC_FD; - } else { - - /*set MII for 10BaseT and Half Duplex */ - p_mac->EMAC_CFG &= ~(AT91C_EMAC_SPD | AT91C_EMAC_FD); - } - - return TRUE; - } - - return FALSE; -} - - -/* - * Name: - * lxt972_InitPhy - * Description: - * MAC starts checking its link by using parallel detection and - * Autonegotiation and the same is set in the MAC configuration registers - * Arguments: - * p_mac - pointer to struct AT91S_EMAC - * Return value: - * TRUE - if link status set succesfully - * FALSE - if link status not set - */ -UCHAR lxt972_InitPhy (AT91PS_EMAC p_mac) -{ - UCHAR ret = TRUE; - - at91rm9200_EmacEnableMDIO (p_mac); - - if (!lxt972_GetLinkSpeed (p_mac)) { - /* Try another time */ - ret = lxt972_GetLinkSpeed (p_mac); - } - - /* Disable PHY Interrupts */ - at91rm9200_EmacWritePhy (p_mac, PHY_LXT971_INT_ENABLE, 0); - - at91rm9200_EmacDisableMDIO (p_mac); - - return (ret); -} - - -/* - * Name: - * lxt972_AutoNegotiate - * Description: - * MAC Autonegotiates with the partner status of same is set in the - * MAC configuration registers - * Arguments: - * dev - pointer to struct net_device - * Return value: - * TRUE - if link status set successfully - * FALSE - if link status not set - */ -UCHAR lxt972_AutoNegotiate (AT91PS_EMAC p_mac, int *status) -{ - unsigned short value; - - /* Set lxt972 control register */ - if (!at91rm9200_EmacReadPhy (p_mac, PHY_BMCR, &value)) - return FALSE; - - /* Restart Auto_negotiation */ - value |= PHY_BMCR_RST_NEG; - if (!at91rm9200_EmacWritePhy (p_mac, PHY_BMCR, &value)) - return FALSE; - - /*check AutoNegotiate complete */ - udelay (10000); - at91rm9200_EmacReadPhy(p_mac, PHY_BMSR, &value); - if (!(value & PHY_BMSR_AUTN_COMP)) - return FALSE; - - return (lxt972_GetLinkSpeed (p_mac)); -} - -#endif - -#endif /* CONFIG_DRIVER_ETHER */ diff --git a/cpu/arm920t/at91rm9200/reset.c b/cpu/arm920t/at91rm9200/reset.c deleted file mode 100644 index 945ea2c248..0000000000 --- a/cpu/arm920t/at91rm9200/reset.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * (C) Copyright 2002 - * Lineo, Inc. - * Bernhard Kuhn - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include - -void board_reset(void) __attribute__((__weak__)); - -/* - * Reset the cpu by setting up the watchdog timer and let him time out - * or toggle a GPIO pin on the AT91RM9200DK board - */ -void reset_cpu (ulong ignored) -{ - -#if defined(CONFIG_AT91RM9200_USART) - /*shutdown the console to avoid strange chars during reset */ - serial_exit(); -#endif - - if (board_reset) - board_reset(); - - /* this is the way Linux does it */ - - /* FIXME: - * These defines should be moved into - * include/asm-arm/arch-at91rm9200/AT91RM9200.h - * as soon as the whitespace fix gets applied. - */ - #define AT91C_ST_RSTEN (0x1 << 16) - #define AT91C_ST_EXTEN (0x1 << 17) - #define AT91C_ST_WDRST (0x1 << 0) - #define ST_WDMR *((unsigned long *)0xfffffd08) /* watchdog mode register */ - #define ST_CR *((unsigned long *)0xfffffd00) /* system clock control register */ - - ST_WDMR = AT91C_ST_RSTEN | AT91C_ST_EXTEN | 1 ; - ST_CR = AT91C_ST_WDRST; - - while (1); - /* Never reached */ -} diff --git a/cpu/arm920t/at91rm9200/spi.c b/cpu/arm920t/at91rm9200/spi.c deleted file mode 100644 index f3cb5d8c2c..0000000000 --- a/cpu/arm920t/at91rm9200/spi.c +++ /dev/null @@ -1,151 +0,0 @@ -/* Driver for ATMEL DataFlash support - * Author : Hamid Ikdoumi (Atmel) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - */ - -#include -#include -#include - -#ifdef CONFIG_HAS_DATAFLASH -#include - -#define AT91C_SPI_CLK 10000000 /* Max Value = 10MHz to be compliant to - the Continuous Array Read function */ - -/* AC Characteristics */ -/* DLYBS = tCSS = 250ns min and DLYBCT = tCSH = 250ns */ -#define DATAFLASH_TCSS (0xC << 16) -#define DATAFLASH_TCHS (0x1 << 24) - -#define AT91C_TIMEOUT_WRDY 200000 -#define AT91C_SPI_PCS0_SERIAL_DATAFLASH 0xE /* Chip Select 0: NPCS0%1110 */ -#define AT91C_SPI_PCS3_DATAFLASH_CARD 0x7 /* Chip Select 3: NPCS3%0111 */ - -/*-------------------------------------------------------------------*/ -/* SPI DataFlash Init */ -/*-------------------------------------------------------------------*/ -void AT91F_SpiInit(void) -{ - /* Configure PIOs */ - AT91C_BASE_PIOA->PIO_ASR = - AT91C_PA3_NPCS0 | AT91C_PA4_NPCS1 | AT91C_PA1_MOSI | - AT91C_PA5_NPCS2 | AT91C_PA6_NPCS3 | AT91C_PA0_MISO | - AT91C_PA2_SPCK; - AT91C_BASE_PIOA->PIO_PDR = - AT91C_PA3_NPCS0 | AT91C_PA4_NPCS1 | AT91C_PA1_MOSI | - AT91C_PA5_NPCS2 | AT91C_PA6_NPCS3 | AT91C_PA0_MISO | - AT91C_PA2_SPCK; - /* Enable CLock */ - AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_SPI; - - /* Reset the SPI */ - AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST; - - /* Configure SPI in Master Mode with No CS selected !!! */ - AT91C_BASE_SPI->SPI_MR = - AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | AT91C_SPI_PCS; - - /* Configure CS0 and CS3 */ - *(AT91C_SPI_CSR + 0) = - AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & DATAFLASH_TCSS) | - (AT91C_SPI_DLYBCT & DATAFLASH_TCHS) | - ((AT91C_MASTER_CLOCK / (2*AT91C_SPI_CLK)) << 8); - - *(AT91C_SPI_CSR + 3) = - AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & DATAFLASH_TCSS) | - (AT91C_SPI_DLYBCT & DATAFLASH_TCHS) | - ((AT91C_MASTER_CLOCK / (2*AT91C_SPI_CLK)) << 8); -} - -void AT91F_SpiEnable(int cs) -{ - switch(cs) { - case 0: /* Configure SPI CS0 for Serial DataFlash AT45DBxx */ - AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF; - AT91C_BASE_SPI->SPI_MR |= - ((AT91C_SPI_PCS0_SERIAL_DATAFLASH<<16) & - AT91C_SPI_PCS); - break; - case 3: /* Configure SPI CS3 for Serial DataFlash Card */ - /* Set up PIO SDC_TYPE to switch on DataFlash Card */ - /* and not MMC/SDCard */ - AT91C_BASE_PIOB->PIO_PER = - AT91C_PIO_PB7; /* Set in PIO mode */ - AT91C_BASE_PIOB->PIO_OER = - AT91C_PIO_PB7; /* Configure in output */ - /* Clear Output */ - AT91C_BASE_PIOB->PIO_CODR = AT91C_PIO_PB7; - /* Configure PCS */ - AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF; - AT91C_BASE_SPI->SPI_MR |= - ((AT91C_SPI_PCS3_DATAFLASH_CARD<<16) & AT91C_SPI_PCS); - break; - } - - /* SPI_Enable */ - AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN; } - -/*---------------------------------------------------------------------------*/ -/* \fn AT91F_SpiWrite */ -/* \brief Set the PDC registers for a transfert */ -/*---------------------------------------------------------------------------*/ -unsigned int AT91F_SpiWrite ( AT91PS_DataflashDesc pDesc ) -{ - unsigned int timeout; - - pDesc->state = BUSY; - - AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS; - - /* Initialize the Transmit and Receive Pointer */ - AT91C_BASE_SPI->SPI_RPR = (unsigned int)pDesc->rx_cmd_pt ; - AT91C_BASE_SPI->SPI_TPR = (unsigned int)pDesc->tx_cmd_pt ; - - /* Intialize the Transmit and Receive Counters */ - AT91C_BASE_SPI->SPI_RCR = pDesc->rx_cmd_size; - AT91C_BASE_SPI->SPI_TCR = pDesc->tx_cmd_size; - - if ( pDesc->tx_data_size != 0 ) { - /* Initialize the Next Transmit and Next Receive Pointer */ - AT91C_BASE_SPI->SPI_RNPR = (unsigned int)pDesc->rx_data_pt ; - AT91C_BASE_SPI->SPI_TNPR = (unsigned int)pDesc->tx_data_pt ; - - /* Intialize the Next Transmit and Next Receive Counters */ - AT91C_BASE_SPI->SPI_RNCR = pDesc->rx_data_size ; - AT91C_BASE_SPI->SPI_TNCR = pDesc->tx_data_size ; - } - - /* arm simple, non interrupt dependent timer */ - reset_timer_masked(); - timeout = 0; - - AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTEN + AT91C_PDC_RXTEN; - while(!(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RXBUFF) && - ((timeout = get_timer_masked() ) < CONFIG_SYS_SPI_WRITE_TOUT)); - AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS; - pDesc->state = IDLE; - - if (timeout >= CONFIG_SYS_SPI_WRITE_TOUT){ - printf("Error Timeout\n\r"); - return DATAFLASH_ERROR; - } - - return DATAFLASH_OK; -} -#endif diff --git a/cpu/arm920t/at91rm9200/timer.c b/cpu/arm920t/at91rm9200/timer.c deleted file mode 100644 index 9c54bbedbe..0000000000 --- a/cpu/arm920t/at91rm9200/timer.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * (C) Copyright 2002 - * Lineo, Inc. - * Bernhard Kuhn - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -/*#include */ -#include -/*#include */ - -/* the number of clocks per CONFIG_SYS_HZ */ -#define TIMER_LOAD_VAL (CONFIG_SYS_HZ_CLOCK/CONFIG_SYS_HZ) - -/* macro to read the 16 bit timer */ -#define READ_TIMER (tmr->TC_CV & 0x0000ffff) -AT91PS_TC tmr; - -static ulong timestamp; -static ulong lastinc; - -int timer_init (void) -{ - tmr = AT91C_BASE_TC0; - - /* enables TC1.0 clock */ - *AT91C_PMC_PCER = 1 << AT91C_ID_TC0; /* enable clock */ - - *AT91C_TCB0_BCR = 0; - *AT91C_TCB0_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_NONE | AT91C_TCB_TC2XC2S_NONE; - tmr->TC_CCR = AT91C_TC_CLKDIS; -#define AT91C_TC_CMR_CPCTRG (1 << 14) - /* set to MCLK/2 and restart the timer when the vlaue in TC_RC is reached */ - tmr->TC_CMR = AT91C_TC_TIMER_DIV1_CLOCK | AT91C_TC_CMR_CPCTRG; - - tmr->TC_IDR = ~0ul; - tmr->TC_RC = TIMER_LOAD_VAL; - lastinc = 0; - tmr->TC_CCR = AT91C_TC_SWTRG | AT91C_TC_CLKEN; - timestamp = 0; - - return (0); -} - -/* - * timer without interrupts - */ - -void reset_timer (void) -{ - reset_timer_masked (); -} - -ulong get_timer (ulong base) -{ - return get_timer_masked () - base; -} - -void set_timer (ulong t) -{ - timestamp = t; -} - -void __udelay (unsigned long usec) -{ - udelay_masked(usec); -} - -void reset_timer_masked (void) -{ - /* reset time */ - lastinc = READ_TIMER; - timestamp = 0; -} - -ulong get_timer_raw (void) -{ - ulong now = READ_TIMER; - - if (now >= lastinc) { - /* normal mode */ - timestamp += now - lastinc; - } else { - /* we have an overflow ... */ - timestamp += now + TIMER_LOAD_VAL - lastinc; - } - lastinc = now; - - return timestamp; -} - -ulong get_timer_masked (void) -{ - return get_timer_raw()/TIMER_LOAD_VAL; -} - -void udelay_masked (unsigned long usec) -{ - ulong tmo; - ulong endtime; - signed long diff; - - tmo = CONFIG_SYS_HZ_CLOCK / 1000; - tmo *= usec; - tmo /= 1000; - - endtime = get_timer_raw () + tmo; - - do { - ulong now = get_timer_raw (); - diff = endtime - now; - } while (diff >= 0); -} - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return get_timer(0); -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk (void) -{ - ulong tbclk; - - tbclk = CONFIG_SYS_HZ; - return tbclk; -} diff --git a/cpu/arm920t/at91rm9200/usb.c b/cpu/arm920t/at91rm9200/usb.c deleted file mode 100644 index 72355dcf9a..0000000000 --- a/cpu/arm920t/at91rm9200/usb.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * (C) Copyright 2006 - * DENX Software Engineering - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include - -#if defined(CONFIG_USB_OHCI_NEW) && defined(CONFIG_SYS_USB_OHCI_CPU_INIT) -# ifdef CONFIG_AT91RM9200 - -#include - -int usb_cpu_init(void) -{ - /* Enable USB host clock. */ - *AT91C_PMC_SCER = AT91C_PMC_UHP; /* 48MHz clock enabled for UHP */ - *AT91C_PMC_PCER = 1 << AT91C_ID_UHP; /* Peripheral Clock Enable Register */ - return 0; -} - -int usb_cpu_stop(void) -{ - /* Initialization failed */ - *AT91C_PMC_PCDR = 1 << AT91C_ID_UHP; /* Peripheral Clock Disable Register */ - *AT91C_PMC_SCDR = AT91C_PMC_UHP; /* 48MHz clock disabled for UHP */ - return 0; -} - -int usb_cpu_init_fail(void) -{ - return usb_cpu_stop(); -} - -# endif /* CONFIG_AT91RM9200 */ -#endif /* defined(CONFIG_USB_OHCI) && defined(CONFIG_SYS_USB_OHCI_CPU_INIT) */ diff --git a/cpu/arm920t/config.mk b/cpu/arm920t/config.mk deleted file mode 100644 index 8f6c1a354c..0000000000 --- a/cpu/arm920t/config.mk +++ /dev/null @@ -1,32 +0,0 @@ -# -# (C) Copyright 2002 -# Gary Jennejohn, DENX Software Engineering, -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float - -PLATFORM_CPPFLAGS += -march=armv4 -# ========================================================================= -# -# Supply options according to compiler version -# -# ========================================================================= -PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/arm920t/cpu.c b/cpu/arm920t/cpu.c deleted file mode 100644 index be82c87c7d..0000000000 --- a/cpu/arm920t/cpu.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * CPU specific code - */ - -#include -#include -#include - -#ifdef CONFIG_AT91_LEGACY -#warning Your board is using legacy AT91RM9200 SoC access. Please update! -#endif - -static void cache_flush(void); - -int cleanup_before_linux (void) -{ - /* - * this function is called just before we call linux - * it prepares the processor for linux - * - * we turn off caches etc ... - */ - - disable_interrupts (); - - /* turn off I/D-cache */ - icache_disable(); - dcache_disable(); - /* flush I/D-cache */ - cache_flush(); - - return 0; -} - -/* flush I/D-cache */ -static void cache_flush (void) -{ - unsigned long i = 0; - - asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); -} diff --git a/cpu/arm920t/ep93xx/Makefile b/cpu/arm920t/ep93xx/Makefile deleted file mode 100644 index 01a2f5555a..0000000000 --- a/cpu/arm920t/ep93xx/Makefile +++ /dev/null @@ -1,55 +0,0 @@ -# -# Cirrus Logic EP93xx CPU-specific Makefile -# -# Copyright (C) 2009 Matthias Kaehlcke -# -# Copyright (C) 2004, 2005 -# Cory T. Tusar, Videon Central, Inc., -# -# Copyright (C) 2006 -# Dominic Rath -# -# Based on an original Makefile, which is -# -# (C) Copyright 2000, 2001, 2002 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this project. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 675 Mass Ave, Cambridge, MA 02139, USA. -# -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(SOC).a - -COBJS = cpu.o led.o speed.o timer.o -SOBJS = lowlevel_init.o - -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) - -all: $(obj).depend $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/arm920t/ep93xx/cpu.c b/cpu/arm920t/ep93xx/cpu.c deleted file mode 100644 index 1abb9c6faa..0000000000 --- a/cpu/arm920t/ep93xx/cpu.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Cirrus Logic EP93xx CPU-specific support. - * - * Copyright (C) 2009 Matthias Kaehlcke - * - * Copyright (C) 2004, 2005 - * Cory T. Tusar, Videon Central, Inc., - * - * See file CREDITS for list of people who contributed to this project. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include - -/* We reset the CPU by generating a 1-->0 transition on DeviceCfg bit 31. */ -extern void reset_cpu(ulong addr) -{ - struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE; - uint32_t value; - - /* Unlock DeviceCfg and set SWRST */ - writel(0xAA, &syscon->sysswlock); - value = readl(&syscon->devicecfg); - value |= SYSCON_DEVICECFG_SWRST; - writel(value, &syscon->devicecfg); - - /* Unlock DeviceCfg and clear SWRST */ - writel(0xAA, &syscon->sysswlock); - value = readl(&syscon->devicecfg); - value &= ~SYSCON_DEVICECFG_SWRST; - writel(value, &syscon->devicecfg); - - /* Dying... */ - while (1) - ; /* noop */ -} diff --git a/cpu/arm920t/ep93xx/led.c b/cpu/arm920t/ep93xx/led.c deleted file mode 100644 index 7e2c897757..0000000000 --- a/cpu/arm920t/ep93xx/led.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2010, 2009 Matthias Kaehlcke - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include - -static uint8_t saved_state[2] = {STATUS_LED_OFF, STATUS_LED_OFF}; -static uint32_t gpio_pin[2] = {1 << STATUS_LED_GREEN, - 1 << STATUS_LED_RED}; - -inline void switch_LED_on(uint8_t led) -{ - register struct gpio_regs *gpio = (struct gpio_regs *)GPIO_BASE; - - writel(readl(&gpio->pedr) | gpio_pin[led], &gpio->pedr); - saved_state[led] = STATUS_LED_ON; -} - -inline void switch_LED_off(uint8_t led) -{ - register struct gpio_regs *gpio = (struct gpio_regs *)GPIO_BASE; - - writel(readl(&gpio->pedr) & ~gpio_pin[led], &gpio->pedr); - saved_state[led] = STATUS_LED_OFF; -} - -void red_LED_on(void) -{ - switch_LED_on(STATUS_LED_RED); -} - -void red_LED_off(void) -{ - switch_LED_off(STATUS_LED_RED); -} - -void green_LED_on(void) -{ - switch_LED_on(STATUS_LED_GREEN); -} - -void green_LED_off(void) -{ - switch_LED_off(STATUS_LED_GREEN); -} - -void __led_init(led_id_t mask, int state) -{ - __led_set(mask, state); -} - -void __led_toggle(led_id_t mask) -{ - if (STATUS_LED_RED == mask) { - if (STATUS_LED_ON == saved_state[STATUS_LED_RED]) - red_LED_off(); - else - red_LED_on(); - } else if (STATUS_LED_GREEN == mask) { - if (STATUS_LED_ON == saved_state[STATUS_LED_GREEN]) - green_LED_off(); - else - green_LED_on(); - } -} - -void __led_set(led_id_t mask, int state) -{ - if (STATUS_LED_RED == mask) { - if (STATUS_LED_ON == state) - red_LED_on(); - else - red_LED_off(); - } else if (STATUS_LED_GREEN == mask) { - if (STATUS_LED_ON == state) - green_LED_on(); - else - green_LED_off(); - } -} diff --git a/cpu/arm920t/ep93xx/lowlevel_init.S b/cpu/arm920t/ep93xx/lowlevel_init.S deleted file mode 100644 index a20ec894be..0000000000 --- a/cpu/arm920t/ep93xx/lowlevel_init.S +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Low-level initialization for EP93xx - * - * Copyright (C) 2009 Matthias Kaehlcke - * - * Copyright (C) 2006 Dominic Rath - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include - -.globl lowlevel_init -lowlevel_init: - /* backup return address */ - ldr r1, =SYSCON_SCRATCH0 - str lr, [r1] - - /* Turn on both LEDs */ - bl red_LED_on - bl green_LED_on - - /* Configure flash wait states before we switch to the PLL */ - bl flash_cfg - - /* Set up PLL */ - bl pll_cfg - - /* Turn off the Green LED and leave the Red LED on */ - bl green_LED_off - - /* Setup SDRAM */ - bl sdram_cfg - - /* Turn on Green LED, Turn off the Red LED */ - bl green_LED_on - bl red_LED_off - - /* FIXME: we use async mode for now */ - mrc p15, 0, r0, c1, c0, 0 - orr r0, r0, #0xc0000000 - mcr p15, 0, r0, c1, c0, 0 - - /* restore return address */ - ldr r1, =SYSCON_SCRATCH0 - ldr lr, [r1] - - mov pc, lr diff --git a/cpu/arm920t/ep93xx/speed.c b/cpu/arm920t/ep93xx/speed.c deleted file mode 100644 index c83a3bb91d..0000000000 --- a/cpu/arm920t/ep93xx/speed.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Cirrus Logic EP93xx PLL support. - * - * Copyright (C) 2009 Matthias Kaehlcke - * - * See file CREDITS for list of people who contributed to this project. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include - -/* - * CONFIG_SYS_CLK_FREQ should be defined as the input frequency of the PLL. - * - * get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of - * the specified bus in HZ. - */ - -/* - * return the PLL output frequency - * - * PLL rate = CONFIG_SYS_CLK_FREQ * (X1FBD + 1) * (X2FBD + 1) - * / (X2IPD + 1) / 2^PS - */ -static ulong get_PLLCLK(uint32_t *pllreg) -{ - uint8_t i; - const uint32_t clkset = readl(pllreg); - uint64_t rate = CONFIG_SYS_CLK_FREQ; - rate *= ((clkset >> SYSCON_CLKSET_PLL_X1FBD1_SHIFT) & 0x1f) + 1; - rate *= ((clkset >> SYSCON_CLKSET_PLL_X2FBD2_SHIFT) & 0x3f) + 1; - do_div(rate, (clkset & 0x1f) + 1); /* X2IPD */ - for (i = 0; i < ((clkset >> SYSCON_CLKSET_PLL_PS_SHIFT) & 3); i++) - rate >>= 1; - - return (ulong)rate; -} - -/* return FCLK frequency */ -ulong get_FCLK() -{ - const uint8_t fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 }; - struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE; - - const uint32_t clkset1 = readl(&syscon->clkset1); - const uint8_t fclk_div = - fclk_divisors[(clkset1 >> SYSCON_CLKSET1_FCLK_DIV_SHIFT) & 7]; - const ulong fclk_rate = get_PLLCLK(&syscon->clkset1) / fclk_div; - - return fclk_rate; -} - -/* return HCLK frequency */ -ulong get_HCLK(void) -{ - const uint8_t hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 }; - struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE; - - const uint32_t clkset1 = readl(&syscon->clkset1); - const uint8_t hclk_div = - hclk_divisors[(clkset1 >> SYSCON_CLKSET1_HCLK_DIV_SHIFT) & 7]; - const ulong hclk_rate = get_PLLCLK(&syscon->clkset1) / hclk_div; - - return hclk_rate; -} - -/* return PCLK frequency */ -ulong get_PCLK(void) -{ - const uint8_t pclk_divisors[] = { 1, 2, 4, 8 }; - struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE; - - const uint32_t clkset1 = readl(&syscon->clkset1); - const uint8_t pclk_div = - pclk_divisors[(clkset1 >> SYSCON_CLKSET1_PCLK_DIV_SHIFT) & 3]; - const ulong pclk_rate = get_HCLK() / pclk_div; - - return pclk_rate; -} - -/* return UCLK frequency */ -ulong get_UCLK(void) -{ - struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE; - ulong uclk_rate; - - const uint32_t value = readl(&syscon->pwrcnt); - if (value & SYSCON_PWRCNT_UART_BAUD) - uclk_rate = CONFIG_SYS_CLK_FREQ; - else - uclk_rate = CONFIG_SYS_CLK_FREQ / 2; - - return uclk_rate; -} diff --git a/cpu/arm920t/ep93xx/timer.c b/cpu/arm920t/ep93xx/timer.c deleted file mode 100644 index 4a0ce4da64..0000000000 --- a/cpu/arm920t/ep93xx/timer.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Cirrus Logic EP93xx timer support. - * - * Copyright (C) 2009, 2010 Matthias Kaehlcke - * - * Copyright (C) 2004, 2005 - * Cory T. Tusar, Videon Central, Inc., - * - * Based on the original intr.c Cirrus Logic EP93xx Rev D. interrupt support, - * author unknown. - * - * See file CREDITS for list of people who contributed to this project. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include - -#define TIMER_CLKSEL (1 << 3) -#define TIMER_ENABLE (1 << 7) - -#define TIMER_FREQ 508469 /* ticks / second */ -#define TIMER_MAX_VAL 0xFFFFFFFF - -static struct ep93xx_timer -{ - unsigned long long ticks; - unsigned long last_read; -} timer; - -static inline unsigned long long usecs_to_ticks(unsigned long usecs) -{ - unsigned long long ticks = (unsigned long long)usecs * TIMER_FREQ; - do_div(ticks, 1000 * 1000); - - return ticks; -} - -static inline void read_timer(void) -{ - struct timer_regs *timer_regs = (struct timer_regs *)TIMER_BASE; - const unsigned long now = TIMER_MAX_VAL - readl(&timer_regs->timer3.value); - - if (now >= timer.last_read) - timer.ticks += now - timer.last_read; - else - /* an overflow occurred */ - timer.ticks += TIMER_MAX_VAL - timer.last_read + now; - - timer.last_read = now; -} - -/* - * Get the number of ticks (in CONFIG_SYS_HZ resolution) - */ -unsigned long long get_ticks(void) -{ - unsigned long long sys_ticks; - - read_timer(); - - sys_ticks = timer.ticks * CONFIG_SYS_HZ; - do_div(sys_ticks, TIMER_FREQ); - - return sys_ticks; -} - -unsigned long get_timer_masked(void) -{ - return get_ticks(); -} - -unsigned long get_timer(unsigned long base) -{ - return get_timer_masked() - base; -} - -void reset_timer_masked(void) -{ - read_timer(); - timer.ticks = 0; -} - -void reset_timer(void) -{ - reset_timer_masked(); -} - -void __udelay(unsigned long usec) -{ - unsigned long long target; - - read_timer(); - - target = timer.ticks + usecs_to_ticks(usec); - - while (timer.ticks < target) - read_timer(); -} - -int timer_init(void) -{ - struct timer_regs *timer_regs = (struct timer_regs *)TIMER_BASE; - - /* use timer 3 with 508KHz and free running, not enabled now */ - writel(TIMER_CLKSEL, &timer_regs->timer3.control); - - /* set initial timer value */ - writel(TIMER_MAX_VAL, &timer_regs->timer3.load); - - /* Enable the timer */ - writel(TIMER_ENABLE | TIMER_CLKSEL, - &timer_regs->timer3.control); - - reset_timer_masked(); - - return 0; -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -unsigned long get_tbclk(void) -{ - return CONFIG_SYS_HZ; -} diff --git a/cpu/arm920t/ep93xx/u-boot.lds b/cpu/arm920t/ep93xx/u-boot.lds deleted file mode 100644 index 737c9d8c1b..0000000000 --- a/cpu/arm920t/ep93xx/u-boot.lds +++ /dev/null @@ -1,59 +0,0 @@ -/* - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -ENTRY(_start) -SECTIONS -{ - . = 0x00000000; - - . = ALIGN(4); - .text : - { - cpu/arm920t/start.o (.text) - /* the EP93xx expects to find the pattern 'CRUS' at 0x1000 */ - . = 0x1000; - LONG(0x53555243) - *(.text) - } - - . = ALIGN(4); - .rodata : { *(.rodata) } - - . = ALIGN(4); - .data : { *(.data) } - - . = ALIGN(4); - .got : { *(.got) } - - . = .; - __u_boot_cmd_start = .; - .u_boot_cmd : { *(.u_boot_cmd) } - __u_boot_cmd_end = .; - - . = ALIGN(4); - __bss_start = .; - .bss : { *(.bss) } - _end = .; -} diff --git a/cpu/arm920t/imx/Makefile b/cpu/arm920t/imx/Makefile deleted file mode 100644 index 28945e22cb..0000000000 --- a/cpu/arm920t/imx/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(SOC).a - -COBJS += generic.o -COBJS += speed.o -COBJS += timer.o - -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) - -all: $(obj).depend $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/arm920t/imx/generic.c b/cpu/arm920t/imx/generic.c deleted file mode 100644 index aa7c8c159d..0000000000 --- a/cpu/arm920t/imx/generic.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * arch/arm/mach-imx/generic.c - * - * author: Sascha Hauer - * Created: april 20th, 2004 - * Copyright: Synertronixx GmbH - * - * Common code for i.MX machines - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include - -#ifdef CONFIG_IMX - -#include - -void imx_gpio_mode(int gpio_mode) -{ - unsigned int pin = gpio_mode & GPIO_PIN_MASK; - unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> 5; - unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> 10; - unsigned int tmp; - - /* Pullup enable */ - if(gpio_mode & GPIO_PUEN) - PUEN(port) |= (1< - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - - -#include -#if defined (CONFIG_IMX) - -#include - -/* ------------------------------------------------------------------------- */ -/* NOTE: This describes the proper use of this file. - * - * CONFIG_SYS_CLK_FREQ should be defined as the input frequency of the PLL. - * SH FIXME: 16780000 in our case - * get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of - * the specified bus in HZ. - */ -/* ------------------------------------------------------------------------- */ - -ulong get_systemPLLCLK(void) -{ - /* FIXME: We assume System_SEL = 0 here */ - u32 spctl0 = SPCTL0; - u32 mfi = (spctl0 >> 10) & 0xf; - u32 mfn = spctl0 & 0x3f; - u32 mfd = (spctl0 >> 16) & 0x3f; - u32 pd = (spctl0 >> 26) & 0xf; - - mfi = mfi<=5 ? 5 : mfi; - - return (2*(CONFIG_SYSPLL_CLK_FREQ>>10)*( (mfi<<10) + (mfn<<10)/(mfd+1)))/(pd+1); -} - -ulong get_mcuPLLCLK(void) -{ - /* FIXME: We assume System_SEL = 0 here */ - u32 mpctl0 = MPCTL0; - u32 mfi = (mpctl0 >> 10) & 0xf; - u32 mfn = mpctl0 & 0x3f; - u32 mfd = (mpctl0 >> 16) & 0x3f; - u32 pd = (mpctl0 >> 26) & 0xf; - - mfi = mfi<=5 ? 5 : mfi; - - return (2*(CONFIG_SYS_CLK_FREQ>>10)*( (mfi<<10) + (mfn<<10)/(mfd+1)))/(pd+1); -} - -ulong get_FCLK(void) -{ - return (( CSCR>>15)&1) ? get_mcuPLLCLK()>>1 : get_mcuPLLCLK(); -} - -/* return HCLK frequency */ -ulong get_HCLK(void) -{ - u32 bclkdiv = (( CSCR >> 10 ) & 0xf) + 1; - printf("bclkdiv: %d\n", bclkdiv); - return get_systemPLLCLK() / bclkdiv; -} - -/* return BCLK frequency */ -ulong get_BCLK(void) -{ - return get_HCLK(); -} - -ulong get_PERCLK1(void) -{ - return get_systemPLLCLK() / (((PCDR) & 0xf)+1); -} - -ulong get_PERCLK2(void) -{ - return get_systemPLLCLK() / (((PCDR>>4) & 0xf)+1); -} - -ulong get_PERCLK3(void) -{ - return get_systemPLLCLK() / (((PCDR>>16) & 0x7f)+1); -} - -#endif /* defined (CONFIG_IMX) */ diff --git a/cpu/arm920t/imx/timer.c b/cpu/arm920t/imx/timer.c deleted file mode 100644 index b06b518f03..0000000000 --- a/cpu/arm920t/imx/timer.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#if defined (CONFIG_IMX) - -#include - -int timer_init (void) -{ - int i; - /* setup GP Timer 1 */ - TCTL1 = TCTL_SWR; - for ( i=0; i<100; i++) TCTL1 = 0; /* We have no udelay by now */ - TPRER1 = get_PERCLK1() / 1000000; /* 1 MHz */ - TCTL1 |= TCTL_FRR | (1<<1); /* Freerun Mode, PERCLK1 input */ - - reset_timer_masked(); - - return (0); -} - -/* - * timer without interrupts - */ - -void reset_timer (void) -{ - reset_timer_masked (); -} - -ulong get_timer (ulong base) -{ - return get_timer_masked() - base; -} - -void set_timer (ulong t) -{ - /* nop */ -} - -void reset_timer_masked (void) -{ - TCTL1 &= ~TCTL_TEN; - TCTL1 |= TCTL_TEN; /* Enable timer */ -} - -ulong get_timer_masked (void) -{ - return TCN1; -} - -void udelay_masked (unsigned long usec) -{ - ulong endtime = get_timer_masked() + usec; - signed long diff; - - do { - ulong now = get_timer_masked (); - diff = endtime - now; - } while (diff >= 0); -} - -void __udelay (unsigned long usec) -{ - udelay_masked(usec); -} - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return get_timer(0); -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk (void) -{ - ulong tbclk; - - tbclk = CONFIG_SYS_HZ; - - return tbclk; -} - -/* - * Reset the cpu by setting up the watchdog timer and let him time out - */ -void reset_cpu (ulong ignored) -{ - /* Disable watchdog and set Time-Out field to 0 */ - WCR = 0x00000000; - - /* Write Service Sequence */ - WSR = 0x00005555; - WSR = 0x0000AAAA; - - /* Enable watchdog */ - WCR = 0x00000001; - - while (1); - /*NOTREACHED*/ -} - -#endif /* defined (CONFIG_IMX) */ diff --git a/cpu/arm920t/interrupts.c b/cpu/arm920t/interrupts.c deleted file mode 100644 index 561083ec73..0000000000 --- a/cpu/arm920t/interrupts.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include - -#if defined (CONFIG_ARCH_INTEGRATOR) -void do_irq (struct pt_regs *pt_regs) -{ - /* ASSUMED to be a timer interrupt */ - /* Just clear it - count handled in */ - /* integratorap.c */ - *(volatile ulong *)(CONFIG_SYS_TIMERBASE + 0x0C) = 0; -} -#endif diff --git a/cpu/arm920t/ks8695/Makefile b/cpu/arm920t/ks8695/Makefile deleted file mode 100644 index f53fdc2b25..0000000000 --- a/cpu/arm920t/ks8695/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(SOC).a - -SOBJS = lowlevel_init.o - -COBJS = timer.o - -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) - -all: $(obj).depend $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/arm920t/ks8695/lowlevel_init.S b/cpu/arm920t/ks8695/lowlevel_init.S deleted file mode 100644 index e9f1227dd6..0000000000 --- a/cpu/arm920t/ks8695/lowlevel_init.S +++ /dev/null @@ -1,205 +0,0 @@ -/* - * lowlevel_init.S - basic hardware initialization for the KS8695 CPU - * - * Copyright (c) 2004-2005, Greg Ungerer - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -#ifndef CONFIG_SKIP_LOWLEVEL_INIT - -/* - ************************************************************************* - * - * Handy dandy macros - * - ************************************************************************* - */ - -/* Delay a bit */ -.macro DELAY_FOR cycles, reg0 - ldr \reg0, =\cycles - subs \reg0, \reg0, #1 - subne pc, pc, #0xc -.endm - -/* - ************************************************************************* - * - * Some local storage. - * - ************************************************************************* - */ - -/* Should we boot with an interactive console or not */ -.globl serial_console - -/* - ************************************************************************* - * - * Raw hardware initialization code. The important thing is to get - * SDRAM setup and running. We do some other basic things here too, - * like getting the PLL set for high speed, and init the LEDs. - * - ************************************************************************* - */ - -.globl lowlevel_init -lowlevel_init: - -#if DEBUG - /* - * enable UART for early debug trace - */ - ldr r1, =(KS8695_IO_BASE+KS8695_UART_DIVISOR) - mov r2, #0xd9 - str r2, [r1] /* 115200 baud */ - ldr r1, =(KS8695_IO_BASE+KS8695_UART_LINE_CTRL) - mov r2, #0x03 - str r2, [r1] /* 8 data bits, no parity, 1 stop */ - ldr r1, =(KS8695_IO_BASE+KS8695_UART_TX_HOLDING) - mov r2, #0x41 - str r2, [r1] /* write 'A' */ -#endif -#if DEBUG - ldr r1, =(KS8695_IO_BASE+KS8695_UART_TX_HOLDING) - mov r2, #0x42 - str r2, [r1] -#endif - - /* - * remap the memory and flash regions. we want to end up with - * ram from address 0, and flash at 32MB. - */ - ldr r1, =(KS8695_IO_BASE+KS8695_MEM_CTRL0) - ldr r2, =0xbfc00040 - str r2, [r1] /* large flash map */ - ldr pc, =(highflash+0x02000000-0x00f00000) /* jump to high flash address */ -highflash: - ldr r2, =0x8fe00040 - str r2, [r1] /* remap flash range */ - - /* - * remap the second select region to the 4MB immediately after - * the first region. This way if you have a larger flash (say 8Mb) - * then you can have it all mapped nicely. Has no effect if you - * only have a 4Mb or smaller flash. - */ - ldr r1, =(KS8695_IO_BASE+KS8695_MEM_CTRL1) - ldr r2, =0x9fe40040 - str r2, [r1] /* remap flash2 region, contiguous */ - ldr r1, =(KS8695_IO_BASE+KS8695_MEM_GENERAL) - ldr r2, =0x30000005 - str r2, [r1] /* enable both flash selects */ - -#ifdef CONFIG_CM41xx - /* - * map the second flash chip, using the external IO lines. - */ - ldr r1, =(KS8695_IO_BASE+KS8695_IO_CTRL0) - ldr r2, =0xafe80b6d - str r2, [r1] /* remap io0 region, contiguous */ - ldr r1, =(KS8695_IO_BASE+KS8695_IO_CTRL1) - ldr r2, =0xbfec0b6d - str r2, [r1] /* remap io1 region, contiguous */ - ldr r1, =(KS8695_IO_BASE+KS8695_MEM_GENERAL) - ldr r2, =0x30050005 - str r2, [r1] /* enable second flash */ -#endif - - /* - * before relocating, we have to setup RAM timing - */ - ldr r1, =(KS8695_IO_BASE+KS8695_SDRAM_CTRL0) -#if (PHYS_SDRAM_1_SIZE == 0x02000000) - ldr r2, =0x7fc0000e /* 32MB */ -#else - ldr r2, =0x3fc0000e /* 16MB */ -#endif - str r2, [r1] /* configure sdram bank0 setup */ - ldr r1, =(KS8695_IO_BASE+KS8695_SDRAM_CTRL1) - mov r2, #0 - str r2, [r1] /* configure sdram bank1 setup */ - - ldr r1, =(KS8695_IO_BASE+KS8695_SDRAM_GENERAL) - ldr r2, =0x0000000a - str r2, [r1] /* set RAS/CAS timing */ - - ldr r1, =(KS8695_IO_BASE+KS8695_SDRAM_BUFFER) - ldr r2, =0x00030000 - str r2, [r1] /* send NOP command */ - DELAY_FOR 0x100, r0 - ldr r2, =0x00010000 - str r2, [r1] /* send PRECHARGE-ALL */ - DELAY_FOR 0x100, r0 - - ldr r1, =(KS8695_IO_BASE+KS8695_SDRAM_REFRESH) - ldr r2, =0x00000020 - str r2, [r1] /* set for fast refresh */ - DELAY_FOR 0x100, r0 - ldr r2, =0x00000190 - str r2, [r1] /* set normal refresh timing */ - - ldr r1, =(KS8695_IO_BASE+KS8695_SDRAM_BUFFER) - ldr r2, =0x00020033 - str r2, [r1] /* send mode command */ - DELAY_FOR 0x100, r0 - ldr r2, =0x01f00000 - str r2, [r1] /* enable sdram fifos */ - - /* - * set pll to top speed - */ - ldr r1, =(KS8695_IO_BASE+KS8695_SYSTEN_BUS_CLOCK) - mov r2, #0 - str r2, [r1] /* set pll clock to 166MHz */ - - ldr r1, =(KS8695_IO_BASE+KS8695_SWITCH_CTRL0) - ldr r2, [r1] /* Get switch ctrl0 register */ - and r2, r2, #0x0fc00000 /* Mask out LED control bits */ - orr r2, r2, #0x01800000 /* Set Link/activity/speed actions */ - str r2, [r1] - -#ifdef CONFIG_CM4008 - ldr r1, =(KS8695_IO_BASE+KS8695_GPIO_MODE) - ldr r2, =0x0000fe30 - str r2, [r1] /* enable LED's as outputs */ - ldr r1, =(KS8695_IO_BASE+KS8695_GPIO_DATA) - ldr r2, =0x0000fe20 - str r2, [r1] /* turn on power LED */ -#endif -#if defined(CONFIG_CM4008) || defined(CONFIG_CM41xx) - ldr r2, [r1] /* get current GPIO input data */ - tst r2, #0x8 /* check if "erase" depressed */ - beq nobutton - mov r2, #0 /* be quiet on boot, no console */ - ldr r1, =serial_console - str r2, [r1] -nobutton: -#endif - - add lr, lr, #0x02000000 /* flash is now mapped high */ - add ip, ip, #0x02000000 /* this is a hack */ - mov pc, lr /* all done, return */ - -#endif /* CONFIG_SKIP_LOWLEVEL_INIT */ diff --git a/cpu/arm920t/ks8695/timer.c b/cpu/arm920t/ks8695/timer.c deleted file mode 100644 index 886e370596..0000000000 --- a/cpu/arm920t/ks8695/timer.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * (C) Copyright 2004-2005, Greg Ungerer - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include - -/* - * Handy KS8695 register access functions. - */ -#define ks8695_read(a) *((volatile ulong *) (KS8695_IO_BASE + (a))) -#define ks8695_write(a,v) *((volatile ulong *) (KS8695_IO_BASE + (a))) = (v) - -ulong timer_ticks; - -int timer_init (void) -{ - reset_timer(); - - return 0; -} - -/* - * Initial timer set constants. Nothing complicated, just set for a 1ms - * tick. - */ -#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_1) -#define TIMER_COUNT (TIMER_INTERVAL / 2) -#define TIMER_PULSE TIMER_COUNT - -void reset_timer_masked(void) -{ - /* Set the hadware timer for 1ms */ - ks8695_write(KS8695_TIMER1, TIMER_COUNT); - ks8695_write(KS8695_TIMER1_PCOUNT, TIMER_PULSE); - ks8695_write(KS8695_TIMER_CTRL, 0x2); - timer_ticks = 0; -} - -void reset_timer(void) -{ - reset_timer_masked(); -} - -ulong get_timer_masked(void) -{ - /* Check for timer wrap */ - if (ks8695_read(KS8695_INT_STATUS) & KS8695_INTMASK_TIMERINT1) { - /* Clear interrupt condition */ - ks8695_write(KS8695_INT_STATUS, KS8695_INTMASK_TIMERINT1); - timer_ticks++; - } - return timer_ticks; -} - -ulong get_timer(ulong base) -{ - return (get_timer_masked() - base); -} - -void set_timer(ulong t) -{ - timer_ticks = t; -} - -void __udelay(ulong usec) -{ - ulong start = get_timer_masked(); - ulong end; - - /* Only 1ms resolution :-( */ - end = usec / 1000; - while (get_timer(start) < end) - ; -} - -void reset_cpu (ulong ignored) -{ - ulong tc; - - /* Set timer0 to watchdog, and let it timeout */ - tc = ks8695_read(KS8695_TIMER_CTRL) & 0x2; - ks8695_write(KS8695_TIMER_CTRL, tc); - ks8695_write(KS8695_TIMER0, ((10 << 8) | 0xff)); - ks8695_write(KS8695_TIMER_CTRL, (tc | 0x1)); - - /* Should only wait here till watchdog resets */ - for (;;) - ; -} diff --git a/cpu/arm920t/s3c24x0/Makefile b/cpu/arm920t/s3c24x0/Makefile deleted file mode 100644 index 7e8d6ed5f2..0000000000 --- a/cpu/arm920t/s3c24x0/Makefile +++ /dev/null @@ -1,50 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(SOC).a - -COBJS-$(CONFIG_USE_IRQ) += interrupts.o -COBJS-y += speed.o -COBJS-y += timer.o -COBJS-y += usb.o -COBJS-y += usb_ohci.o - - -SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y)) - -all: $(obj).depend $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/arm920t/s3c24x0/interrupts.c b/cpu/arm920t/s3c24x0/interrupts.c deleted file mode 100644 index 879fda66a9..0000000000 --- a/cpu/arm920t/s3c24x0/interrupts.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include - -#include -#include - -void do_irq (struct pt_regs *pt_regs) -{ - struct s3c24x0_interrupt *irq = s3c24x0_get_base_interrupt(); - u_int32_t intpnd = readl(&irq->INTPND); - -} diff --git a/cpu/arm920t/s3c24x0/speed.c b/cpu/arm920t/s3c24x0/speed.c deleted file mode 100644 index b13283a798..0000000000 --- a/cpu/arm920t/s3c24x0/speed.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * (C) Copyright 2001-2004 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * (C) Copyright 2002 - * David Mueller, ELSOFT AG, d.mueller@elsoft.ch - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* This code should work for both the S3C2400 and the S3C2410 - * as they seem to have the same PLL and clock machinery inside. - * The different address mapping is handled by the s3c24xx.h files below. - */ - -#include -#ifdef CONFIG_S3C24X0 - -#include -#include - -#define MPLL 0 -#define UPLL 1 - -/* ------------------------------------------------------------------------- */ -/* NOTE: This describes the proper use of this file. - * - * CONFIG_SYS_CLK_FREQ should be defined as the input frequency of the PLL. - * - * get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of - * the specified bus in HZ. - */ -/* ------------------------------------------------------------------------- */ - -static ulong get_PLLCLK(int pllreg) -{ - struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power(); - ulong r, m, p, s; - - if (pllreg == MPLL) - r = readl(&clk_power->MPLLCON); - else if (pllreg == UPLL) - r = readl(&clk_power->UPLLCON); - else - hang(); - - m = ((r & 0xFF000) >> 12) + 8; - p = ((r & 0x003F0) >> 4) + 2; - s = r & 0x3; - - return (CONFIG_SYS_CLK_FREQ * m) / (p << s); -} - -/* return FCLK frequency */ -ulong get_FCLK(void) -{ - return get_PLLCLK(MPLL); -} - -/* return HCLK frequency */ -ulong get_HCLK(void) -{ - struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power(); - - return (readl(&clk_power->CLKDIVN) & 2) ? get_FCLK() / 2 : get_FCLK(); -} - -/* return PCLK frequency */ -ulong get_PCLK(void) -{ - struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power(); - - return (readl(&clk_power->CLKDIVN) & 1) ? get_HCLK() / 2 : get_HCLK(); -} - -/* return UCLK frequency */ -ulong get_UCLK(void) -{ - return get_PLLCLK(UPLL); -} - -#endif /* CONFIG_S3C24X0 */ diff --git a/cpu/arm920t/s3c24x0/timer.c b/cpu/arm920t/s3c24x0/timer.c deleted file mode 100644 index 7d47354381..0000000000 --- a/cpu/arm920t/s3c24x0/timer.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#ifdef CONFIG_S3C24X0 - -#include -#include - -int timer_load_val = 0; -static ulong timer_clk; - -/* macro to read the 16 bit timer */ -static inline ulong READ_TIMER(void) -{ - struct s3c24x0_timers *timers = s3c24x0_get_base_timers(); - - return readl(&timers->TCNTO4) & 0xffff; -} - -static ulong timestamp; -static ulong lastdec; - -int timer_init(void) -{ - struct s3c24x0_timers *timers = s3c24x0_get_base_timers(); - ulong tmr; - - /* use PWM Timer 4 because it has no output */ - /* prescaler for Timer 4 is 16 */ - writel(0x0f00, &timers->TCFG0); - if (timer_load_val == 0) { - /* - * for 10 ms clock period @ PCLK with 4 bit divider = 1/2 - * (default) and prescaler = 16. Should be 10390 - * @33.25MHz and 15625 @ 50 MHz - */ - timer_load_val = get_PCLK() / (2 * 16 * 100); - timer_clk = get_PCLK() / (2 * 16); - } - /* load value for 10 ms timeout */ - lastdec = timer_load_val; - writel(timer_load_val, &timers->TCNTB4); - /* auto load, manual update of Timer 4 */ - tmr = (readl(&timers->TCON) & ~0x0700000) | 0x0600000; - writel(tmr, &timers->TCON); - /* auto load, start Timer 4 */ - tmr = (tmr & ~0x0700000) | 0x0500000; - writel(tmr, &timers->TCON); - timestamp = 0; - - return (0); -} - -/* - * timer without interrupts - */ - -void reset_timer(void) -{ - reset_timer_masked(); -} - -ulong get_timer(ulong base) -{ - return get_timer_masked() - base; -} - -void set_timer(ulong t) -{ - timestamp = t; -} - -void __udelay (unsigned long usec) -{ - ulong tmo; - ulong start = get_ticks(); - - tmo = usec / 1000; - tmo *= (timer_load_val * 100); - tmo /= 1000; - - while ((ulong) (get_ticks() - start) < tmo) - /*NOP*/; -} - -void reset_timer_masked(void) -{ - /* reset time */ - lastdec = READ_TIMER(); - timestamp = 0; -} - -ulong get_timer_masked(void) -{ - ulong tmr = get_ticks(); - - return tmr / (timer_clk / CONFIG_SYS_HZ); -} - -void udelay_masked(unsigned long usec) -{ - ulong tmo; - ulong endtime; - signed long diff; - - if (usec >= 1000) { - tmo = usec / 1000; - tmo *= (timer_load_val * 100); - tmo /= 1000; - } else { - tmo = usec * (timer_load_val * 100); - tmo /= (1000 * 1000); - } - - endtime = get_ticks() + tmo; - - do { - ulong now = get_ticks(); - diff = endtime - now; - } while (diff >= 0); -} - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - ulong now = READ_TIMER(); - - if (lastdec >= now) { - /* normal mode */ - timestamp += lastdec - now; - } else { - /* we have an overflow ... */ - timestamp += lastdec + timer_load_val - now; - } - lastdec = now; - - return timestamp; -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk(void) -{ - ulong tbclk; - -#if defined(CONFIG_SMDK2400) || defined(CONFIG_TRAB) - tbclk = timer_load_val * 100; -#elif defined(CONFIG_SBC2410X) || \ - defined(CONFIG_SMDK2410) || \ - defined(CONFIG_VCMA9) - tbclk = CONFIG_SYS_HZ; -#else -# error "tbclk not configured" -#endif - - return tbclk; -} - -/* - * reset the cpu by setting up the watchdog timer and let him time out - */ -void reset_cpu(ulong ignored) -{ - struct s3c24x0_watchdog *watchdog; - -#ifdef CONFIG_TRAB - extern void disable_vfd(void); - - disable_vfd(); -#endif - - watchdog = s3c24x0_get_base_watchdog(); - - /* Disable watchdog */ - writel(0x0000, &watchdog->WTCON); - - /* Initialize watchdog timer count register */ - writel(0x0001, &watchdog->WTCNT); - - /* Enable watchdog timer; assert reset at timer timeout */ - writel(0x0021, &watchdog->WTCON); - - while (1) - /* loop forever and wait for reset to happen */; - - /*NOTREACHED*/ -} - -#endif /* CONFIG_S3C24X0 */ diff --git a/cpu/arm920t/s3c24x0/usb.c b/cpu/arm920t/s3c24x0/usb.c deleted file mode 100644 index e468ed08fc..0000000000 --- a/cpu/arm920t/s3c24x0/usb.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * (C) Copyright 2006 - * DENX Software Engineering - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include - -#if defined(CONFIG_USB_OHCI_NEW) && \ - defined(CONFIG_SYS_USB_OHCI_CPU_INIT) && \ - defined(CONFIG_S3C24X0) - -#include -#include - -int usb_cpu_init(void) -{ - struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power(); - struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio(); - - /* - * Set the 48 MHz UPLL clocking. Values are taken from - * "PLL value selection guide", 6-23, s3c2400_UM.pdf. - */ - writel((40 << 12) + (1 << 4) + 2, &clk_power->UPLLCON); - /* 1 = use pads related USB for USB host */ - writel(readl(&gpio->MISCCR) | 0x8, &gpio->MISCCR); - - /* - * Enable USB host clock. - */ - writel(readl(&clk_power->CLKCON) | (1 << 4), &clk_power->CLKCON); - - return 0; -} - -int usb_cpu_stop(void) -{ - struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power(); - /* may not want to do this */ - writel(readl(&clk_power->CLKCON) & ~(1 << 4), &clk_power->CLKCON); - return 0; -} - -int usb_cpu_init_fail(void) -{ - struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power(); - writel(readl(&clk_power->CLKCON) & ~(1 << 4), &clk_power->CLKCON); - return 0; -} - -#endif /* defined(CONFIG_USB_OHCI_NEW) && \ - defined(CONFIG_SYS_USB_OHCI_CPU_INIT) && \ - defined(CONFIG_S3C24X0) */ diff --git a/cpu/arm920t/s3c24x0/usb_ohci.c b/cpu/arm920t/s3c24x0/usb_ohci.c deleted file mode 100644 index 5aa8d64a55..0000000000 --- a/cpu/arm920t/s3c24x0/usb_ohci.c +++ /dev/null @@ -1,1755 +0,0 @@ -/* - * URB OHCI HCD (Host Controller Driver) for USB on the S3C2400. - * - * (C) Copyright 2003 - * Gary Jennejohn, DENX Software Engineering - * - * Note: Much of this code has been derived from Linux 2.4 - * (C) Copyright 1999 Roman Weissgaerber - * (C) Copyright 2000-2002 David Brownell - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - */ -/* - * IMPORTANT NOTES - * 1 - this driver is intended for use with USB Mass Storage Devices - * (BBB) ONLY. There is NO support for Interrupt or Isochronous pipes! - */ - -#include -/* #include no PCI on the S3C24X0 */ - -#if defined(CONFIG_USB_OHCI) && defined(CONFIG_S3C24X0) - -#include -#include -#include -#include -#include "usb_ohci.h" - -#define OHCI_USE_NPS /* force NoPowerSwitching mode */ -#undef OHCI_VERBOSE_DEBUG /* not always helpful */ - - -/* For initializing controller (mask in an HCFS mode too) */ -#define OHCI_CONTROL_INIT \ - (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE - -#define min_t(type, x, y) \ - ({ type __x = (x); type __y = (y); __x < __y ? __x : __y; }) - -#undef DEBUG -#ifdef DEBUG -#define dbg(format, arg...) printf("DEBUG: " format "\n", ## arg) -#else -#define dbg(format, arg...) do {} while(0) -#endif /* DEBUG */ -#define err(format, arg...) printf("ERROR: " format "\n", ## arg) -#undef SHOW_INFO -#ifdef SHOW_INFO -#define info(format, arg...) printf("INFO: " format "\n", ## arg) -#else -#define info(format, arg...) do {} while(0) -#endif - -#define m16_swap(x) swap_16(x) -#define m32_swap(x) swap_32(x) - -/* global struct ohci */ -static struct ohci gohci; -/* this must be aligned to a 256 byte boundary */ -struct ohci_hcca ghcca[1]; -/* a pointer to the aligned storage */ -struct ohci_hcca *phcca; -/* this allocates EDs for all possible endpoints */ -struct ohci_device ohci_dev; -/* urb_priv */ -struct urb_priv urb_priv; -/* RHSC flag */ -int got_rhsc; -/* device which was disconnected */ -struct usb_device *devgone; -/* flag guarding URB transation */ -int urb_finished = 0; - -/*-------------------------------------------------------------------------*/ - -/* AMD-756 (D2 rev) reports corrupt register contents in some cases. - * The erratum (#4) description is incorrect. AMD's workaround waits - * till some bits (mostly reserved) are clear; ok for all revs. - */ -#define OHCI_QUIRK_AMD756 0xabcd -#define read_roothub(hc, register, mask) ({ \ - u32 temp = readl (&hc->regs->roothub.register); \ - if (hc->flags & OHCI_QUIRK_AMD756) \ - while (temp & mask) \ - temp = readl (&hc->regs->roothub.register); \ - temp; }) - -static u32 roothub_a(struct ohci *hc) -{ - return read_roothub(hc, a, 0xfc0fe000); -} -static inline u32 roothub_b(struct ohci *hc) -{ - return readl(&hc->regs->roothub.b); -} -static inline u32 roothub_status(struct ohci *hc) -{ - return readl(&hc->regs->roothub.status); -} -static u32 roothub_portstatus(struct ohci *hc, int i) -{ - return read_roothub(hc, portstatus[i], 0xffe0fce0); -} - -/* forward declaration */ -static int hc_interrupt(void); -static void td_submit_job(struct usb_device *dev, unsigned long pipe, - void *buffer, int transfer_len, - struct devrequest *setup, struct urb_priv *urb, - int interval); - -/*-------------------------------------------------------------------------* - * URB support functions - *-------------------------------------------------------------------------*/ - -/* free HCD-private data associated with this URB */ - -static void urb_free_priv(struct urb_priv *urb) -{ - int i; - int last; - struct td *td; - - last = urb->length - 1; - if (last >= 0) { - for (i = 0; i <= last; i++) { - td = urb->td[i]; - if (td) { - td->usb_dev = NULL; - urb->td[i] = NULL; - } - } - } -} - -/*-------------------------------------------------------------------------*/ - -#ifdef DEBUG -static int sohci_get_current_frame_number(struct usb_device *dev); - -/* debug| print the main components of an URB - * small: 0) header + data packets 1) just header */ - -static void pkt_print(struct usb_device *dev, unsigned long pipe, void *buffer, - int transfer_len, struct devrequest *setup, char *str, - int small) -{ - struct urb_priv *purb = &urb_priv; - - dbg("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,len:%d/%d stat:%#lx", - str, - sohci_get_current_frame_number(dev), - usb_pipedevice(pipe), - usb_pipeendpoint(pipe), - usb_pipeout(pipe) ? 'O' : 'I', - usb_pipetype(pipe) < 2 ? - (usb_pipeint(pipe) ? "INTR" : "ISOC") : - (usb_pipecontrol(pipe) ? "CTRL" : "BULK"), - purb->actual_length, transfer_len, dev->status); -#ifdef OHCI_VERBOSE_DEBUG - if (!small) { - int i, len; - - if (usb_pipecontrol(pipe)) { - printf(__FILE__ ": cmd(8):"); - for (i = 0; i < 8; i++) - printf(" %02x", ((__u8 *) setup)[i]); - printf("\n"); - } - if (transfer_len > 0 && buffer) { - printf(__FILE__ ": data(%d/%d):", - purb->actual_length, transfer_len); - len = usb_pipeout(pipe) ? - transfer_len : purb->actual_length; - for (i = 0; i < 16 && i < len; i++) - printf(" %02x", ((__u8 *) buffer)[i]); - printf("%s\n", i < len ? "..." : ""); - } - } -#endif -} - -/* just for debugging; prints non-empty branches of the - int ed tree inclusive iso eds*/ -void ep_print_int_eds(struct ohci *ohci, char *str) -{ - int i, j; - __u32 *ed_p; - for (i = 0; i < 32; i++) { - j = 5; - ed_p = &(ohci->hcca->int_table[i]); - if (*ed_p == 0) - continue; - printf(__FILE__ ": %s branch int %2d(%2x):", str, i, i); - while (*ed_p != 0 && j--) { - struct ed *ed = (struct ed *) m32_swap(ed_p); - printf(" ed: %4x;", ed->hwINFO); - ed_p = &ed->hwNextED; - } - printf("\n"); - } -} - -static void ohci_dump_intr_mask(char *label, __u32 mask) -{ - dbg("%s: 0x%08x%s%s%s%s%s%s%s%s%s", - label, - mask, - (mask & OHCI_INTR_MIE) ? " MIE" : "", - (mask & OHCI_INTR_OC) ? " OC" : "", - (mask & OHCI_INTR_RHSC) ? " RHSC" : "", - (mask & OHCI_INTR_FNO) ? " FNO" : "", - (mask & OHCI_INTR_UE) ? " UE" : "", - (mask & OHCI_INTR_RD) ? " RD" : "", - (mask & OHCI_INTR_SF) ? " SF" : "", - (mask & OHCI_INTR_WDH) ? " WDH" : "", - (mask & OHCI_INTR_SO) ? " SO" : ""); -} - -static void maybe_print_eds(char *label, __u32 value) -{ - struct ed *edp = (struct ed *) value; - - if (value) { - dbg("%s %08x", label, value); - dbg("%08x", edp->hwINFO); - dbg("%08x", edp->hwTailP); - dbg("%08x", edp->hwHeadP); - dbg("%08x", edp->hwNextED); - } -} - -static char *hcfs2string(int state) -{ - switch (state) { - case OHCI_USB_RESET: - return "reset"; - case OHCI_USB_RESUME: - return "resume"; - case OHCI_USB_OPER: - return "operational"; - case OHCI_USB_SUSPEND: - return "suspend"; - } - return "?"; -} - -/* dump control and status registers */ -static void ohci_dump_status(struct ohci *controller) -{ - struct ohci_regs *regs = controller->regs; - __u32 temp; - - temp = readl(®s->revision) & 0xff; - if (temp != 0x10) - dbg("spec %d.%d", (temp >> 4), (temp & 0x0f)); - - temp = readl(®s->control); - dbg("control: 0x%08x%s%s%s HCFS=%s%s%s%s%s CBSR=%d", temp, - (temp & OHCI_CTRL_RWE) ? " RWE" : "", - (temp & OHCI_CTRL_RWC) ? " RWC" : "", - (temp & OHCI_CTRL_IR) ? " IR" : "", - hcfs2string(temp & OHCI_CTRL_HCFS), - (temp & OHCI_CTRL_BLE) ? " BLE" : "", - (temp & OHCI_CTRL_CLE) ? " CLE" : "", - (temp & OHCI_CTRL_IE) ? " IE" : "", - (temp & OHCI_CTRL_PLE) ? " PLE" : "", temp & OHCI_CTRL_CBSR); - - temp = readl(®s->cmdstatus); - dbg("cmdstatus: 0x%08x SOC=%d%s%s%s%s", temp, - (temp & OHCI_SOC) >> 16, - (temp & OHCI_OCR) ? " OCR" : "", - (temp & OHCI_BLF) ? " BLF" : "", - (temp & OHCI_CLF) ? " CLF" : "", (temp & OHCI_HCR) ? " HCR" : ""); - - ohci_dump_intr_mask("intrstatus", readl(®s->intrstatus)); - ohci_dump_intr_mask("intrenable", readl(®s->intrenable)); - - maybe_print_eds("ed_periodcurrent", readl(®s->ed_periodcurrent)); - - maybe_print_eds("ed_controlhead", readl(®s->ed_controlhead)); - maybe_print_eds("ed_controlcurrent", readl(®s->ed_controlcurrent)); - - maybe_print_eds("ed_bulkhead", readl(®s->ed_bulkhead)); - maybe_print_eds("ed_bulkcurrent", readl(®s->ed_bulkcurrent)); - - maybe_print_eds("donehead", readl(®s->donehead)); -} - -static void ohci_dump_roothub(struct ohci *controller, int verbose) -{ - __u32 temp, ndp, i; - - temp = roothub_a(controller); - ndp = (temp & RH_A_NDP); - - if (verbose) { - dbg("roothub.a: %08x POTPGT=%d%s%s%s%s%s NDP=%d", temp, - ((temp & RH_A_POTPGT) >> 24) & 0xff, - (temp & RH_A_NOCP) ? " NOCP" : "", - (temp & RH_A_OCPM) ? " OCPM" : "", - (temp & RH_A_DT) ? " DT" : "", - (temp & RH_A_NPS) ? " NPS" : "", - (temp & RH_A_PSM) ? " PSM" : "", ndp); - temp = roothub_b(controller); - dbg("roothub.b: %08x PPCM=%04x DR=%04x", - temp, (temp & RH_B_PPCM) >> 16, (temp & RH_B_DR) - ); - temp = roothub_status(controller); - dbg("roothub.status: %08x%s%s%s%s%s%s", - temp, - (temp & RH_HS_CRWE) ? " CRWE" : "", - (temp & RH_HS_OCIC) ? " OCIC" : "", - (temp & RH_HS_LPSC) ? " LPSC" : "", - (temp & RH_HS_DRWE) ? " DRWE" : "", - (temp & RH_HS_OCI) ? " OCI" : "", - (temp & RH_HS_LPS) ? " LPS" : ""); - } - - for (i = 0; i < ndp; i++) { - temp = roothub_portstatus(controller, i); - dbg("roothub.portstatus [%d] = 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s", - i, - temp, - (temp & RH_PS_PRSC) ? " PRSC" : "", - (temp & RH_PS_OCIC) ? " OCIC" : "", - (temp & RH_PS_PSSC) ? " PSSC" : "", - (temp & RH_PS_PESC) ? " PESC" : "", - (temp & RH_PS_CSC) ? " CSC" : "", - (temp & RH_PS_LSDA) ? " LSDA" : "", - (temp & RH_PS_PPS) ? " PPS" : "", - (temp & RH_PS_PRS) ? " PRS" : "", - (temp & RH_PS_POCI) ? " POCI" : "", - (temp & RH_PS_PSS) ? " PSS" : "", - (temp & RH_PS_PES) ? " PES" : "", - (temp & RH_PS_CCS) ? " CCS" : ""); - } -} - -static void ohci_dump(struct ohci *controller, int verbose) -{ - dbg("OHCI controller usb-%s state", controller->slot_name); - - /* dumps some of the state we know about */ - ohci_dump_status(controller); - if (verbose) - ep_print_int_eds(controller, "hcca"); - dbg("hcca frame #%04x", controller->hcca->frame_no); - ohci_dump_roothub(controller, 1); -} - -#endif /* DEBUG */ - -/*-------------------------------------------------------------------------* - * Interface functions (URB) - *-------------------------------------------------------------------------*/ - -/* get a transfer request */ - -int sohci_submit_job(struct usb_device *dev, unsigned long pipe, void *buffer, - int transfer_len, struct devrequest *setup, int interval) -{ - struct ohci *ohci; - struct ed *ed; - struct urb_priv *purb_priv; - int i, size = 0; - - ohci = &gohci; - - /* when controller's hung, permit only roothub cleanup attempts - * such as powering down ports */ - if (ohci->disabled) { - err("sohci_submit_job: EPIPE"); - return -1; - } - - /* if we have an unfinished URB from previous transaction let's - * fail and scream as quickly as possible so as not to corrupt - * further communication */ - if (!urb_finished) { - err("sohci_submit_job: URB NOT FINISHED"); - return -1; - } - /* we're about to begin a new transaction here - so mark the URB unfinished */ - urb_finished = 0; - - /* every endpoint has a ed, locate and fill it */ - ed = ep_add_ed(dev, pipe); - if (!ed) { - err("sohci_submit_job: ENOMEM"); - return -1; - } - - /* for the private part of the URB we need the number of TDs (size) */ - switch (usb_pipetype(pipe)) { - case PIPE_BULK: - /* one TD for every 4096 Byte */ - size = (transfer_len - 1) / 4096 + 1; - break; - case PIPE_CONTROL: - /* 1 TD for setup, 1 for ACK and 1 for every 4096 B */ - size = (transfer_len == 0) ? 2 : (transfer_len - 1) / 4096 + 3; - break; - } - - if (size >= (N_URB_TD - 1)) { - err("need %d TDs, only have %d", size, N_URB_TD); - return -1; - } - purb_priv = &urb_priv; - purb_priv->pipe = pipe; - - /* fill the private part of the URB */ - purb_priv->length = size; - purb_priv->ed = ed; - purb_priv->actual_length = 0; - - /* allocate the TDs */ - /* note that td[0] was allocated in ep_add_ed */ - for (i = 0; i < size; i++) { - purb_priv->td[i] = td_alloc(dev); - if (!purb_priv->td[i]) { - purb_priv->length = i; - urb_free_priv(purb_priv); - err("sohci_submit_job: ENOMEM"); - return -1; - } - } - - if (ed->state == ED_NEW || (ed->state & ED_DEL)) { - urb_free_priv(purb_priv); - err("sohci_submit_job: EINVAL"); - return -1; - } - - /* link the ed into a chain if is not already */ - if (ed->state != ED_OPER) - ep_link(ohci, ed); - - /* fill the TDs and link it to the ed */ - td_submit_job(dev, pipe, buffer, transfer_len, setup, purb_priv, - interval); - - return 0; -} - -/*-------------------------------------------------------------------------*/ - -#ifdef DEBUG -/* tell us the current USB frame number */ - -static int sohci_get_current_frame_number(struct usb_device *usb_dev) -{ - struct ohci *ohci = &gohci; - - return m16_swap(ohci->hcca->frame_no); -} -#endif - -/*-------------------------------------------------------------------------* - * ED handling functions - *-------------------------------------------------------------------------*/ - -/* link an ed into one of the HC chains */ - -static int ep_link(struct ohci *ohci, struct ed *edi) -{ - struct ed *ed = edi; - - ed->state = ED_OPER; - - switch (ed->type) { - case PIPE_CONTROL: - ed->hwNextED = 0; - if (ohci->ed_controltail == NULL) { - writel((u32)ed, &ohci->regs->ed_controlhead); - } else { - ohci->ed_controltail->hwNextED = (__u32) m32_swap(ed); - } - ed->ed_prev = ohci->ed_controltail; - if (!ohci->ed_controltail && !ohci->ed_rm_list[0] && - !ohci->ed_rm_list[1] && !ohci->sleeping) { - ohci->hc_control |= OHCI_CTRL_CLE; - writel(ohci->hc_control, &ohci->regs->control); - } - ohci->ed_controltail = edi; - break; - - case PIPE_BULK: - ed->hwNextED = 0; - if (ohci->ed_bulktail == NULL) { - writel((u32)ed, &ohci->regs->ed_bulkhead); - } else { - ohci->ed_bulktail->hwNextED = (__u32) m32_swap(ed); - } - ed->ed_prev = ohci->ed_bulktail; - if (!ohci->ed_bulktail && !ohci->ed_rm_list[0] && - !ohci->ed_rm_list[1] && !ohci->sleeping) { - ohci->hc_control |= OHCI_CTRL_BLE; - writel(ohci->hc_control, &ohci->regs->control); - } - ohci->ed_bulktail = edi; - break; - } - return 0; -} - -/*-------------------------------------------------------------------------*/ - -/* unlink an ed from one of the HC chains. - * just the link to the ed is unlinked. - * the link from the ed still points to another operational ed or 0 - * so the HC can eventually finish the processing of the unlinked ed */ - -static int ep_unlink(struct ohci *ohci, struct ed *ed) -{ - struct ed *next; - ed->hwINFO |= m32_swap(OHCI_ED_SKIP); - - switch (ed->type) { - case PIPE_CONTROL: - if (ed->ed_prev == NULL) { - if (!ed->hwNextED) { - ohci->hc_control &= ~OHCI_CTRL_CLE; - writel(ohci->hc_control, &ohci->regs->control); - } - writel(m32_swap(*((__u32 *) &ed->hwNextED)), - &ohci->regs->ed_controlhead); - } else { - ed->ed_prev->hwNextED = ed->hwNextED; - } - if (ohci->ed_controltail == ed) { - ohci->ed_controltail = ed->ed_prev; - } else { - next = (struct ed *)m32_swap(*((__u32 *)&ed->hwNextED)); - next->ed_prev = ed->ed_prev; - } - break; - - case PIPE_BULK: - if (ed->ed_prev == NULL) { - if (!ed->hwNextED) { - ohci->hc_control &= ~OHCI_CTRL_BLE; - writel(ohci->hc_control, &ohci->regs->control); - } - writel(m32_swap(*((__u32 *) &ed->hwNextED)), - &ohci->regs->ed_bulkhead); - } else { - ed->ed_prev->hwNextED = ed->hwNextED; - } - if (ohci->ed_bulktail == ed) { - ohci->ed_bulktail = ed->ed_prev; - } else { - next = (struct ed *)m32_swap(*((__u32 *)&ed->hwNextED)); - next->ed_prev = ed->ed_prev; - } - break; - } - ed->state = ED_UNLINK; - return 0; -} - -/*-------------------------------------------------------------------------*/ - -/* add/reinit an endpoint; this should be done once at the usb_set_configuration - * command, but the USB stack is a little bit stateless so we do it at every - * transaction. If the state of the ed is ED_NEW then a dummy td is added and - * the state is changed to ED_UNLINK. In all other cases the state is left - * unchanged. The ed info fields are setted anyway even though most of them - * should not change */ - -static struct ed *ep_add_ed(struct usb_device *usb_dev, unsigned long pipe) -{ - struct td *td; - struct ed *ed_ret; - struct ed *ed; - - ed = ed_ret = &ohci_dev.ed[(usb_pipeendpoint(pipe) << 1) | - (usb_pipecontrol(pipe) ? 0 : - usb_pipeout(pipe))]; - - if ((ed->state & ED_DEL) || (ed->state & ED_URB_DEL)) { - err("ep_add_ed: pending delete"); - /* pending delete request */ - return NULL; - } - - if (ed->state == ED_NEW) { - ed->hwINFO = m32_swap(OHCI_ED_SKIP); /* skip ed */ - /* dummy td; end of td list for ed */ - td = td_alloc(usb_dev); - ed->hwTailP = (__u32) m32_swap(td); - ed->hwHeadP = ed->hwTailP; - ed->state = ED_UNLINK; - ed->type = usb_pipetype(pipe); - ohci_dev.ed_cnt++; - } - - ed->hwINFO = m32_swap(usb_pipedevice(pipe) - | usb_pipeendpoint(pipe) << 7 - | (usb_pipeisoc(pipe) ? 0x8000 : 0) - | (usb_pipecontrol(pipe) ? 0 : - (usb_pipeout(pipe) ? 0x800 : 0x1000)) - | usb_pipeslow(pipe) << 13 | - usb_maxpacket(usb_dev, pipe) << 16); - - return ed_ret; -} - -/*-------------------------------------------------------------------------* - * TD handling functions - *-------------------------------------------------------------------------*/ - -/* enqueue next TD for this URB (OHCI spec 5.2.8.2) */ - -static void td_fill(struct ohci *ohci, unsigned int info, void *data, int len, - struct usb_device *dev, int index, - struct urb_priv *urb_priv) -{ - struct td *td, *td_pt; -#ifdef OHCI_FILL_TRACE - int i; -#endif - - if (index > urb_priv->length) { - err("index > length"); - return; - } - /* use this td as the next dummy */ - td_pt = urb_priv->td[index]; - td_pt->hwNextTD = 0; - - /* fill the old dummy TD */ - td = urb_priv->td[index] = - (struct td *) (m32_swap(urb_priv->ed->hwTailP) & ~0xf); - - td->ed = urb_priv->ed; - td->next_dl_td = NULL; - td->index = index; - td->data = (__u32) data; -#ifdef OHCI_FILL_TRACE - if (usb_pipebulk(urb_priv->pipe) && usb_pipeout(urb_priv->pipe)) { - for (i = 0; i < len; i++) - printf("td->data[%d] %#2x ", i, - ((unsigned char *)td->data)[i]); - printf("\n"); - } -#endif - if (!len) - data = 0; - - td->hwINFO = (__u32) m32_swap(info); - td->hwCBP = (__u32) m32_swap(data); - if (data) - td->hwBE = (__u32) m32_swap(data + len - 1); - else - td->hwBE = 0; - td->hwNextTD = (__u32) m32_swap(td_pt); - - /* append to queue */ - td->ed->hwTailP = td->hwNextTD; -} - -/*-------------------------------------------------------------------------*/ - -/* prepare all TDs of a transfer */ - -static void td_submit_job(struct usb_device *dev, unsigned long pipe, - void *buffer, int transfer_len, - struct devrequest *setup, struct urb_priv *urb, - int interval) -{ - struct ohci *ohci = &gohci; - int data_len = transfer_len; - void *data; - int cnt = 0; - __u32 info = 0; - unsigned int toggle = 0; - - /* OHCI handles the DATA-toggles itself, we just - use the USB-toggle bits for reseting */ - if (usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe))) { - toggle = TD_T_TOGGLE; - } else { - toggle = TD_T_DATA0; - usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), - 1); - } - urb->td_cnt = 0; - if (data_len) - data = buffer; - else - data = 0; - - switch (usb_pipetype(pipe)) { - case PIPE_BULK: - info = usb_pipeout(pipe) ? TD_CC | TD_DP_OUT : TD_CC | TD_DP_IN; - while (data_len > 4096) { - td_fill(ohci, info | (cnt ? TD_T_TOGGLE : toggle), data, - 4096, dev, cnt, urb); - data += 4096; - data_len -= 4096; - cnt++; - } - info = usb_pipeout(pipe) ? - TD_CC | TD_DP_OUT : - TD_CC | TD_R | TD_DP_IN; - td_fill(ohci, info | (cnt ? TD_T_TOGGLE : toggle), data, - data_len, dev, cnt, urb); - cnt++; - - if (!ohci->sleeping) - /* start bulk list */ - writel(OHCI_BLF, &ohci->regs->cmdstatus); - break; - - case PIPE_CONTROL: - info = TD_CC | TD_DP_SETUP | TD_T_DATA0; - td_fill(ohci, info, setup, 8, dev, cnt++, urb); - if (data_len > 0) { - info = usb_pipeout(pipe) ? - TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1 : - TD_CC | TD_R | TD_DP_IN | TD_T_DATA1; - /* NOTE: mishandles transfers >8K, some >4K */ - td_fill(ohci, info, data, data_len, dev, cnt++, urb); - } - info = usb_pipeout(pipe) ? - TD_CC | TD_DP_IN | TD_T_DATA1 : - TD_CC | TD_DP_OUT | TD_T_DATA1; - td_fill(ohci, info, data, 0, dev, cnt++, urb); - if (!ohci->sleeping) - /* start Control list */ - writel(OHCI_CLF, &ohci->regs->cmdstatus); - break; - } - if (urb->length != cnt) - dbg("TD LENGTH %d != CNT %d", urb->length, cnt); -} - -/*-------------------------------------------------------------------------* - * Done List handling functions - *-------------------------------------------------------------------------*/ - - -/* calculate the transfer length and update the urb */ - -static void dl_transfer_length(struct td *td) -{ - __u32 tdINFO, tdBE, tdCBP; - struct urb_priv *lurb_priv = &urb_priv; - - tdINFO = m32_swap(td->hwINFO); - tdBE = m32_swap(td->hwBE); - tdCBP = m32_swap(td->hwCBP); - - if (!(usb_pipecontrol(lurb_priv->pipe) && - ((td->index == 0) || (td->index == lurb_priv->length - 1)))) { - if (tdBE != 0) { - if (td->hwCBP == 0) - lurb_priv->actual_length += tdBE - td->data + 1; - else - lurb_priv->actual_length += tdCBP - td->data; - } - } -} - -/*-------------------------------------------------------------------------*/ - -/* replies to the request have to be on a FIFO basis so - * we reverse the reversed done-list */ - -static struct td *dl_reverse_done_list(struct ohci *ohci) -{ - __u32 td_list_hc; - __u32 tmp; - struct td *td_rev = NULL; - struct td *td_list = NULL; - struct urb_priv *lurb_priv = NULL; - - td_list_hc = m32_swap(ohci->hcca->done_head) & 0xfffffff0; - ohci->hcca->done_head = 0; - - while (td_list_hc) { - td_list = (struct td *) td_list_hc; - - if (TD_CC_GET(m32_swap(td_list->hwINFO))) { - lurb_priv = &urb_priv; - dbg(" USB-error/status: %x : %p", - TD_CC_GET(m32_swap(td_list->hwINFO)), td_list); - if (td_list->ed->hwHeadP & m32_swap(0x1)) { - if (lurb_priv && - ((td_list->index+1) < lurb_priv->length)) { - tmp = lurb_priv->length - 1; - td_list->ed->hwHeadP = - (lurb_priv->td[tmp]->hwNextTD & - m32_swap(0xfffffff0)) | - (td_list->ed->hwHeadP & - m32_swap(0x2)); - lurb_priv->td_cnt += lurb_priv->length - - td_list->index - 1; - } else - td_list->ed->hwHeadP &= - m32_swap(0xfffffff2); - } - } - - td_list->next_dl_td = td_rev; - td_rev = td_list; - td_list_hc = m32_swap(td_list->hwNextTD) & 0xfffffff0; - } - - return td_list; -} - -/*-------------------------------------------------------------------------*/ - -/* td done list */ -static int dl_done_list(struct ohci *ohci, struct td *td_list) -{ - struct td *td_list_next = NULL; - struct ed *ed; - int cc = 0; - int stat = 0; - /* urb_t *urb; */ - struct urb_priv *lurb_priv; - __u32 tdINFO, edHeadP, edTailP; - - while (td_list) { - td_list_next = td_list->next_dl_td; - - lurb_priv = &urb_priv; - tdINFO = m32_swap(td_list->hwINFO); - - ed = td_list->ed; - - dl_transfer_length(td_list); - - /* error code of transfer */ - cc = TD_CC_GET(tdINFO); - if (cc != 0) { - dbg("ConditionCode %#x", cc); - stat = cc_to_error[cc]; - } - - /* see if this done list makes for all TD's of current URB, - * and mark the URB finished if so */ - if (++(lurb_priv->td_cnt) == lurb_priv->length) { - if ((ed->state & (ED_OPER | ED_UNLINK))) - urb_finished = 1; - else - dbg("dl_done_list: strange.., ED state %x, " - "ed->state\n"); - } else - dbg("dl_done_list: processing TD %x, len %x\n", - lurb_priv->td_cnt, lurb_priv->length); - - if (ed->state != ED_NEW) { - edHeadP = m32_swap(ed->hwHeadP) & 0xfffffff0; - edTailP = m32_swap(ed->hwTailP); - - /* unlink eds if they are not busy */ - if ((edHeadP == edTailP) && (ed->state == ED_OPER)) - ep_unlink(ohci, ed); - } - - td_list = td_list_next; - } - return stat; -} - -/*-------------------------------------------------------------------------* - * Virtual Root Hub - *-------------------------------------------------------------------------*/ - -/* Device descriptor */ -static __u8 root_hub_dev_des[] = { - 0x12, /* __u8 bLength; */ - 0x01, /* __u8 bDescriptorType; Device */ - 0x10, /* __u16 bcdUSB; v1.1 */ - 0x01, - 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ - 0x00, /* __u8 bDeviceSubClass; */ - 0x00, /* __u8 bDeviceProtocol; */ - 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */ - 0x00, /* __u16 idVendor; */ - 0x00, - 0x00, /* __u16 idProduct; */ - 0x00, - 0x00, /* __u16 bcdDevice; */ - 0x00, - 0x00, /* __u8 iManufacturer; */ - 0x01, /* __u8 iProduct; */ - 0x00, /* __u8 iSerialNumber; */ - 0x01 /* __u8 bNumConfigurations; */ -}; - -/* Configuration descriptor */ -static __u8 root_hub_config_des[] = { - 0x09, /* __u8 bLength; */ - 0x02, /* __u8 bDescriptorType; Configuration */ - 0x19, /* __u16 wTotalLength; */ - 0x00, - 0x01, /* __u8 bNumInterfaces; */ - 0x01, /* __u8 bConfigurationValue; */ - 0x00, /* __u8 iConfiguration; */ - 0x40, /* __u8 bmAttributes; - Bit 7: Bus-powered, 6: Self-powered, - 5 Remote-wakwup, 4..0: resvd */ - 0x00, /* __u8 MaxPower; */ - - /* interface */ - 0x09, /* __u8 if_bLength; */ - 0x04, /* __u8 if_bDescriptorType; Interface */ - 0x00, /* __u8 if_bInterfaceNumber; */ - 0x00, /* __u8 if_bAlternateSetting; */ - 0x01, /* __u8 if_bNumEndpoints; */ - 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */ - 0x00, /* __u8 if_bInterfaceSubClass; */ - 0x00, /* __u8 if_bInterfaceProtocol; */ - 0x00, /* __u8 if_iInterface; */ - - /* endpoint */ - 0x07, /* __u8 ep_bLength; */ - 0x05, /* __u8 ep_bDescriptorType; Endpoint */ - 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */ - 0x03, /* __u8 ep_bmAttributes; Interrupt */ - 0x02, /* __u16 ep_wMaxPacketSize; ((MAX_ROOT_PORTS + 1) / 8 */ - 0x00, - 0xff /* __u8 ep_bInterval; 255 ms */ -}; - -static unsigned char root_hub_str_index0[] = { - 0x04, /* __u8 bLength; */ - 0x03, /* __u8 bDescriptorType; String-descriptor */ - 0x09, /* __u8 lang ID */ - 0x04, /* __u8 lang ID */ -}; - -static unsigned char root_hub_str_index1[] = { - 28, /* __u8 bLength; */ - 0x03, /* __u8 bDescriptorType; String-descriptor */ - 'O', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - 'H', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - 'C', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - 'I', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - ' ', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - 'R', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - 'o', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - 'o', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - 't', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - ' ', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - 'H', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - 'u', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - 'b', /* __u8 Unicode */ - 0, /* __u8 Unicode */ -}; - -/* Hub class-specific descriptor is constructed dynamically */ - - -/*-------------------------------------------------------------------------*/ - -#define OK(x) len = (x); break -#ifdef DEBUG -#define WR_RH_STAT(x) \ -{ \ - info("WR:status %#8x", (x)); \ - writel((x), &gohci.regs->roothub.status); \ -} -#define WR_RH_PORTSTAT(x) \ -{ \ - info("WR:portstatus[%d] %#8x", wIndex-1, (x)); \ - writel((x), &gohci.regs->roothub.portstatus[wIndex-1]); \ -} -#else -#define WR_RH_STAT(x) \ - writel((x), &gohci.regs->roothub.status) -#define WR_RH_PORTSTAT(x)\ - writel((x), &gohci.regs->roothub.portstatus[wIndex-1]) -#endif -#define RD_RH_STAT roothub_status(&gohci) -#define RD_RH_PORTSTAT roothub_portstatus(&gohci, wIndex-1) - -/* request to virtual root hub */ - -int rh_check_port_status(struct ohci *controller) -{ - __u32 temp, ndp, i; - int res; - - res = -1; - temp = roothub_a(controller); - ndp = (temp & RH_A_NDP); - for (i = 0; i < ndp; i++) { - temp = roothub_portstatus(controller, i); - /* check for a device disconnect */ - if (((temp & (RH_PS_PESC | RH_PS_CSC)) == - (RH_PS_PESC | RH_PS_CSC)) && ((temp & RH_PS_CCS) == 0)) { - res = i; - break; - } - } - return res; -} - -static int ohci_submit_rh_msg(struct usb_device *dev, unsigned long pipe, - void *buffer, int transfer_len, - struct devrequest *cmd) -{ - void *data = buffer; - int leni = transfer_len; - int len = 0; - int stat = 0; - __u32 datab[4]; - __u8 *data_buf = (__u8 *) datab; - __u16 bmRType_bReq; - __u16 wValue; - __u16 wIndex; - __u16 wLength; - -#ifdef DEBUG - urb_priv.actual_length = 0; - pkt_print(dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", - usb_pipein(pipe)); -#else - wait_ms(1); -#endif - if (usb_pipeint(pipe)) { - info("Root-Hub submit IRQ: NOT implemented"); - return 0; - } - - bmRType_bReq = cmd->requesttype | (cmd->request << 8); - wValue = m16_swap(cmd->value); - wIndex = m16_swap(cmd->index); - wLength = m16_swap(cmd->length); - - info("Root-Hub: adr: %2x cmd(%1x): %08x %04x %04x %04x", - dev->devnum, 8, bmRType_bReq, wValue, wIndex, wLength); - - switch (bmRType_bReq) { - /* Request Destination: - without flags: Device, - RH_INTERFACE: interface, - RH_ENDPOINT: endpoint, - RH_CLASS means HUB here, - RH_OTHER | RH_CLASS almost ever means HUB_PORT here - */ - - case RH_GET_STATUS: - *(__u16 *) data_buf = m16_swap(1); - OK(2); - case RH_GET_STATUS | RH_INTERFACE: - *(__u16 *) data_buf = m16_swap(0); - OK(2); - case RH_GET_STATUS | RH_ENDPOINT: - *(__u16 *) data_buf = m16_swap(0); - OK(2); - case RH_GET_STATUS | RH_CLASS: - *(__u32 *) data_buf = - m32_swap(RD_RH_STAT & ~(RH_HS_CRWE | RH_HS_DRWE)); - OK(4); - case RH_GET_STATUS | RH_OTHER | RH_CLASS: - *(__u32 *) data_buf = m32_swap(RD_RH_PORTSTAT); - OK(4); - - case RH_CLEAR_FEATURE | RH_ENDPOINT: - switch (wValue) { - case (RH_ENDPOINT_STALL): - OK(0); - } - break; - - case RH_CLEAR_FEATURE | RH_CLASS: - switch (wValue) { - case RH_C_HUB_LOCAL_POWER: - OK(0); - case (RH_C_HUB_OVER_CURRENT): - WR_RH_STAT(RH_HS_OCIC); - OK(0); - } - break; - - case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS: - switch (wValue) { - case (RH_PORT_ENABLE): - WR_RH_PORTSTAT(RH_PS_CCS); - OK(0); - case (RH_PORT_SUSPEND): - WR_RH_PORTSTAT(RH_PS_POCI); - OK(0); - case (RH_PORT_POWER): - WR_RH_PORTSTAT(RH_PS_LSDA); - OK(0); - case (RH_C_PORT_CONNECTION): - WR_RH_PORTSTAT(RH_PS_CSC); - OK(0); - case (RH_C_PORT_ENABLE): - WR_RH_PORTSTAT(RH_PS_PESC); - OK(0); - case (RH_C_PORT_SUSPEND): - WR_RH_PORTSTAT(RH_PS_PSSC); - OK(0); - case (RH_C_PORT_OVER_CURRENT): - WR_RH_PORTSTAT(RH_PS_OCIC); - OK(0); - case (RH_C_PORT_RESET): - WR_RH_PORTSTAT(RH_PS_PRSC); - OK(0); - } - break; - - case RH_SET_FEATURE | RH_OTHER | RH_CLASS: - switch (wValue) { - case (RH_PORT_SUSPEND): - WR_RH_PORTSTAT(RH_PS_PSS); - OK(0); - case (RH_PORT_RESET): /* BUG IN HUP CODE ******** */ - if (RD_RH_PORTSTAT & RH_PS_CCS) - WR_RH_PORTSTAT(RH_PS_PRS); - OK(0); - case (RH_PORT_POWER): - WR_RH_PORTSTAT(RH_PS_PPS); - OK(0); - case (RH_PORT_ENABLE): /* BUG IN HUP CODE ******** */ - if (RD_RH_PORTSTAT & RH_PS_CCS) - WR_RH_PORTSTAT(RH_PS_PES); - OK(0); - } - break; - - case RH_SET_ADDRESS: - gohci.rh.devnum = wValue; - OK(0); - - case RH_GET_DESCRIPTOR: - switch ((wValue & 0xff00) >> 8) { - case (0x01): /* device descriptor */ - len = min_t(unsigned int, - leni, - min_t(unsigned int, - sizeof(root_hub_dev_des), wLength)); - data_buf = root_hub_dev_des; - OK(len); - case (0x02): /* configuration descriptor */ - len = min_t(unsigned int, - leni, - min_t(unsigned int, - sizeof(root_hub_config_des), - wLength)); - data_buf = root_hub_config_des; - OK(len); - case (0x03): /* string descriptors */ - if (wValue == 0x0300) { - len = min_t(unsigned int, - leni, - min_t(unsigned int, - sizeof(root_hub_str_index0), - wLength)); - data_buf = root_hub_str_index0; - OK(len); - } - if (wValue == 0x0301) { - len = min_t(unsigned int, - leni, - min_t(unsigned int, - sizeof(root_hub_str_index1), - wLength)); - data_buf = root_hub_str_index1; - OK(len); - } - default: - stat = USB_ST_STALLED; - } - break; - - case RH_GET_DESCRIPTOR | RH_CLASS: - { - __u32 temp = roothub_a(&gohci); - - data_buf[0] = 9; /* min length; */ - data_buf[1] = 0x29; - data_buf[2] = temp & RH_A_NDP; - data_buf[3] = 0; - if (temp & RH_A_PSM) - /* per-port power switching? */ - data_buf[3] |= 0x1; - if (temp & RH_A_NOCP) - /* no overcurrent reporting? */ - data_buf[3] |= 0x10; - else if (temp & RH_A_OCPM) - /* per-port overcurrent reporting? */ - data_buf[3] |= 0x8; - - /* corresponds to data_buf[4-7] */ - datab[1] = 0; - data_buf[5] = (temp & RH_A_POTPGT) >> 24; - temp = roothub_b(&gohci); - data_buf[7] = temp & RH_B_DR; - if (data_buf[2] < 7) { - data_buf[8] = 0xff; - } else { - data_buf[0] += 2; - data_buf[8] = (temp & RH_B_DR) >> 8; - data_buf[10] = data_buf[9] = 0xff; - } - - len = min_t(unsigned int, leni, - min_t(unsigned int, data_buf[0], wLength)); - OK(len); - } - - case RH_GET_CONFIGURATION: - *(__u8 *) data_buf = 0x01; - OK(1); - - case RH_SET_CONFIGURATION: - WR_RH_STAT(0x10000); - OK(0); - - default: - dbg("unsupported root hub command"); - stat = USB_ST_STALLED; - } - -#ifdef DEBUG - ohci_dump_roothub(&gohci, 1); -#else - wait_ms(1); -#endif - - len = min_t(int, len, leni); - if (data != data_buf) - memcpy(data, data_buf, len); - dev->act_len = len; - dev->status = stat; - -#ifdef DEBUG - if (transfer_len) - urb_priv.actual_length = transfer_len; - pkt_print(dev, pipe, buffer, transfer_len, cmd, "RET(rh)", - 0 /*usb_pipein(pipe) */); -#else - wait_ms(1); -#endif - - return stat; -} - -/*-------------------------------------------------------------------------*/ - -/* common code for handling submit messages - used for all but root hub */ -/* accesses. */ -int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int transfer_len, struct devrequest *setup, int interval) -{ - int stat = 0; - int maxsize = usb_maxpacket(dev, pipe); - int timeout; - - /* device pulled? Shortcut the action. */ - if (devgone == dev) { - dev->status = USB_ST_CRC_ERR; - return 0; - } -#ifdef DEBUG - urb_priv.actual_length = 0; - pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB", - usb_pipein(pipe)); -#else - wait_ms(1); -#endif - if (!maxsize) { - err("submit_common_message: pipesize for pipe %lx is zero", - pipe); - return -1; - } - - if (sohci_submit_job(dev, pipe, buffer, transfer_len, setup, interval) < - 0) { - err("sohci_submit_job failed"); - return -1; - } - - wait_ms(10); - /* ohci_dump_status(&gohci); */ - - /* allow more time for a BULK device to react - some are slow */ -#define BULK_TO 5000 /* timeout in milliseconds */ - if (usb_pipebulk(pipe)) - timeout = BULK_TO; - else - timeout = 100; - - /* wait for it to complete */ - for (;;) { - /* check whether the controller is done */ - stat = hc_interrupt(); - - if (stat < 0) { - stat = USB_ST_CRC_ERR; - break; - } - - /* NOTE: since we are not interrupt driven in U-Boot and always - * handle only one URB at a time, we cannot assume the - * transaction finished on the first successful return from - * hc_interrupt().. unless the flag for current URB is set, - * meaning that all TD's to/from device got actually - * transferred and processed. If the current URB is not - * finished we need to re-iterate this loop so as - * hc_interrupt() gets called again as there needs to be some - * more TD's to process still */ - if ((stat >= 0) && (stat != 0xff) && (urb_finished)) { - /* 0xff is returned for an SF-interrupt */ - break; - } - - if (--timeout) { - wait_ms(1); - if (!urb_finished) - dbg("\%"); - - } else { - err("CTL:TIMEOUT "); - dbg("submit_common_msg: TO status %x\n", stat); - stat = USB_ST_CRC_ERR; - urb_finished = 1; - break; - } - } - -#if 0 - /* we got an Root Hub Status Change interrupt */ - if (got_rhsc) { -#ifdef DEBUG - ohci_dump_roothub(&gohci, 1); -#endif - got_rhsc = 0; - /* abuse timeout */ - timeout = rh_check_port_status(&gohci); - if (timeout >= 0) { -#if 0 /* this does nothing useful, but leave it here - in case that changes */ - /* the called routine adds 1 to the passed value */ - usb_hub_port_connect_change(gohci.rh.dev, timeout - 1); -#endif - /* - * XXX - * This is potentially dangerous because it assumes - * that only one device is ever plugged in! - */ - devgone = dev; - } - } -#endif - - dev->status = stat; - dev->act_len = transfer_len; - -#ifdef DEBUG - pkt_print(dev, pipe, buffer, transfer_len, setup, "RET(ctlr)", - usb_pipein(pipe)); -#else - wait_ms(1); -#endif - - /* free TDs in urb_priv */ - urb_free_priv(&urb_priv); - return 0; -} - -/* submit routines called from usb.c */ -int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int transfer_len) -{ - info("submit_bulk_msg"); - return submit_common_msg(dev, pipe, buffer, transfer_len, NULL, 0); -} - -int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int transfer_len, struct devrequest *setup) -{ - int maxsize = usb_maxpacket(dev, pipe); - - info("submit_control_msg"); -#ifdef DEBUG - urb_priv.actual_length = 0; - pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB", - usb_pipein(pipe)); -#else - wait_ms(1); -#endif - if (!maxsize) { - err("submit_control_message: pipesize for pipe %lx is zero", - pipe); - return -1; - } - if (((pipe >> 8) & 0x7f) == gohci.rh.devnum) { - gohci.rh.dev = dev; - /* root hub - redirect */ - return ohci_submit_rh_msg(dev, pipe, buffer, transfer_len, - setup); - } - - return submit_common_msg(dev, pipe, buffer, transfer_len, setup, 0); -} - -int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int transfer_len, int interval) -{ - info("submit_int_msg"); - return -1; -} - -/*-------------------------------------------------------------------------* - * HC functions - *-------------------------------------------------------------------------*/ - -/* reset the HC and BUS */ - -static int hc_reset(struct ohci *ohci) -{ - int timeout = 30; - int smm_timeout = 50; /* 0,5 sec */ - - if (readl(&ohci->regs->control) & OHCI_CTRL_IR) { - /* SMM owns the HC - request ownership */ - writel(OHCI_OCR, &ohci->regs->cmdstatus); - info("USB HC TakeOver from SMM"); - while (readl(&ohci->regs->control) & OHCI_CTRL_IR) { - wait_ms(10); - if (--smm_timeout == 0) { - err("USB HC TakeOver failed!"); - return -1; - } - } - } - - /* Disable HC interrupts */ - writel(OHCI_INTR_MIE, &ohci->regs->intrdisable); - - dbg("USB HC reset_hc usb-%s: ctrl = 0x%X ;", - ohci->slot_name, readl(&ohci->regs->control)); - - /* Reset USB (needed by some controllers) */ - writel(0, &ohci->regs->control); - - /* HC Reset requires max 10 us delay */ - writel(OHCI_HCR, &ohci->regs->cmdstatus); - while ((readl(&ohci->regs->cmdstatus) & OHCI_HCR) != 0) { - if (--timeout == 0) { - err("USB HC reset timed out!"); - return -1; - } - udelay(1); - } - return 0; -} - -/*-------------------------------------------------------------------------*/ - -/* Start an OHCI controller, set the BUS operational - * enable interrupts - * connect the virtual root hub */ - -static int hc_start(struct ohci *ohci) -{ - __u32 mask; - unsigned int fminterval; - - ohci->disabled = 1; - - /* Tell the controller where the control and bulk lists are - * The lists are empty now. */ - - writel(0, &ohci->regs->ed_controlhead); - writel(0, &ohci->regs->ed_bulkhead); - - /* a reset clears this */ - writel((__u32) ohci->hcca, &ohci->regs->hcca); - - fminterval = 0x2edf; - writel((fminterval * 9) / 10, &ohci->regs->periodicstart); - fminterval |= ((((fminterval - 210) * 6) / 7) << 16); - writel(fminterval, &ohci->regs->fminterval); - writel(0x628, &ohci->regs->lsthresh); - - /* start controller operations */ - ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER; - ohci->disabled = 0; - writel(ohci->hc_control, &ohci->regs->control); - - /* disable all interrupts */ - mask = (OHCI_INTR_SO | OHCI_INTR_WDH | OHCI_INTR_SF | OHCI_INTR_RD | - OHCI_INTR_UE | OHCI_INTR_FNO | OHCI_INTR_RHSC | - OHCI_INTR_OC | OHCI_INTR_MIE); - writel(mask, &ohci->regs->intrdisable); - /* clear all interrupts */ - mask &= ~OHCI_INTR_MIE; - writel(mask, &ohci->regs->intrstatus); - /* Choose the interrupts we care about now - but w/o MIE */ - mask = OHCI_INTR_RHSC | OHCI_INTR_UE | OHCI_INTR_WDH | OHCI_INTR_SO; - writel(mask, &ohci->regs->intrenable); - -#ifdef OHCI_USE_NPS - /* required for AMD-756 and some Mac platforms */ - writel((roothub_a(ohci) | RH_A_NPS) & ~RH_A_PSM, - &ohci->regs->roothub.a); - writel(RH_HS_LPSC, &ohci->regs->roothub.status); -#endif /* OHCI_USE_NPS */ - -#define mdelay(n) ({unsigned long msec=(n); while (msec--) udelay(1000);}) - /* POTPGT delay is bits 24-31, in 2 ms units. */ - mdelay((roothub_a(ohci) >> 23) & 0x1fe); - - /* connect the virtual root hub */ - ohci->rh.devnum = 0; - - return 0; -} - -/*-------------------------------------------------------------------------*/ - -/* an interrupt happens */ - -static int hc_interrupt(void) -{ - struct ohci *ohci = &gohci; - struct ohci_regs *regs = ohci->regs; - int ints; - int stat = -1; - - if ((ohci->hcca->done_head != 0) && - !(m32_swap(ohci->hcca->done_head) & 0x01)) { - - ints = OHCI_INTR_WDH; - - } else { - ints = readl(®s->intrstatus); - if (ints == ~(u32) 0) { - ohci->disabled++; - err("%s device removed!", ohci->slot_name); - return -1; - } - ints &= readl(®s->intrenable); - if (ints == 0) { - dbg("hc_interrupt: returning..\n"); - return 0xff; - } - } - - /* dbg("Interrupt: %x frame: %x", ints, - le16_to_cpu(ohci->hcca->frame_no)); */ - - if (ints & OHCI_INTR_RHSC) { - got_rhsc = 1; - stat = 0xff; - } - - if (ints & OHCI_INTR_UE) { - ohci->disabled++; - err("OHCI Unrecoverable Error, controller usb-%s disabled", - ohci->slot_name); - /* e.g. due to PCI Master/Target Abort */ - -#ifdef DEBUG - ohci_dump(ohci, 1); -#else - wait_ms(1); -#endif - /* FIXME: be optimistic, hope that bug won't repeat often. */ - /* Make some non-interrupt context restart the controller. */ - /* Count and limit the retries though; either hardware or */ - /* software errors can go forever... */ - hc_reset(ohci); - return -1; - } - - if (ints & OHCI_INTR_WDH) { - wait_ms(1); - - writel(OHCI_INTR_WDH, ®s->intrdisable); - stat = dl_done_list(&gohci, dl_reverse_done_list(&gohci)); - writel(OHCI_INTR_WDH, ®s->intrenable); - } - - if (ints & OHCI_INTR_SO) { - dbg("USB Schedule overrun\n"); - writel(OHCI_INTR_SO, ®s->intrenable); - stat = -1; - } - - /* FIXME: this assumes SOF (1/ms) interrupts don't get lost... */ - if (ints & OHCI_INTR_SF) { - unsigned int frame = m16_swap(ohci->hcca->frame_no) & 1; - wait_ms(1); - writel(OHCI_INTR_SF, ®s->intrdisable); - if (ohci->ed_rm_list[frame] != NULL) - writel(OHCI_INTR_SF, ®s->intrenable); - stat = 0xff; - } - - writel(ints, ®s->intrstatus); - return stat; -} - -/*-------------------------------------------------------------------------*/ - -/*-------------------------------------------------------------------------*/ - -/* De-allocate all resources.. */ - -static void hc_release_ohci(struct ohci *ohci) -{ - dbg("USB HC release ohci usb-%s", ohci->slot_name); - - if (!ohci->disabled) - hc_reset(ohci); -} - -/*-------------------------------------------------------------------------*/ - -/* - * low level initalisation routine, called from usb.c - */ -static char ohci_inited = 0; - -int usb_lowlevel_init(void) -{ - struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power(); - struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio(); - - /* - * Set the 48 MHz UPLL clocking. Values are taken from - * "PLL value selection guide", 6-23, s3c2400_UM.pdf. - */ - clk_power->UPLLCON = ((40 << 12) + (1 << 4) + 2); - gpio->MISCCR |= 0x8; /* 1 = use pads related USB for USB host */ - - /* - * Enable USB host clock. - */ - clk_power->CLKCON |= (1 << 4); - - memset(&gohci, 0, sizeof(struct ohci)); - memset(&urb_priv, 0, sizeof(struct urb_priv)); - - /* align the storage */ - if ((__u32) &ghcca[0] & 0xff) { - err("HCCA not aligned!!"); - return -1; - } - phcca = &ghcca[0]; - info("aligned ghcca %p", phcca); - memset(&ohci_dev, 0, sizeof(struct ohci_device)); - if ((__u32) &ohci_dev.ed[0] & 0x7) { - err("EDs not aligned!!"); - return -1; - } - memset(gtd, 0, sizeof(struct td) * (NUM_TD + 1)); - if ((__u32) gtd & 0x7) { - err("TDs not aligned!!"); - return -1; - } - ptd = gtd; - gohci.hcca = phcca; - memset(phcca, 0, sizeof(struct ohci_hcca)); - - gohci.disabled = 1; - gohci.sleeping = 0; - gohci.irq = -1; - gohci.regs = (struct ohci_regs *)S3C24X0_USB_HOST_BASE; - - gohci.flags = 0; - gohci.slot_name = "s3c2400"; - - if (hc_reset(&gohci) < 0) { - hc_release_ohci(&gohci); - /* Initialization failed */ - clk_power->CLKCON &= ~(1 << 4); - return -1; - } - - /* FIXME this is a second HC reset; why?? */ - gohci.hc_control = OHCI_USB_RESET; - writel(gohci.hc_control, &gohci.regs->control); - wait_ms(10); - - if (hc_start(&gohci) < 0) { - err("can't start usb-%s", gohci.slot_name); - hc_release_ohci(&gohci); - /* Initialization failed */ - clk_power->CLKCON &= ~(1 << 4); - return -1; - } -#ifdef DEBUG - ohci_dump(&gohci, 1); -#else - wait_ms(1); -#endif - ohci_inited = 1; - urb_finished = 1; - - return 0; -} - -int usb_lowlevel_stop(void) -{ - struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power(); - - /* this gets called really early - before the controller has */ - /* even been initialized! */ - if (!ohci_inited) - return 0; - /* TODO release any interrupts, etc. */ - /* call hc_release_ohci() here ? */ - hc_reset(&gohci); - /* may not want to do this */ - clk_power->CLKCON &= ~(1 << 4); - return 0; -} - -#endif /* defined(CONFIG_USB_OHCI) && defined(CONFIG_S3C24X0) */ diff --git a/cpu/arm920t/s3c24x0/usb_ohci.h b/cpu/arm920t/s3c24x0/usb_ohci.h deleted file mode 100644 index f272d78859..0000000000 --- a/cpu/arm920t/s3c24x0/usb_ohci.h +++ /dev/null @@ -1,409 +0,0 @@ -/* - * URB OHCI HCD (Host Controller Driver) for USB. - * - * (C) Copyright 1999 Roman Weissgaerber - * (C) Copyright 2000-2001 David Brownell - * - * usb-ohci.h - */ - - -static int cc_to_error[16] = { - -/* mapping of the OHCI CC status to error codes */ - /* No Error */ 0, - /* CRC Error */ USB_ST_CRC_ERR, - /* Bit Stuff */ USB_ST_BIT_ERR, - /* Data Togg */ USB_ST_CRC_ERR, - /* Stall */ USB_ST_STALLED, - /* DevNotResp */ -1, - /* PIDCheck */ USB_ST_BIT_ERR, - /* UnExpPID */ USB_ST_BIT_ERR, - /* DataOver */ USB_ST_BUF_ERR, - /* DataUnder */ USB_ST_BUF_ERR, - /* reservd */ -1, - /* reservd */ -1, - /* BufferOver */ USB_ST_BUF_ERR, - /* BuffUnder */ USB_ST_BUF_ERR, - /* Not Access */ -1, - /* Not Access */ -1 -}; - -/* ED States */ -#define ED_NEW 0x00 -#define ED_UNLINK 0x01 -#define ED_OPER 0x02 -#define ED_DEL 0x04 -#define ED_URB_DEL 0x08 - -/* usb_ohci_ed */ -struct ed { - __u32 hwINFO; - __u32 hwTailP; - __u32 hwHeadP; - __u32 hwNextED; - - struct ed *ed_prev; - __u8 int_period; - __u8 int_branch; - __u8 int_load; - __u8 int_interval; - __u8 state; - __u8 type; - __u16 last_iso; - struct ed *ed_rm_list; - - struct usb_device *usb_dev; - __u32 unused[3]; -} __attribute__ ((aligned(16))); - -/* TD info field */ -#define TD_CC 0xf0000000 -#define TD_CC_GET(td_p) (((td_p) >> 28) & 0x0f) -#define TD_CC_SET(td_p, cc) \ - {(td_p) = ((td_p) & 0x0fffffff) | (((cc) & 0x0f) << 28)} -#define TD_EC 0x0C000000 -#define TD_T 0x03000000 -#define TD_T_DATA0 0x02000000 -#define TD_T_DATA1 0x03000000 -#define TD_T_TOGGLE 0x00000000 -#define TD_R 0x00040000 -#define TD_DI 0x00E00000 -#define TD_DI_SET(X) (((X) & 0x07)<< 21) -#define TD_DP 0x00180000 -#define TD_DP_SETUP 0x00000000 -#define TD_DP_IN 0x00100000 -#define TD_DP_OUT 0x00080000 - -#define TD_ISO 0x00010000 -#define TD_DEL 0x00020000 - -/* CC Codes */ -#define TD_CC_NOERROR 0x00 -#define TD_CC_CRC 0x01 -#define TD_CC_BITSTUFFING 0x02 -#define TD_CC_DATATOGGLEM 0x03 -#define TD_CC_STALL 0x04 -#define TD_DEVNOTRESP 0x05 -#define TD_PIDCHECKFAIL 0x06 -#define TD_UNEXPECTEDPID 0x07 -#define TD_DATAOVERRUN 0x08 -#define TD_DATAUNDERRUN 0x09 -#define TD_BUFFEROVERRUN 0x0C -#define TD_BUFFERUNDERRUN 0x0D -#define TD_NOTACCESSED 0x0F - - -#define MAXPSW 1 - -struct td { - __u32 hwINFO; - __u32 hwCBP; /* Current Buffer Pointer */ - __u32 hwNextTD; /* Next TD Pointer */ - __u32 hwBE; /* Memory Buffer End Pointer */ - - __u8 unused; - __u8 index; - struct ed *ed; - struct td *next_dl_td; - struct usb_device *usb_dev; - int transfer_len; - __u32 data; - - __u32 unused2[2]; -} __attribute__ ((aligned(32))); - -#define OHCI_ED_SKIP (1 << 14) - -/* - * The HCCA (Host Controller Communications Area) is a 256 byte - * structure defined in the OHCI spec. that the host controller is - * told the base address of. It must be 256-byte aligned. - */ - -#define NUM_INTS 32 /* part of the OHCI standard */ -struct ohci_hcca { - __u32 int_table[NUM_INTS]; /* Interrupt ED table */ - __u16 frame_no; /* current frame number */ - __u16 pad1; /* set to 0 on each frame_no change */ - __u32 done_head; /* info returned for an interrupt */ - u8 reserved_for_hc[116]; -} __attribute__ ((aligned(256))); - -/* - * Maximum number of root hub ports. - */ -#define MAX_ROOT_PORTS 15 /* maximum OHCI root hub ports */ - -/* - * This is the structure of the OHCI controller's memory mapped I/O - * region. This is Memory Mapped I/O. You must use the readl() and - * writel() macros defined in asm/io.h to access these!! - */ -struct ohci_regs { - /* control and status registers */ - __u32 revision; - __u32 control; - __u32 cmdstatus; - __u32 intrstatus; - __u32 intrenable; - __u32 intrdisable; - /* memory pointers */ - __u32 hcca; - __u32 ed_periodcurrent; - __u32 ed_controlhead; - __u32 ed_controlcurrent; - __u32 ed_bulkhead; - __u32 ed_bulkcurrent; - __u32 donehead; - /* frame counters */ - __u32 fminterval; - __u32 fmremaining; - __u32 fmnumber; - __u32 periodicstart; - __u32 lsthresh; - /* Root hub ports */ - struct ohci_roothub_regs { - __u32 a; - __u32 b; - __u32 status; - __u32 portstatus[MAX_ROOT_PORTS]; - } roothub; -} __attribute__ ((aligned(32))); - -/* OHCI CONTROL AND STATUS REGISTER MASKS */ - -/* - * HcControl (control) register masks - */ -#define OHCI_CTRL_CBSR (3 << 0) /* control/bulk service ratio */ -#define OHCI_CTRL_PLE (1 << 2) /* periodic list enable */ -#define OHCI_CTRL_IE (1 << 3) /* isochronous enable */ -#define OHCI_CTRL_CLE (1 << 4) /* control list enable */ -#define OHCI_CTRL_BLE (1 << 5) /* bulk list enable */ -#define OHCI_CTRL_HCFS (3 << 6) /* host controller functional state */ -#define OHCI_CTRL_IR (1 << 8) /* interrupt routing */ -#define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */ -#define OHCI_CTRL_RWE (1 << 10) /* remote wakeup enable */ - -/* pre-shifted values for HCFS */ -# define OHCI_USB_RESET (0 << 6) -# define OHCI_USB_RESUME (1 << 6) -# define OHCI_USB_OPER (2 << 6) -# define OHCI_USB_SUSPEND (3 << 6) - -/* - * HcCommandStatus (cmdstatus) register masks - */ -#define OHCI_HCR (1 << 0) /* host controller reset */ -#define OHCI_CLF (1 << 1) /* control list filled */ -#define OHCI_BLF (1 << 2) /* bulk list filled */ -#define OHCI_OCR (1 << 3) /* ownership change request */ -#define OHCI_SOC (3 << 16) /* scheduling overrun count */ - -/* - * masks used with interrupt registers: - * HcInterruptStatus (intrstatus) - * HcInterruptEnable (intrenable) - * HcInterruptDisable (intrdisable) - */ -#define OHCI_INTR_SO (1 << 0) /* scheduling overrun */ -#define OHCI_INTR_WDH (1 << 1) /* writeback of done_head */ -#define OHCI_INTR_SF (1 << 2) /* start frame */ -#define OHCI_INTR_RD (1 << 3) /* resume detect */ -#define OHCI_INTR_UE (1 << 4) /* unrecoverable error */ -#define OHCI_INTR_FNO (1 << 5) /* frame number overflow */ -#define OHCI_INTR_RHSC (1 << 6) /* root hub status change */ -#define OHCI_INTR_OC (1 << 30) /* ownership change */ -#define OHCI_INTR_MIE (1 << 31) /* master interrupt enable */ - -/* Virtual Root HUB */ -struct virt_root_hub { - int devnum; /* Address of Root Hub endpoint */ - void *dev; /* was urb */ - void *int_addr; - int send; - int interval; -}; - -/* USB HUB CONSTANTS (not OHCI-specific; see hub.h) */ - -/* destination of request */ -#define RH_INTERFACE 0x01 -#define RH_ENDPOINT 0x02 -#define RH_OTHER 0x03 - -#define RH_CLASS 0x20 -#define RH_VENDOR 0x40 - -/* Requests: bRequest << 8 | bmRequestType */ -#define RH_GET_STATUS 0x0080 -#define RH_CLEAR_FEATURE 0x0100 -#define RH_SET_FEATURE 0x0300 -#define RH_SET_ADDRESS 0x0500 -#define RH_GET_DESCRIPTOR 0x0680 -#define RH_SET_DESCRIPTOR 0x0700 -#define RH_GET_CONFIGURATION 0x0880 -#define RH_SET_CONFIGURATION 0x0900 -#define RH_GET_STATE 0x0280 -#define RH_GET_INTERFACE 0x0A80 -#define RH_SET_INTERFACE 0x0B00 -#define RH_SYNC_FRAME 0x0C80 -/* Our Vendor Specific Request */ -#define RH_SET_EP 0x2000 - - -/* Hub port features */ -#define RH_PORT_CONNECTION 0x00 -#define RH_PORT_ENABLE 0x01 -#define RH_PORT_SUSPEND 0x02 -#define RH_PORT_OVER_CURRENT 0x03 -#define RH_PORT_RESET 0x04 -#define RH_PORT_POWER 0x08 -#define RH_PORT_LOW_SPEED 0x09 - -#define RH_C_PORT_CONNECTION 0x10 -#define RH_C_PORT_ENABLE 0x11 -#define RH_C_PORT_SUSPEND 0x12 -#define RH_C_PORT_OVER_CURRENT 0x13 -#define RH_C_PORT_RESET 0x14 - -/* Hub features */ -#define RH_C_HUB_LOCAL_POWER 0x00 -#define RH_C_HUB_OVER_CURRENT 0x01 - -#define RH_DEVICE_REMOTE_WAKEUP 0x00 -#define RH_ENDPOINT_STALL 0x01 - -#define RH_ACK 0x01 -#define RH_REQ_ERR -1 -#define RH_NACK 0x00 - - -/* OHCI ROOT HUB REGISTER MASKS */ - -/* roothub.portstatus [i] bits */ -#define RH_PS_CCS 0x00000001 /* current connect status */ -#define RH_PS_PES 0x00000002 /* port enable status */ -#define RH_PS_PSS 0x00000004 /* port suspend status */ -#define RH_PS_POCI 0x00000008 /* port over current indicator */ -#define RH_PS_PRS 0x00000010 /* port reset status */ -#define RH_PS_PPS 0x00000100 /* port power status */ -#define RH_PS_LSDA 0x00000200 /* low speed device attached */ -#define RH_PS_CSC 0x00010000 /* connect status change */ -#define RH_PS_PESC 0x00020000 /* port enable status change */ -#define RH_PS_PSSC 0x00040000 /* port suspend status change */ -#define RH_PS_OCIC 0x00080000 /* over current indicator change */ -#define RH_PS_PRSC 0x00100000 /* port reset status change */ - -/* roothub.status bits */ -#define RH_HS_LPS 0x00000001 /* local power status */ -#define RH_HS_OCI 0x00000002 /* over current indicator */ -#define RH_HS_DRWE 0x00008000 /* device remote wakeup enable */ -#define RH_HS_LPSC 0x00010000 /* local power status change */ -#define RH_HS_OCIC 0x00020000 /* over current indicator change */ -#define RH_HS_CRWE 0x80000000 /* clear remote wakeup enable */ - -/* roothub.b masks */ -#define RH_B_DR 0x0000ffff /* device removable flags */ -#define RH_B_PPCM 0xffff0000 /* port power control mask */ - -/* roothub.a masks */ -#define RH_A_NDP (0xff << 0) /* number of downstream ports */ -#define RH_A_PSM (1 << 8) /* power switching mode */ -#define RH_A_NPS (1 << 9) /* no power switching */ -#define RH_A_DT (1 << 10) /* device type (mbz) */ -#define RH_A_OCPM (1 << 11) /* over current protection mode */ -#define RH_A_NOCP (1 << 12) /* no over current protection */ -#define RH_A_POTPGT (0xff << 24) /* power on to power good time */ - -/* urb */ -#define N_URB_TD 48 -struct urb_priv { - struct ed *ed; - __u16 length; /* number of tds associated with this request */ - __u16 td_cnt; /* number of tds already serviced */ - int state; - unsigned long pipe; - int actual_length; - struct td *td[N_URB_TD]; /* list pointer to all corresponding TDs - associated with this request */ -}; -#define URB_DEL 1 - -/* - * This is the full ohci controller description - * - * Note how the "proper" USB information is just - * a subset of what the full implementation needs. (Linus) - */ - - -struct ohci { - struct ohci_hcca *hcca; /* hcca */ - /*dma_addr_t hcca_dma; */ - - int irq; - int disabled; /* e.g. got a UE, we're hung */ - int sleeping; - unsigned long flags; /* for HC bugs */ - - struct ohci_regs *regs; /* OHCI controller's memory */ - - struct ed *ed_rm_list[2]; /* lists of all endpoints to be removed */ - struct ed *ed_bulktail; /* last endpoint of bulk list */ - struct ed *ed_controltail; /* last endpoint of control list */ - int intrstatus; - __u32 hc_control; /* copy of the hc control reg */ - struct usb_device *dev[32]; - struct virt_root_hub rh; - - const char *slot_name; -}; - -#define NUM_EDS 8 /* num of preallocated endpoint descriptors */ - -struct ohci_device { - struct ed ed[NUM_EDS]; - int ed_cnt; -}; - -/* hcd */ -/* endpoint */ -static int ep_link(struct ohci *ohci, struct ed *ed); -static int ep_unlink(struct ohci *ohci, struct ed *ed); -static struct ed *ep_add_ed(struct usb_device *usb_dev, unsigned long pipe); - -/*-------------------------------------------------------------------------*/ - -/* we need more TDs than EDs */ -#define NUM_TD 64 - -/* +1 so we can align the storage */ -struct td gtd[NUM_TD + 1]; - -/* pointers to aligned storage */ -struct td *ptd; - -/* TDs ... */ -static inline struct td *td_alloc(struct usb_device *usb_dev) -{ - int i; - struct td *td; - - td = NULL; - for (i = 0; i < NUM_TD; i++) { - if (ptd[i].usb_dev == NULL) { - td = &ptd[i]; - td->usb_dev = usb_dev; - break; - } - } - - return td; -} - -static inline void ed_free(struct ed *ed) -{ - ed->usb_dev = NULL; -} diff --git a/cpu/arm920t/start.S b/cpu/arm920t/start.S deleted file mode 100644 index 779f192e51..0000000000 --- a/cpu/arm920t/start.S +++ /dev/null @@ -1,436 +0,0 @@ -/* - * armboot - Startup Code for ARM920 CPU-core - * - * Copyright (c) 2001 Marius Gröger - * Copyright (c) 2002 Alex Züpke - * Copyright (c) 2002 Gary Jennejohn - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include - -/* - ************************************************************************* - * - * Jump vector table as in table 3.1 in [1] - * - ************************************************************************* - */ - - -.globl _start -_start: b start_code - 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 - -_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 (called from the ARM reset exception vector) - * - * do important init only if we don't start from memory! - * relocate armboot to ram - * setup stack - * jump to second stage - * - ************************************************************************* - */ - -_TEXT_BASE: - .word TEXT_BASE - -.globl _armboot_start -_armboot_start: - .word _start - -/* - * These are defined in the board-specific linker script. - */ -.globl _bss_start -_bss_start: - .word __bss_start - -.globl _bss_end -_bss_end: - .word _end - -#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 - - -/* - * the actual start code - */ - -start_code: - /* - * set the cpu to SVC32 mode - */ - mrs r0, cpsr - bic r0, r0, #0x1f - orr r0, r0, #0xd3 - msr cpsr, r0 - - bl coloured_LED_init - bl red_LED_on - -#if defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK) - /* - * relocate exception table - */ - ldr r0, =_start - ldr r1, =0x0 - mov r2, #16 -copyex: - subs r2, r2, #1 - ldr r3, [r0], #4 - str r3, [r1], #4 - bne copyex -#endif - -#ifdef CONFIG_S3C24X0 - /* turn off the watchdog */ - -# if defined(CONFIG_S3C2400) -# define pWTCON 0x15300000 -# define INTMSK 0x14400008 /* Interupt-Controller base addresses */ -# define CLKDIVN 0x14800014 /* clock divisor register */ -#else -# define pWTCON 0x53000000 -# define INTMSK 0x4A000008 /* Interupt-Controller base addresses */ -# define INTSUBMSK 0x4A00001C -# define CLKDIVN 0x4C000014 /* clock divisor register */ -# endif - - ldr r0, =pWTCON - mov r1, #0x0 - str r1, [r0] - - /* - * mask all IRQs by setting all bits in the INTMR - default - */ - mov r1, #0xffffffff - ldr r0, =INTMSK - str r1, [r0] -# if defined(CONFIG_S3C2410) - ldr r1, =0x3ff - ldr r0, =INTSUBMSK - str r1, [r0] -# endif - - /* FCLK:HCLK:PCLK = 1:2:4 */ - /* default FCLK is 120 MHz ! */ - ldr r0, =CLKDIVN - mov r1, #3 - str r1, [r0] -#endif /* CONFIG_S3C24X0 */ - - /* - * we do sys-critical inits only at reboot, - * not when booting from ram! - */ -#ifndef CONFIG_SKIP_LOWLEVEL_INIT - bl cpu_init_crit -#endif - -#ifndef CONFIG_SKIP_RELOCATE_UBOOT -relocate: /* relocate U-Boot to RAM */ - adr r0, _start /* r0 <- current position of code */ - ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ - cmp r0, r1 /* don't reloc during debug */ - beq stack_setup - - ldr r2, _armboot_start - ldr r3, _bss_start - sub r2, r3, r2 /* r2 <- size of armboot */ - add r2, r0, r2 /* r2 <- source end address */ - -copy_loop: - ldmia r0!, {r3-r10} /* copy from source address [r0] */ - stmia r1!, {r3-r10} /* copy to target address [r1] */ - cmp r0, r2 /* until source end addreee [r2] */ - ble copy_loop -#endif /* CONFIG_SKIP_RELOCATE_UBOOT */ - - /* Set up the stack */ -stack_setup: - ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ - sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */ - sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ -#ifdef CONFIG_USE_IRQ - sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) -#endif - sub sp, r0, #12 /* leave 3 words for abort-stack */ - -clear_bss: - ldr r0, _bss_start /* find start of bss segment */ - ldr r1, _bss_end /* stop here */ - mov r2, #0x00000000 /* clear */ - -clbss_l:str r2, [r0] /* clear loop... */ - add r0, r0, #4 - cmp r0, r1 - ble clbss_l - - ldr pc, _start_armboot - -_start_armboot: .word start_armboot - - -/* - ************************************************************************* - * - * CPU_init_critical registers - * - * setup important registers - * setup memory timing - * - ************************************************************************* - */ - - -#ifndef CONFIG_SKIP_LOWLEVEL_INIT -cpu_init_crit: - /* - * flush v4 I/D caches - */ - mov r0, #0 - mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ - mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ - - /* - * disable MMU stuff and caches - */ - mrc p15, 0, r0, c1, c0, 0 - bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) - bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) - orr r0, r0, #0x00000002 @ set bit 2 (A) Align - orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache - mcr p15, 0, r0, c1, c0, 0 - - /* - * before relocating, we have to setup RAM timing - * because memory timing is board-dependend, you will - * find a lowlevel_init.S in your board directory. - */ - mov ip, lr - - bl lowlevel_init - - mov lr, ip - mov pc, lr -#endif /* CONFIG_SKIP_LOWLEVEL_INIT */ - -/* - ************************************************************************* - * - * 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 -#define I_BIT 0x80 - -/* - * use bad_save_user_regs for abort/prefetch/undef/swi ... - * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling - */ - - .macro bad_save_user_regs - sub sp, sp, #S_FRAME_SIZE - stmia sp, {r0 - r12} @ Calling r0-r12 - ldr r2, _armboot_start - sub r2, r2, #(CONFIG_STACKSIZE) - sub r2, r2, #(CONFIG_SYS_MALLOC_LEN) - /* set base 2 words into abort stack */ - sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) - ldmia r2, {r2 - r3} @ get pc, cpsr - add r0, sp, #S_FRAME_SIZE @ restore sp_SVC - - add r5, sp, #S_SP - mov r1, lr - stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr - mov r0, sp - .endm - - .macro irq_save_user_regs - sub sp, sp, #S_FRAME_SIZE - stmia sp, {r0 - r12} @ Calling r0-r12 - add r7, sp, #S_PC - stmdb r7, {sp, lr}^ @ Calling SP, LR - str lr, [r7, #0] @ Save calling PC - mrs r6, spsr - str r6, [r7, #4] @ Save CPSR - str r0, [r7, #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 - /* return & move spsr_svc into cpsr */ - subs pc, lr, #4 - .endm - - .macro get_bad_stack - ldr r13, _armboot_start @ setup our mode stack - sub r13, r13, #(CONFIG_STACKSIZE) - sub r13, r13, #(CONFIG_SYS_MALLOC_LEN) - /* reserve a couple spots in abort stack */ - sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) - - 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 - msr spsr, 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 - /* someone ought to write a more effiction fiq_save_user_regs */ - irq_save_user_regs - bl do_fiq - 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 diff --git a/cpu/arm920t/u-boot.lds b/cpu/arm920t/u-boot.lds deleted file mode 100644 index d9bfbee73b..0000000000 --- a/cpu/arm920t/u-boot.lds +++ /dev/null @@ -1,64 +0,0 @@ -/* - * (c) Copyright 2004 - * Techware Information Technology, Inc. - * Ming-Len Wu - * - * (C) Copyright 2000-2004 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - */ - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -ENTRY(_start) -SECTIONS -{ - . = 0x00000000; - - . = ALIGN(4); - .text : - { - cpu/arm920t/start.o (.text) - *(.text) - } - - . = ALIGN(4); - .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } - - . = ALIGN(4); - .data : { *(.data) } - - . = ALIGN(4); - .got : { *(.got) } - - . = .; - __u_boot_cmd_start = .; - .u_boot_cmd : { *(.u_boot_cmd) } - __u_boot_cmd_end = .; - - . = ALIGN(4); - __bss_start = .; - .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } - _end = .; -} diff --git a/cpu/arm925t/Makefile b/cpu/arm925t/Makefile deleted file mode 100644 index 8d0e88f902..0000000000 --- a/cpu/arm925t/Makefile +++ /dev/null @@ -1,50 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(CPU).a - -START = start.o - -COBJS += cpu.o -COBJS += omap925.o -COBJS += timer.o - -SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) -START := $(addprefix $(obj),$(START)) - -all: $(obj).depend $(START) $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/arm925t/config.mk b/cpu/arm925t/config.mk deleted file mode 100644 index 8f6c1a354c..0000000000 --- a/cpu/arm925t/config.mk +++ /dev/null @@ -1,32 +0,0 @@ -# -# (C) Copyright 2002 -# Gary Jennejohn, DENX Software Engineering, -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float - -PLATFORM_CPPFLAGS += -march=armv4 -# ========================================================================= -# -# Supply options according to compiler version -# -# ========================================================================= -PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/arm925t/cpu.c b/cpu/arm925t/cpu.c deleted file mode 100644 index 71700bb175..0000000000 --- a/cpu/arm925t/cpu.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * CPU specific code - */ - -#include -#include -#include -#include - -static void cache_flush(void); - -int cleanup_before_linux (void) -{ - /* - * this function is called just before we call linux - * it prepares the processor for linux - * - * we turn off caches etc ... - */ - - disable_interrupts (); - - - /* turn off I/D-cache */ - icache_disable(); - dcache_disable(); - /* flush I/D-cache */ - cache_flush(); - - return 0; -} - -/* flush I/D-cache */ -static void cache_flush (void) -{ - unsigned long i = 0; - - asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); -} diff --git a/cpu/arm925t/omap925.c b/cpu/arm925t/omap925.c deleted file mode 100644 index 65dab9f88d..0000000000 --- a/cpu/arm925t/omap925.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * (C) Copyright 2003 - * Texas Instruments - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -#define MIF_CONFIG_REG 0xFFFECC0C -#define FLASH_GLOBAL_CTRL_NWP 1 - -void archflashwp (void *archdata, int wp) -{ - ulong *fgc = (ulong *) MIF_CONFIG_REG; - - if (wp == 1) - *fgc &= ~FLASH_GLOBAL_CTRL_NWP; - else - *fgc |= FLASH_GLOBAL_CTRL_NWP; -} diff --git a/cpu/arm925t/start.S b/cpu/arm925t/start.S deleted file mode 100644 index 567e80479e..0000000000 --- a/cpu/arm925t/start.S +++ /dev/null @@ -1,429 +0,0 @@ -/* - * armboot - Startup Code for ARM925 CPU-core - * - * Copyright (c) 2003 Texas Instruments - * - * ----- Adapted for OMAP1510 from ARM920 code ------ - * - * Copyright (c) 2001 Marius Gröger - * Copyright (c) 2002 Alex Züpke - * Copyright (c) 2002 Gary Jennejohn - * Copyright (c) 2003 Richard Woodruff - * Copyright (c) 2003 Kshitij - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - - -#include -#include - -#if defined(CONFIG_OMAP1510) -#include <./configs/omap1510.h> -#endif - -/* - ************************************************************************* - * - * Jump vector table as in table 3.1 in [1] - * - ************************************************************************* - */ - - -.globl _start -_start: b 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 - -_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! - * setup Memory and board specific bits prior to relocation. - * relocate armboot to ram - * setup stack - * - ************************************************************************* - */ - -_TEXT_BASE: - .word TEXT_BASE - -.globl _armboot_start -_armboot_start: - .word _start - -/* - * These are defined in the board-specific linker script. - */ -.globl _bss_start -_bss_start: - .word __bss_start - -.globl _bss_end -_bss_end: - .word _end - -#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 - - -/* - * the actual reset code - */ - -reset: - /* - * set the cpu to SVC32 mode - */ - mrs r0,cpsr - bic r0,r0,#0x1f - orr r0,r0,#0xd3 - msr cpsr,r0 - - /* - * Set up 925T mode - */ - mov r1, #0x81 /* Set ARM925T configuration. */ - mcr p15, 0, r1, c15, c1, 0 /* Write ARM925T configuration register. */ - - /* - * turn off the watchdog, unlock/diable sequence - */ - mov r1, #0xF5 - ldr r0, =WDTIM_MODE - strh r1, [r0] - mov r1, #0xA0 - strh r1, [r0] - - /* - * mask all IRQs by setting all bits in the INTMR - default - */ - mov r1, #0xffffffff - ldr r0, =REG_IHL1_MIR - str r1, [r0] - ldr r0, =REG_IHL2_MIR - str r1, [r0] - - /* - * wait for dpll to lock - */ - ldr r0, =CK_DPLL1 - mov r1, #0x10 - strh r1, [r0] -poll1: - ldrh r1, [r0] - ands r1, r1, #0x01 - beq poll1 - - /* - * we do sys-critical inits only at reboot, - * not when booting from ram! - */ -#ifndef CONFIG_SKIP_LOWLEVEL_INIT - bl cpu_init_crit -#endif - -#ifndef CONFIG_SKIP_RELOCATE_UBOOT -relocate: /* relocate U-Boot to RAM */ - adr r0, _start /* r0 <- current position of code */ - ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ - cmp r0, r1 /* don't reloc during debug */ - beq stack_setup - - ldr r2, _armboot_start - ldr r3, _bss_start - sub r2, r3, r2 /* r2 <- size of armboot */ - add r2, r0, r2 /* r2 <- source end address */ - -copy_loop: - ldmia r0!, {r3-r10} /* copy from source address [r0] */ - stmia r1!, {r3-r10} /* copy to target address [r1] */ - cmp r0, r2 /* until source end addreee [r2] */ - ble copy_loop -#endif /* CONFIG_SKIP_RELOCATE_UBOOT */ - - /* Set up the stack */ -stack_setup: - ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ - sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */ - sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ -#ifdef CONFIG_USE_IRQ - sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) -#endif - sub sp, r0, #12 /* leave 3 words for abort-stack */ - -clear_bss: - ldr r0, _bss_start /* find start of bss segment */ - ldr r1, _bss_end /* stop here */ - mov r2, #0x00000000 /* clear */ - -clbss_l:str r2, [r0] /* clear loop... */ - add r0, r0, #4 - cmp r0, r1 - ble clbss_l - - ldr pc, _start_armboot - -_start_armboot: .word start_armboot - - -/* - ************************************************************************* - * - * CPU_init_critical registers - * - * setup important registers - * setup memory timing - * - ************************************************************************* - */ - - -cpu_init_crit: - /* - * flush v4 I/D caches - */ - mov r0, #0 - mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ - mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ - - /* - * disable MMU stuff and caches - */ - mrc p15, 0, r0, c1, c0, 0 - bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) - bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) - orr r0, r0, #0x00000002 @ set bit 2 (A) Align - orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache - mcr p15, 0, r0, c1, c0, 0 - - /* - * Go setup Memory and board specific bits prior to relocation. - */ - mov ip, lr /* perserve link reg across call */ - bl lowlevel_init /* go setup pll,mux,memory */ - mov lr, ip /* restore link */ - mov pc, lr /* back to my caller */ -/* - ************************************************************************* - * - * 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 -#define I_BIT 0x80 - -/* - * use bad_save_user_regs for abort/prefetch/undef/swi ... - * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling - */ - - .macro bad_save_user_regs - sub sp, sp, #S_FRAME_SIZE @ carve out a frame on current user stack - stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12 - - ldr r2, _armboot_start - sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) - sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack - ldmia r2, {r2 - r3} @ get values for "aborted" pc and cpsr (into parm regs) - add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack - - add r5, sp, #S_SP - mov r1, lr - stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr - mov r0, sp @ save current stack into r0 (param register) - .endm - - .macro irq_save_user_regs - sub sp, sp, #S_FRAME_SIZE - stmia sp, {r0 - r12} @ Calling r0-r12 - add r8, sp, #S_PC @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good. - 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, _armboot_start @ setup our mode stack - sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) - sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack - - str lr, [r13] @ save caller lr in position 0 of saved stack - mrs lr, spsr @ get the spsr - str lr, [r13, #4] @ save spsr in position 1 of saved stack - - mov r13, #MODE_SVC @ prepare SVC-Mode - @ msr spsr_c, r13 - msr spsr, r13 @ switch modes, make sure moves will execute - mov lr, pc @ capture return pc - movs pc, lr @ jump to next instruction & switch modes. - .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 - /* someone ought to write a more effiction fiq_save_user_regs */ - irq_save_user_regs - bl do_fiq - 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 - - .align 5 -.globl reset_cpu -reset_cpu: - ldr r1, rstctl1 /* get clkm1 reset ctl */ - mov r3, #0x3 /* dsp_en + arm_rst = global reset */ - strh r3, [r1] /* force reset */ - mov r0, r0 -_loop_forever: - b _loop_forever -rstctl1: - .word 0xfffece10 diff --git a/cpu/arm925t/timer.c b/cpu/arm925t/timer.c deleted file mode 100644 index 7dfe2b5646..0000000000 --- a/cpu/arm925t/timer.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * (C) Copyright 2009 - * 2N Telekomunikace, - * - * (C) Copyright 2003 - * Texas Instruments, - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include - -#define TIMER_LOAD_VAL 0xffffffff -#define TIMER_CLOCK (CONFIG_SYS_CLK_FREQ / (2 << CONFIG_SYS_PTV)) - -static uint32_t timestamp; -static uint32_t lastdec; - -/* nothing really to do with interrupts, just starts up a counter. */ -int timer_init (void) -{ - /* Start the decrementer ticking down from 0xffffffff */ - __raw_writel(TIMER_LOAD_VAL, CONFIG_SYS_TIMERBASE + LOAD_TIM); - __raw_writel(MPUTIM_ST | MPUTIM_AR | MPUTIM_CLOCK_ENABLE | - (CONFIG_SYS_PTV << MPUTIM_PTV_BIT), - CONFIG_SYS_TIMERBASE + CNTL_TIMER); - - /* init the timestamp and lastdec value */ - reset_timer_masked(); - - return 0; -} - -/* - * timer without interrupts - */ - -void reset_timer (void) -{ - reset_timer_masked (); -} - -ulong get_timer (ulong base) -{ - return get_timer_masked () - base; -} - -void set_timer (ulong t) -{ - timestamp = t; -} - -/* delay x useconds AND preserve advance timestamp value */ -void __udelay (unsigned long usec) -{ - int32_t tmo = usec * (TIMER_CLOCK / 1000) / 1000; - uint32_t now, last = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM); - - while (tmo > 0) { - now = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM); - if (last < now) /* count down timer underflow */ - tmo -= TIMER_LOAD_VAL - now + last; - else - tmo -= last - now; - last = now; - } -} - -void reset_timer_masked (void) -{ - /* reset time */ - lastdec = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM) / - (TIMER_CLOCK / CONFIG_SYS_HZ); - timestamp = 0; /* start "advancing" time stamp from 0 */ -} - -ulong get_timer_masked (void) -{ - uint32_t now = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM) / - (TIMER_CLOCK / CONFIG_SYS_HZ); - if (lastdec < now) /* count down timer underflow */ - timestamp += TIMER_LOAD_VAL / (TIMER_CLOCK / CONFIG_SYS_HZ) - - now + lastdec; - else - timestamp += lastdec - now; - lastdec = now; - - return timestamp; -} - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return get_timer(0); -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk (void) -{ - return CONFIG_SYS_HZ; -} diff --git a/cpu/arm925t/u-boot.lds b/cpu/arm925t/u-boot.lds deleted file mode 100644 index 694780eba2..0000000000 --- a/cpu/arm925t/u-boot.lds +++ /dev/null @@ -1,59 +0,0 @@ -/* - * (C) Copyright 2004 - * Wolfgang Denk, DENX Software Engineering, - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -ENTRY(_start) -SECTIONS -{ - . = 0x00000000; - - . = ALIGN(4); - .text : - { - cpu/arm925t/start.o (.text) - *(.text) - } - - . = ALIGN(4); - .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } - - . = ALIGN(4); - .data : { *(.data) } - - . = ALIGN(4); - .got : { *(.got) } - - . = .; - __u_boot_cmd_start = .; - .u_boot_cmd : { *(.u_boot_cmd) } - __u_boot_cmd_end = .; - - . = ALIGN(4); - __bss_start = .; - .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } - _end = .; -} diff --git a/cpu/arm926ejs/Makefile b/cpu/arm926ejs/Makefile deleted file mode 100644 index 7701b03bbe..0000000000 --- a/cpu/arm926ejs/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(CPU).a - -START = start.o -COBJS = cpu.o - -SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) -START := $(addprefix $(obj),$(START)) - -all: $(obj).depend $(START) $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/arm926ejs/at91/Makefile b/cpu/arm926ejs/at91/Makefile deleted file mode 100644 index 4f467be91c..0000000000 --- a/cpu/arm926ejs/at91/Makefile +++ /dev/null @@ -1,62 +0,0 @@ -# -# (C) Copyright 2000-2008 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(SOC).a - -COBJS-$(CONFIG_AT91CAP9) += at91cap9_devices.o -COBJS-$(CONFIG_AT91SAM9260) += at91sam9260_devices.o -COBJS-$(CONFIG_AT91SAM9G20) += at91sam9260_devices.o -COBJS-$(CONFIG_AT91SAM9261) += at91sam9261_devices.o -COBJS-$(CONFIG_AT91SAM9G10) += at91sam9261_devices.o -COBJS-$(CONFIG_AT91SAM9263) += at91sam9263_devices.o -COBJS-$(CONFIG_AT91SAM9RL) += at91sam9rl_devices.o -COBJS-$(CONFIG_AT91SAM9M10G45) += at91sam9m10g45_devices.o -COBJS-$(CONFIG_AT91SAM9G45) += at91sam9m10g45_devices.o -COBJS-$(CONFIG_AT91_LED) += led.o -COBJS-y += clock.o -COBJS-y += cpu.o -COBJS-y += reset.o -COBJS-y += timer.o - -ifndef CONFIG_SKIP_LOWLEVEL_INIT -SOBJS-y := lowlevel_init.o -endif - -SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) - -all: $(obj).depend $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/arm926ejs/at91/at91cap9_devices.c b/cpu/arm926ejs/at91/at91cap9_devices.c deleted file mode 100644 index 2d878fdde6..0000000000 --- a/cpu/arm926ejs/at91/at91cap9_devices.c +++ /dev/null @@ -1,205 +0,0 @@ -/* - * (C) Copyright 2007-2008 - * Stelian Pop - * Lead Tech Design - * - * (C) Copyright 2009 - * Daniel Gorsulowski - * esd electronic system design gmbh - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include - -void at91_serial0_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTA, 22, 1); /* TXD0 */ - at91_set_a_periph(AT91_PIO_PORTA, 23, 0); /* RXD0 */ - writel(1 << AT91CAP9_ID_US0, &pmc->pcer); -} - -void at91_serial1_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTD, 0, 1); /* TXD1 */ - at91_set_a_periph(AT91_PIO_PORTD, 1, 0); /* RXD1 */ - writel(1 << AT91CAP9_ID_US1, &pmc->pcer); -} - -void at91_serial2_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTD, 2, 1); /* TXD2 */ - at91_set_a_periph(AT91_PIO_PORTD, 3, 0); /* RXD2 */ - writel(1 << AT91CAP9_ID_US2, &pmc->pcer); -} - -void at91_serial3_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTC, 30, 0); /* DRXD */ - at91_set_a_periph(AT91_PIO_PORTC, 31, 1); /* DTXD */ - writel(1 << AT91_ID_SYS, &pmc->pcer); -} - -void at91_serial_hw_init(void) -{ -#ifdef CONFIG_USART0 - at91_serial0_hw_init(); -#endif - -#ifdef CONFIG_USART1 - at91_serial1_hw_init(); -#endif - -#ifdef CONFIG_USART2 - at91_serial2_hw_init(); -#endif - -#ifdef CONFIG_USART3 /* DBGU */ - at91_serial3_hw_init(); -#endif -} - -#ifdef CONFIG_HAS_DATAFLASH -void at91_spi0_hw_init(unsigned long cs_mask) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_b_periph(AT91_PIO_PORTA, 0, 0); /* SPI0_MISO */ - at91_set_b_periph(AT91_PIO_PORTA, 1, 0); /* SPI0_MOSI */ - at91_set_b_periph(AT91_PIO_PORTA, 2, 0); /* SPI0_SPCK */ - - /* Enable clock */ - writel(1 << AT91CAP9_ID_SPI0, &pmc->pcer); - - if (cs_mask & (1 << 0)) { - at91_set_b_periph(AT91_PIO_PORTA, 5, 1); - } - if (cs_mask & (1 << 1)) { - at91_set_b_periph(AT91_PIO_PORTA, 3, 1); - } - if (cs_mask & (1 << 2)) { - at91_set_b_periph(AT91_PIO_PORTD, 0, 1); - } - if (cs_mask & (1 << 3)) { - at91_set_b_periph(AT91_PIO_PORTD, 1, 1); - } - if (cs_mask & (1 << 4)) { - at91_set_pio_output(AT91_PIO_PORTA, 5, 1); - } - if (cs_mask & (1 << 5)) { - at91_set_pio_output(AT91_PIO_PORTA, 3, 1); - } - if (cs_mask & (1 << 6)) { - at91_set_pio_output(AT91_PIO_PORTD, 0, 1); - } - if (cs_mask & (1 << 7)) { - at91_set_pio_output(AT91_PIO_PORTD, 1, 1); - } -} - -void at91_spi1_hw_init(unsigned long cs_mask) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTB, 12, 0); /* SPI1_MISO */ - at91_set_a_periph(AT91_PIO_PORTB, 13, 0); /* SPI1_MOSI */ - at91_set_a_periph(AT91_PIO_PORTB, 14, 0); /* SPI1_SPCK */ - - /* Enable clock */ - writel(1 << AT91CAP9_ID_SPI1, &pmc->pcer); - - if (cs_mask & (1 << 0)) { - at91_set_a_periph(AT91_PIO_PORTB, 15, 1); - } - if (cs_mask & (1 << 1)) { - at91_set_a_periph(AT91_PIO_PORTB, 16, 1); - } - if (cs_mask & (1 << 2)) { - at91_set_a_periph(AT91_PIO_PORTB, 17, 1); - } - if (cs_mask & (1 << 3)) { - at91_set_a_periph(AT91_PIO_PORTB, 18, 1); - } - if (cs_mask & (1 << 4)) { - at91_set_pio_output(AT91_PIO_PORTB, 15, 1); - } - if (cs_mask & (1 << 5)) { - at91_set_pio_output(AT91_PIO_PORTB, 16, 1); - } - if (cs_mask & (1 << 6)) { - at91_set_pio_output(AT91_PIO_PORTB, 17, 1); - } - if (cs_mask & (1 << 7)) { - at91_set_pio_output(AT91_PIO_PORTB, 18, 1); - } - -} -#endif - -#ifdef CONFIG_MACB -void at91_macb_hw_init(void) -{ - at91_set_a_periph(AT91_PIO_PORTB, 21, 0); /* ETXCK_EREFCK */ - at91_set_a_periph(AT91_PIO_PORTB, 22, 0); /* ERXDV */ - at91_set_a_periph(AT91_PIO_PORTB, 25, 0); /* ERX0 */ - at91_set_a_periph(AT91_PIO_PORTB, 26, 0); /* ERX1 */ - at91_set_a_periph(AT91_PIO_PORTB, 27, 0); /* ERXER */ - at91_set_a_periph(AT91_PIO_PORTB, 28, 0); /* ETXEN */ - at91_set_a_periph(AT91_PIO_PORTB, 23, 0); /* ETX0 */ - at91_set_a_periph(AT91_PIO_PORTB, 24, 0); /* ETX1 */ - at91_set_a_periph(AT91_PIO_PORTB, 30, 0); /* EMDIO */ - at91_set_a_periph(AT91_PIO_PORTB, 29, 0); /* EMDC */ - -#ifndef CONFIG_RMII - at91_set_b_periph(AT91_PIO_PORTC, 25, 0); /* ECRS */ - at91_set_b_periph(AT91_PIO_PORTC, 26, 0); /* ECOL */ - at91_set_b_periph(AT91_PIO_PORTC, 22, 0); /* ERX2 */ - at91_set_b_periph(AT91_PIO_PORTC, 23, 0); /* ERX3 */ - at91_set_b_periph(AT91_PIO_PORTC, 27, 0); /* ERXCK */ - at91_set_b_periph(AT91_PIO_PORTC, 20, 0); /* ETX2 */ - at91_set_b_periph(AT91_PIO_PORTC, 21, 0); /* ETX3 */ - at91_set_b_periph(AT91_PIO_PORTC, 24, 0); /* ETXER */ -#endif -} -#endif - -#ifdef CONFIG_AT91_CAN -void at91_can_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTA, 12, 0); /* CAN_TX */ - at91_set_a_periph(AT91_PIO_PORTA, 13, 1); /* CAN_RX */ - - /* Enable clock */ - writel(1 << AT91CAP9_ID_CAN, &pmc->pcer); -} -#endif diff --git a/cpu/arm926ejs/at91/at91sam9260_devices.c b/cpu/arm926ejs/at91/at91sam9260_devices.c deleted file mode 100644 index 77d49ab1c7..0000000000 --- a/cpu/arm926ejs/at91/at91sam9260_devices.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * (C) Copyright 2007-2008 - * Stelian Pop - * Lead Tech Design - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include - -void at91_serial0_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTB, 4, 1); /* TXD0 */ - at91_set_a_periph(AT91_PIO_PORTB, 5, 0); /* RXD0 */ - writel(1 << AT91SAM9260_ID_US0, &pmc->pcer); -} - -void at91_serial1_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTB, 6, 1); /* TXD1 */ - at91_set_a_periph(AT91_PIO_PORTB, 7, 0); /* RXD1 */ - writel(1 << AT91SAM9260_ID_US1, &pmc->pcer); -} - -void at91_serial2_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTB, 8, 1); /* TXD2 */ - at91_set_a_periph(AT91_PIO_PORTB, 9, 0); /* RXD2 */ - writel(1 << AT91SAM9260_ID_US2, &pmc->pcer); -} - -void at91_serial3_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTB, 14, 0); /* DRXD */ - at91_set_a_periph(AT91_PIO_PORTB, 15, 1); /* DTXD */ - writel(1 << AT91_ID_SYS, &pmc->pcer); -} - -void at91_serial_hw_init(void) -{ -#ifdef CONFIG_USART0 - at91_serial0_hw_init(); -#endif - -#ifdef CONFIG_USART1 - at91_serial1_hw_init(); -#endif - -#ifdef CONFIG_USART2 - at91_serial2_hw_init(); -#endif - -#ifdef CONFIG_USART3 /* DBGU */ - at91_serial3_hw_init(); -#endif -} - -#if defined(CONFIG_HAS_DATAFLASH) || defined(CONFIG_ATMEL_SPI) -void at91_spi0_hw_init(unsigned long cs_mask) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTA, 0, 0); /* SPI0_MISO */ - at91_set_a_periph(AT91_PIO_PORTA, 1, 0); /* SPI0_MOSI */ - at91_set_a_periph(AT91_PIO_PORTA, 2, 0); /* SPI0_SPCK */ - - /* Enable clock */ - writel(1 << AT91SAM9260_ID_SPI0, &pmc->pcer); - - if (cs_mask & (1 << 0)) { - at91_set_a_periph(AT91_PIO_PORTA, 3, 1); - } - if (cs_mask & (1 << 1)) { - at91_set_b_periph(AT91_PIO_PORTC, 11, 1); - } - if (cs_mask & (1 << 2)) { - at91_set_b_periph(AT91_PIO_PORTC, 16, 1); - } - if (cs_mask & (1 << 3)) { - at91_set_b_periph(AT91_PIO_PORTC, 17, 1); - } - if (cs_mask & (1 << 4)) { - at91_set_pio_output(AT91_PIO_PORTA, 3, 1); - } - if (cs_mask & (1 << 5)) { - at91_set_pio_output(AT91_PIO_PORTC, 11, 1); - } - if (cs_mask & (1 << 6)) { - at91_set_pio_output(AT91_PIO_PORTC, 16, 1); - } - if (cs_mask & (1 << 7)) { - at91_set_pio_output(AT91_PIO_PORTC, 17, 1); - } -} - -void at91_spi1_hw_init(unsigned long cs_mask) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTB, 0, 0); /* SPI1_MISO */ - at91_set_a_periph(AT91_PIO_PORTB, 1, 0); /* SPI1_MOSI */ - at91_set_a_periph(AT91_PIO_PORTB, 2, 0); /* SPI1_SPCK */ - - /* Enable clock */ - writel(1 << AT91SAM9260_ID_SPI1, &pmc->pcer); - - if (cs_mask & (1 << 0)) { - at91_set_a_periph(AT91_PIO_PORTB, 3, 1); - } - if (cs_mask & (1 << 1)) { - at91_set_b_periph(AT91_PIO_PORTC, 5, 1); - } - if (cs_mask & (1 << 2)) { - at91_set_b_periph(AT91_PIO_PORTC, 4, 1); - } - if (cs_mask & (1 << 3)) { - at91_set_pio_output(AT91_PIO_PORTC, 3, 1); - } - if (cs_mask & (1 << 4)) { - at91_set_pio_output(AT91_PIO_PORTB, 3, 1); - } - if (cs_mask & (1 << 5)) { - at91_set_pio_output(AT91_PIO_PORTC, 5, 1); - } - if (cs_mask & (1 << 6)) { - at91_set_pio_output(AT91_PIO_PORTC, 4, 1); - } - if (cs_mask & (1 << 7)) { - at91_set_pio_output(AT91_PIO_PORTC, 3, 1); - } -} -#endif - -#ifdef CONFIG_MACB -void at91_macb_hw_init(void) -{ - at91_set_a_periph(AT91_PIO_PORTA, 19, 0); /* ETXCK_EREFCK */ - at91_set_a_periph(AT91_PIO_PORTA, 17, 0); /* ERXDV */ - at91_set_a_periph(AT91_PIO_PORTA, 14, 0); /* ERX0 */ - at91_set_a_periph(AT91_PIO_PORTA, 15, 0); /* ERX1 */ - at91_set_a_periph(AT91_PIO_PORTA, 18, 0); /* ERXER */ - at91_set_a_periph(AT91_PIO_PORTA, 16, 0); /* ETXEN */ - at91_set_a_periph(AT91_PIO_PORTA, 12, 0); /* ETX0 */ - at91_set_a_periph(AT91_PIO_PORTA, 13, 0); /* ETX1 */ - at91_set_a_periph(AT91_PIO_PORTA, 21, 0); /* EMDIO */ - at91_set_a_periph(AT91_PIO_PORTA, 20, 0); /* EMDC */ - -#ifndef CONFIG_RMII - at91_set_b_periph(AT91_PIO_PORTA, 28, 0); /* ECRS */ - at91_set_b_periph(AT91_PIO_PORTA, 29, 0); /* ECOL */ - at91_set_b_periph(AT91_PIO_PORTA, 25, 0); /* ERX2 */ - at91_set_b_periph(AT91_PIO_PORTA, 26, 0); /* ERX3 */ - at91_set_b_periph(AT91_PIO_PORTA, 27, 0); /* ERXCK */ -#if defined(CONFIG_AT91SAM9260EK) || defined(CONFIG_AFEB9260) - /* - * use PA10, PA11 for ETX2, ETX3. - * PA23 and PA24 are for TWI EEPROM - */ - at91_set_b_periph(AT91_PIO_PORTA, 10, 0); /* ETX2 */ - at91_set_b_periph(AT91_PIO_PORTA, 11, 0); /* ETX3 */ -#else - at91_set_b_periph(AT91_PIO_PORTA, 23, 0); /* ETX2 */ - at91_set_b_periph(AT91_PIO_PORTA, 24, 0); /* ETX3 */ -#endif - at91_set_b_periph(AT91_PIO_PORTA, 22, 0); /* ETXER */ -#endif -} -#endif diff --git a/cpu/arm926ejs/at91/at91sam9261_devices.c b/cpu/arm926ejs/at91/at91sam9261_devices.c deleted file mode 100644 index b4353ef5cb..0000000000 --- a/cpu/arm926ejs/at91/at91sam9261_devices.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * (C) Copyright 2007-2008 - * Stelian Pop - * Lead Tech Design - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include - -void at91_serial0_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTC, 8, 1); /* TXD0 */ - at91_set_a_periph(AT91_PIO_PORTC, 9, 0); /* RXD0 */ - writel(1 << AT91SAM9261_ID_US0, &pmc->pcer); -} - -void at91_serial1_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTC, 12, 1); /* TXD1 */ - at91_set_a_periph(AT91_PIO_PORTC, 13, 0); /* RXD1 */ - writel(1 << AT91SAM9261_ID_US1, &pmc->pcer); -} - -void at91_serial2_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTC, 14, 1); /* TXD2 */ - at91_set_a_periph(AT91_PIO_PORTC, 15, 0); /* RXD2 */ - writel(1 << AT91SAM9261_ID_US2, &pmc->pcer); -} - -void at91_serial3_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTA, 9, 0); /* DRXD */ - at91_set_a_periph(AT91_PIO_PORTA, 10, 1); /* DTXD */ - writel(1 << AT91_ID_SYS, &pmc->pcer); -} - -void at91_serial_hw_init(void) -{ -#ifdef CONFIG_USART0 - at91_serial0_hw_init(); -#endif - -#ifdef CONFIG_USART1 - at91_serial1_hw_init(); -#endif - -#ifdef CONFIG_USART2 - at91_serial2_hw_init(); -#endif - -#ifdef CONFIG_USART3 /* DBGU */ - at91_serial3_hw_init(); -#endif -} - -#ifdef CONFIG_HAS_DATAFLASH -void at91_spi0_hw_init(unsigned long cs_mask) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTA, 0, 0); /* SPI0_MISO */ - at91_set_a_periph(AT91_PIO_PORTA, 1, 0); /* SPI0_MOSI */ - at91_set_a_periph(AT91_PIO_PORTA, 2, 0); /* SPI0_SPCK */ - - /* Enable clock */ - writel(1 << AT91SAM9261_ID_SPI0, &pmc->pcer); - - if (cs_mask & (1 << 0)) { - at91_set_a_periph(AT91_PIO_PORTA, 3, 1); - } - if (cs_mask & (1 << 1)) { - at91_set_a_periph(AT91_PIO_PORTA, 4, 1); - } - if (cs_mask & (1 << 2)) { - at91_set_a_periph(AT91_PIO_PORTA, 5, 1); - } - if (cs_mask & (1 << 3)) { - at91_set_a_periph(AT91_PIO_PORTA, 6, 1); - } - if (cs_mask & (1 << 4)) { - at91_set_pio_output(AT91_PIO_PORTA, 3, 1); - } - if (cs_mask & (1 << 5)) { - at91_set_pio_output(AT91_PIO_PORTA, 4, 1); - } - if (cs_mask & (1 << 6)) { - at91_set_pio_output(AT91_PIO_PORTA, 5, 1); - } - if (cs_mask & (1 << 7)) { - at91_set_pio_output(AT91_PIO_PORTA, 6, 1); - } -} - -void at91_spi1_hw_init(unsigned long cs_mask) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTB, 30, 0); /* SPI1_MISO */ - at91_set_a_periph(AT91_PIO_PORTB, 31, 0); /* SPI1_MOSI */ - at91_set_a_periph(AT91_PIO_PORTB, 29, 0); /* SPI1_SPCK */ - - /* Enable clock */ - writel(1 << AT91SAM9261_ID_SPI1, &pmc->pcer); - - if (cs_mask & (1 << 0)) { - at91_set_a_periph(AT91_PIO_PORTB, 28, 1); - } - if (cs_mask & (1 << 1)) { - at91_set_b_periph(AT91_PIO_PORTA, 24, 1); - } - if (cs_mask & (1 << 2)) { - at91_set_b_periph(AT91_PIO_PORTA, 25, 1); - } - if (cs_mask & (1 << 3)) { - at91_set_a_periph(AT91_PIO_PORTA, 26, 1); - } - if (cs_mask & (1 << 4)) { - at91_set_pio_output(AT91_PIO_PORTB, 28, 1); - } - if (cs_mask & (1 << 5)) { - at91_set_pio_output(AT91_PIO_PORTA, 24, 1); - } - if (cs_mask & (1 << 6)) { - at91_set_pio_output(AT91_PIO_PORTA, 25, 1); - } - if (cs_mask & (1 << 7)) { - at91_set_pio_output(AT91_PIO_PORTA, 26, 1); - } -} -#endif diff --git a/cpu/arm926ejs/at91/at91sam9263_devices.c b/cpu/arm926ejs/at91/at91sam9263_devices.c deleted file mode 100644 index deda3e54d9..0000000000 --- a/cpu/arm926ejs/at91/at91sam9263_devices.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * (C) Copyright 2007-2008 - * Stelian Pop - * Lead Tech Design - * - * (C) Copyright 2009 - * Daniel Gorsulowski - * esd electronic system design gmbh - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include - -void at91_serial0_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTA, 26, 1); /* TXD0 */ - at91_set_a_periph(AT91_PIO_PORTA, 27, 0); /* RXD0 */ - writel(1 << AT91SAM9263_ID_US0, &pmc->pcer); -} - -void at91_serial1_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTD, 0, 1); /* TXD1 */ - at91_set_a_periph(AT91_PIO_PORTD, 1, 0); /* RXD1 */ - writel(1 << AT91SAM9263_ID_US1, &pmc->pcer); -} - -void at91_serial2_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTD, 2, 1); /* TXD2 */ - at91_set_a_periph(AT91_PIO_PORTD, 3, 0); /* RXD2 */ - writel(1 << AT91SAM9263_ID_US2, &pmc->pcer); -} - -void at91_serial3_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTC, 30, 0); /* DRXD */ - at91_set_a_periph(AT91_PIO_PORTC, 31, 1); /* DTXD */ - writel(1 << AT91_ID_SYS, &pmc->pcer); -} - -void at91_serial_hw_init(void) -{ -#ifdef CONFIG_USART0 - at91_serial0_hw_init(); -#endif - -#ifdef CONFIG_USART1 - at91_serial1_hw_init(); -#endif - -#ifdef CONFIG_USART2 - at91_serial2_hw_init(); -#endif - -#ifdef CONFIG_USART3 /* DBGU */ - at91_serial3_hw_init(); -#endif -} - -#ifdef CONFIG_HAS_DATAFLASH -void at91_spi0_hw_init(unsigned long cs_mask) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_b_periph(AT91_PIO_PORTA, 0, 0); /* SPI0_MISO */ - at91_set_b_periph(AT91_PIO_PORTA, 1, 0); /* SPI0_MOSI */ - at91_set_b_periph(AT91_PIO_PORTA, 2, 0); /* SPI0_SPCK */ - - /* Enable clock */ - writel(1 << AT91SAM9263_ID_SPI0, &pmc->pcer); - - if (cs_mask & (1 << 0)) { - at91_set_b_periph(AT91_PIO_PORTA, 5, 1); - } - if (cs_mask & (1 << 1)) { - at91_set_b_periph(AT91_PIO_PORTA, 3, 1); - } - if (cs_mask & (1 << 2)) { - at91_set_b_periph(AT91_PIO_PORTA, 4, 1); - } - if (cs_mask & (1 << 3)) { - at91_set_b_periph(AT91_PIO_PORTB, 11, 1); - } - if (cs_mask & (1 << 4)) { - at91_set_pio_output(AT91_PIO_PORTA, 5, 1); - } - if (cs_mask & (1 << 5)) { - at91_set_pio_output(AT91_PIO_PORTA, 3, 1); - } - if (cs_mask & (1 << 6)) { - at91_set_pio_output(AT91_PIO_PORTA, 4, 1); - } - if (cs_mask & (1 << 7)) { - at91_set_pio_output(AT91_PIO_PORTB, 11, 1); - } -} - -void at91_spi1_hw_init(unsigned long cs_mask) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTB, 12, 0); /* SPI1_MISO */ - at91_set_a_periph(AT91_PIO_PORTB, 13, 0); /* SPI1_MOSI */ - at91_set_a_periph(AT91_PIO_PORTB, 14, 0); /* SPI1_SPCK */ - - /* Enable clock */ - writel(1 << AT91SAM9263_ID_SPI1, &pmc->pcer); - - if (cs_mask & (1 << 0)) { - at91_set_a_periph(AT91_PIO_PORTB, 15, 1); - } - if (cs_mask & (1 << 1)) { - at91_set_a_periph(AT91_PIO_PORTB, 16, 1); - } - if (cs_mask & (1 << 2)) { - at91_set_a_periph(AT91_PIO_PORTB, 17, 1); - } - if (cs_mask & (1 << 3)) { - at91_set_a_periph(AT91_PIO_PORTB, 18, 1); - } - if (cs_mask & (1 << 4)) { - at91_set_pio_output(AT91_PIO_PORTB, 15, 1); - } - if (cs_mask & (1 << 5)) { - at91_set_pio_output(AT91_PIO_PORTB, 16, 1); - } - if (cs_mask & (1 << 6)) { - at91_set_pio_output(AT91_PIO_PORTB, 17, 1); - } - if (cs_mask & (1 << 7)) { - at91_set_pio_output(AT91_PIO_PORTB, 18, 1); - } -} -#endif - -#ifdef CONFIG_MACB -void at91_macb_hw_init(void) -{ - at91_set_a_periph(AT91_PIO_PORTE, 21, 0); /* ETXCK_EREFCK */ - at91_set_b_periph(AT91_PIO_PORTC, 25, 0); /* ERXDV */ - at91_set_a_periph(AT91_PIO_PORTE, 25, 0); /* ERX0 */ - at91_set_a_periph(AT91_PIO_PORTE, 26, 0); /* ERX1 */ - at91_set_a_periph(AT91_PIO_PORTE, 27, 0); /* ERXER */ - at91_set_a_periph(AT91_PIO_PORTE, 28, 0); /* ETXEN */ - at91_set_a_periph(AT91_PIO_PORTE, 23, 0); /* ETX0 */ - at91_set_a_periph(AT91_PIO_PORTE, 24, 0); /* ETX1 */ - at91_set_a_periph(AT91_PIO_PORTE, 30, 0); /* EMDIO */ - at91_set_a_periph(AT91_PIO_PORTE, 29, 0); /* EMDC */ - -#ifndef CONFIG_RMII - at91_set_a_periph(AT91_PIO_PORTE, 22, 0); /* ECRS */ - at91_set_b_periph(AT91_PIO_PORTC, 26, 0); /* ECOL */ - at91_set_b_periph(AT91_PIO_PORTC, 22, 0); /* ERX2 */ - at91_set_b_periph(AT91_PIO_PORTC, 23, 0); /* ERX3 */ - at91_set_b_periph(AT91_PIO_PORTC, 27, 0); /* ERXCK */ - at91_set_b_periph(AT91_PIO_PORTC, 20, 0); /* ETX2 */ - at91_set_b_periph(AT91_PIO_PORTC, 21, 0); /* ETX3 */ - at91_set_b_periph(AT91_PIO_PORTC, 24, 0); /* ETXER */ -#endif -} -#endif - -#ifdef CONFIG_USB_OHCI_NEW -void at91_uhp_hw_init(void) -{ - /* Enable VBus on UHP ports */ - at91_set_pio_output(AT91_PIO_PORTA, 21, 0); - at91_set_pio_output(AT91_PIO_PORTA, 24, 0); -} -#endif - -#ifdef CONFIG_AT91_CAN -void at91_can_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTA, 13, 0); /* CAN_TX */ - at91_set_a_periph(AT91_PIO_PORTA, 14, 1); /* CAN_RX */ - - /* Enable clock */ - writel(1 << AT91SAM9263_ID_CAN, &pmc->pcer); -} -#endif diff --git a/cpu/arm926ejs/at91/at91sam9m10g45_devices.c b/cpu/arm926ejs/at91/at91sam9m10g45_devices.c deleted file mode 100644 index 4ad9b1fcc9..0000000000 --- a/cpu/arm926ejs/at91/at91sam9m10g45_devices.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * (C) Copyright 2007-2008 - * Stelian Pop - * Lead Tech Design - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include - -void at91_serial0_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTB, 19, 1); /* TXD0 */ - at91_set_a_periph(AT91_PIO_PORTB, 18, 0); /* RXD0 */ - writel(1 << AT91SAM9G45_ID_US0, &pmc->pcer); -} - -void at91_serial1_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTB, 4, 1); /* TXD1 */ - at91_set_a_periph(AT91_PIO_PORTB, 5, 0); /* RXD1 */ - writel(1 << AT91SAM9G45_ID_US1, &pmc->pcer); -} - -void at91_serial2_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTD, 6, 1); /* TXD2 */ - at91_set_a_periph(AT91_PIO_PORTD, 7, 0); /* RXD2 */ - writel(1 << AT91SAM9G45_ID_US2, &pmc->pcer); -} - -void at91_serial3_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTB, 12, 0); /* DRXD */ - at91_set_a_periph(AT91_PIO_PORTB, 13, 1); /* DTXD */ - writel(1 << AT91_ID_SYS, &pmc->pcer); -} - -void at91_serial_hw_init(void) -{ -#ifdef CONFIG_USART0 - at91_serial0_hw_init(); -#endif - -#ifdef CONFIG_USART1 - at91_serial1_hw_init(); -#endif - -#ifdef CONFIG_USART2 - at91_serial2_hw_init(); -#endif - -#ifdef CONFIG_USART3 /* DBGU */ - at91_serial3_hw_init(); -#endif -} - -#ifdef CONFIG_ATMEL_SPI -void at91_spi0_hw_init(unsigned long cs_mask) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTB, 0, 0); /* SPI0_MISO */ - at91_set_a_periph(AT91_PIO_PORTB, 1, 0); /* SPI0_MOSI */ - at91_set_a_periph(AT91_PIO_PORTB, 2, 0); /* SPI0_SPCK */ - - /* Enable clock */ - writel(1 << AT91SAM9G45_ID_SPI0, &pmc->pcer); - - if (cs_mask & (1 << 0)) { - at91_set_a_periph(AT91_PIO_PORTB, 3, 0); - } - if (cs_mask & (1 << 1)) { - at91_set_b_periph(AT91_PIO_PORTB, 18, 0); - } - if (cs_mask & (1 << 2)) { - at91_set_b_periph(AT91_PIO_PORTB, 19, 0); - } - if (cs_mask & (1 << 3)) { - at91_set_b_periph(AT91_PIO_PORTD, 27, 0); - } - if (cs_mask & (1 << 4)) { - at91_set_pio_output(AT91_PIO_PORTB, 3, 0); - } - if (cs_mask & (1 << 5)) { - at91_set_pio_output(AT91_PIO_PORTB, 18, 0); - } - if (cs_mask & (1 << 6)) { - at91_set_pio_output(AT91_PIO_PORTB, 19, 0); - } - if (cs_mask & (1 << 7)) { - at91_set_pio_output(AT91_PIO_PORTD, 27, 0); - } -} - -void at91_spi1_hw_init(unsigned long cs_mask) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTB, 14, 0); /* SPI1_MISO */ - at91_set_a_periph(AT91_PIO_PORTB, 15, 0); /* SPI1_MOSI */ - at91_set_a_periph(AT91_PIO_PORTB, 16, 0); /* SPI1_SPCK */ - - /* Enable clock */ - writel(1 << AT91SAM9G45_ID_SPI1, &pmc->pcer); - - if (cs_mask & (1 << 0)) { - at91_set_a_periph(AT91_PIO_PORTB, 17, 0); - } - if (cs_mask & (1 << 1)) { - at91_set_b_periph(AT91_PIO_PORTD, 28, 0); - } - if (cs_mask & (1 << 2)) { - at91_set_a_periph(AT91_PIO_PORTD, 18, 0); - } - if (cs_mask & (1 << 3)) { - at91_set_a_periph(AT91_PIO_PORTD, 19, 0); - } - if (cs_mask & (1 << 4)) { - at91_set_pio_output(AT91_PIO_PORTB, 17, 0); - } - if (cs_mask & (1 << 5)) { - at91_set_pio_output(AT91_PIO_PORTD, 28, 0); - } - if (cs_mask & (1 << 6)) { - at91_set_pio_output(AT91_PIO_PORTD, 18, 0); - } - if (cs_mask & (1 << 7)) { - at91_set_pio_output(AT91_PIO_PORTD, 19, 0); - } - -} -#endif - -#ifdef CONFIG_MACB -void at91_macb_hw_init(void) -{ - at91_set_a_periph(AT91_PIO_PORTA, 17, 0); /* ETXCK_EREFCK */ - at91_set_a_periph(AT91_PIO_PORTA, 15, 0); /* ERXDV */ - at91_set_a_periph(AT91_PIO_PORTA, 12, 0); /* ERX0 */ - at91_set_a_periph(AT91_PIO_PORTA, 13, 0); /* ERX1 */ - at91_set_a_periph(AT91_PIO_PORTA, 16, 0); /* ERXER */ - at91_set_a_periph(AT91_PIO_PORTA, 14, 0); /* ETXEN */ - at91_set_a_periph(AT91_PIO_PORTA, 10, 0); /* ETX0 */ - at91_set_a_periph(AT91_PIO_PORTA, 11, 0); /* ETX1 */ - at91_set_a_periph(AT91_PIO_PORTA, 19, 0); /* EMDIO */ - at91_set_a_periph(AT91_PIO_PORTA, 18, 0); /* EMDC */ -#ifndef CONFIG_RMII - at91_set_b_periph(AT91_PIO_PORTA, 29, 0); /* ECRS */ - at91_set_b_periph(AT91_PIO_PORTA, 30, 0); /* ECOL */ - at91_set_b_periph(AT91_PIO_PORTA, 8, 0); /* ERX2 */ - at91_set_b_periph(AT91_PIO_PORTA, 9, 0); /* ERX3 */ - at91_set_b_periph(AT91_PIO_PORTA, 28, 0); /* ERXCK */ - at91_set_b_periph(AT91_PIO_PORTA, 6, 0); /* ETX2 */ - at91_set_b_periph(AT91_PIO_PORTA, 7, 0); /* ETX3 */ - at91_set_b_periph(AT91_PIO_PORTA, 27, 0); /* ETXER */ -#endif -} -#endif diff --git a/cpu/arm926ejs/at91/at91sam9rl_devices.c b/cpu/arm926ejs/at91/at91sam9rl_devices.c deleted file mode 100644 index 4f570f4fb5..0000000000 --- a/cpu/arm926ejs/at91/at91sam9rl_devices.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * (C) Copyright 2007-2008 - * Stelian Pop - * Lead Tech Design - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include - -void at91_serial0_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTA, 6, 1); /* TXD0 */ - at91_set_a_periph(AT91_PIO_PORTA, 7, 0); /* RXD0 */ - writel(1 << AT91SAM9RL_ID_US0, &pmc->pcer); -} - -void at91_serial1_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTA, 11, 1); /* TXD1 */ - at91_set_a_periph(AT91_PIO_PORTA, 12, 0); /* RXD1 */ - writel(1 << AT91SAM9RL_ID_US1, &pmc->pcer); -} - -void at91_serial2_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTA, 13, 1); /* TXD2 */ - at91_set_a_periph(AT91_PIO_PORTA, 14, 0); /* RXD2 */ - writel(1 << AT91SAM9RL_ID_US2, &pmc->pcer); -} - -void at91_serial3_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTA, 21, 0); /* DRXD */ - at91_set_a_periph(AT91_PIO_PORTA, 22, 1); /* DTXD */ - writel(1 << AT91_ID_SYS, &pmc->pcer); -} - -void at91_serial_hw_init(void) -{ -#ifdef CONFIG_USART0 - at91_serial0_hw_init(); -#endif - -#ifdef CONFIG_USART1 - at91_serial1_hw_init(); -#endif - -#ifdef CONFIG_USART2 - at91_serial2_hw_init(); -#endif - -#ifdef CONFIG_USART3 /* DBGU */ - at91_serial3_hw_init(); -#endif -} - -#ifdef CONFIG_HAS_DATAFLASH -void at91_spi0_hw_init(unsigned long cs_mask) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTA, 25, 0); /* SPI0_MISO */ - at91_set_a_periph(AT91_PIO_PORTA, 26, 0); /* SPI0_MOSI */ - at91_set_a_periph(AT91_PIO_PORTA, 27, 0); /* SPI0_SPCK */ - - /* Enable clock */ - writel(1 << AT91SAM9RL_ID_SPI, &pmc->pcer); - - if (cs_mask & (1 << 0)) { - at91_set_a_periph(AT91_PIO_PORTA, 28, 1); - } - if (cs_mask & (1 << 1)) { - at91_set_b_periph(AT91_PIO_PORTB, 7, 1); - } - if (cs_mask & (1 << 2)) { - at91_set_a_periph(AT91_PIO_PORTD, 8, 1); - } - if (cs_mask & (1 << 3)) { - at91_set_b_periph(AT91_PIO_PORTD, 9, 1); - } - if (cs_mask & (1 << 4)) { - at91_set_pio_output(AT91_PIO_PORTA, 28, 1); - } - if (cs_mask & (1 << 5)) { - at91_set_pio_output(AT91_PIO_PORTB, 7, 1); - } - if (cs_mask & (1 << 6)) { - at91_set_pio_output(AT91_PIO_PORTD, 8, 1); - } - if (cs_mask & (1 << 7)) { - at91_set_pio_output(AT91_PIO_PORTD, 9, 1); - } -} -#endif diff --git a/cpu/arm926ejs/at91/clock.c b/cpu/arm926ejs/at91/clock.c deleted file mode 100644 index ecf91f5187..0000000000 --- a/cpu/arm926ejs/at91/clock.c +++ /dev/null @@ -1,216 +0,0 @@ -/* - * [origin: Linux kernel linux/arch/arm/mach-at91/clock.c] - * - * Copyright (C) 2005 David Brownell - * Copyright (C) 2005 Ivan Kokshaysky - * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include -#include -#include -#include -#include - -static unsigned long cpu_clk_rate_hz; -static unsigned long main_clk_rate_hz; -static unsigned long mck_rate_hz; -static unsigned long plla_rate_hz; -static unsigned long pllb_rate_hz; -static u32 at91_pllb_usb_init; - -unsigned long get_cpu_clk_rate(void) -{ - return cpu_clk_rate_hz; -} - -unsigned long get_main_clk_rate(void) -{ - return main_clk_rate_hz; -} - -unsigned long get_mck_clk_rate(void) -{ - return mck_rate_hz; -} - -unsigned long get_plla_clk_rate(void) -{ - return plla_rate_hz; -} - -unsigned long get_pllb_clk_rate(void) -{ - return pllb_rate_hz; -} - -u32 get_pllb_init(void) -{ - return at91_pllb_usb_init; -} - -static unsigned long at91_css_to_rate(unsigned long css) -{ - switch (css) { - case AT91_PMC_MCKR_CSS_SLOW: - return AT91_SLOW_CLOCK; - case AT91_PMC_MCKR_CSS_MAIN: - return main_clk_rate_hz; - case AT91_PMC_MCKR_CSS_PLLA: - return plla_rate_hz; - case AT91_PMC_MCKR_CSS_PLLB: - return pllb_rate_hz; - } - - return 0; -} - -#ifdef CONFIG_USB_ATMEL -static unsigned at91_pll_calc(unsigned main_freq, unsigned out_freq) -{ - unsigned i, div = 0, mul = 0, diff = 1 << 30; - unsigned ret = (out_freq > 155000000) ? 0xbe00 : 0x3e00; - - /* PLL output max 240 MHz (or 180 MHz per errata) */ - if (out_freq > 240000000) - goto fail; - - for (i = 1; i < 256; i++) { - int diff1; - unsigned input, mul1; - - /* - * PLL input between 1MHz and 32MHz per spec, but lower - * frequences seem necessary in some cases so allow 100K. - * Warning: some newer products need 2MHz min. - */ - input = main_freq / i; -#if defined(CONFIG_AT91SAM9G20) - if (input < 2000000) - continue; -#endif - if (input < 100000) - continue; - if (input > 32000000) - continue; - - mul1 = out_freq / input; -#if defined(CONFIG_AT91SAM9G20) - if (mul > 63) - continue; -#endif - if (mul1 > 2048) - continue; - if (mul1 < 2) - goto fail; - - diff1 = out_freq - input * mul1; - if (diff1 < 0) - diff1 = -diff1; - if (diff > diff1) { - diff = diff1; - div = i; - mul = mul1; - if (diff == 0) - break; - } - } - if (i == 256 && diff > (out_freq >> 5)) - goto fail; - return ret | ((mul - 1) << 16) | div; -fail: - return 0; -} -#endif - -static u32 at91_pll_rate(u32 freq, u32 reg) -{ - unsigned mul, div; - - div = reg & 0xff; - mul = (reg >> 16) & 0x7ff; - if (div && mul) { - freq /= div; - freq *= mul + 1; - } else - freq = 0; - - return freq; -} - -int at91_clock_init(unsigned long main_clock) -{ - unsigned freq, mckr; - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; -#ifndef CONFIG_SYS_AT91_MAIN_CLOCK - unsigned tmp; - /* - * When the bootloader initialized the main oscillator correctly, - * there's no problem using the cycle counter. But if it didn't, - * or when using oscillator bypass mode, we must be told the speed - * of the main clock. - */ - if (!main_clock) { - do { - tmp = readl(&pmc->mcfr); - } while (!(tmp & AT91_PMC_MCFR_MAINRDY)); - tmp &= AT91_PMC_MCFR_MAINF_MASK; - main_clock = tmp * (AT91_SLOW_CLOCK / 16); - } -#endif - main_clk_rate_hz = main_clock; - - /* report if PLLA is more than mildly overclocked */ - plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar)); - -#ifdef CONFIG_USB_ATMEL - /* - * USB clock init: choose 48 MHz PLLB value, - * disable 48MHz clock during usb peripheral suspend. - * - * REVISIT: assumes MCK doesn't derive from PLLB! - */ - at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | - AT91_PMC_PLLBR_USBDIV_2; - pllb_rate_hz = at91_pll_rate(main_clock, at91_pllb_usb_init); -#endif - - /* - * MCK and CPU derive from one of those primary clocks. - * For now, assume this parentage won't change. - */ - mckr = readl(&pmc->mckr); -#if defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) - /* plla divisor by 2 */ - plla_rate_hz /= (1 << ((mckr & 1 << 12) >> 12)); -#endif - mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK); - freq = mck_rate_hz; - - freq /= (1 << ((mckr & AT91_PMC_MCKR_PRES_MASK) >> 2)); /* prescale */ -#if defined(CONFIG_AT91RM9200) - /* mdiv */ - mck_rate_hz = freq / (1 + ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8)); -#elif defined(CONFIG_AT91SAM9G20) - /* mdiv ; (x >> 7) = ((x >> 8) * 2) */ - mck_rate_hz = (mckr & AT91_PMC_MCKR_MDIV_MASK) ? - freq / ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 7) : freq; - if (mckr & AT91_PMC_MCKR_MDIV_MASK) - freq /= 2; /* processor clock division */ -#elif defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) - mck_rate_hz = (mckr & AT91_PMC_MCKR_MDIV_MASK) == - (AT91_PMC_MCKR_MDIV_2 | AT91_PMC_MCKR_MDIV_4) - ? freq / 3 - : freq / (1 << ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8)); -#else - mck_rate_hz = freq / (1 << ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8)); -#endif - cpu_clk_rate_hz = freq; - - return 0; -} diff --git a/cpu/arm926ejs/at91/config.mk b/cpu/arm926ejs/at91/config.mk deleted file mode 100644 index 19296fdba2..0000000000 --- a/cpu/arm926ejs/at91/config.mk +++ /dev/null @@ -1 +0,0 @@ -PLATFORM_CPPFLAGS += $(call cc-option,-mtune=arm926ejs,) diff --git a/cpu/arm926ejs/at91/cpu.c b/cpu/arm926ejs/at91/cpu.c deleted file mode 100644 index 141a7d1ec6..0000000000 --- a/cpu/arm926ejs/at91/cpu.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * (C) Copyright 2009 - * Jean-Christophe PLAGNIOL-VILLARD - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#ifdef CONFIG_AT91_LEGACY -#warning Your board is using legacy SoC access. Please update! -#endif - -#include -#include -#include -#include - -#ifndef CONFIG_SYS_AT91_MAIN_CLOCK -#define CONFIG_SYS_AT91_MAIN_CLOCK 0 -#endif - -/* - * The at91sam9260 has 4 GPBR (0-3), we'll use the last one, nr 3, - * to keep track of the bootcount. - */ -#define AT91_GPBR_BOOTCOUNT_REGISTER 3 -#define AT91_BOOTCOUNT_ADDRESS (AT91_GPBR + 4*AT91_GPBR_BOOTCOUNT_REGISTER) - -int arch_cpu_init(void) -{ - return at91_clock_init(CONFIG_SYS_AT91_MAIN_CLOCK); -} - -#if defined(CONFIG_DISPLAY_CPUINFO) -int print_cpuinfo(void) -{ - char buf[32]; - - printf("CPU: %s\n", CONFIG_SYS_AT91_CPU_NAME); - printf("Crystal frequency: %8s MHz\n", - strmhz(buf, get_main_clk_rate())); - printf("CPU clock : %8s MHz\n", - strmhz(buf, get_cpu_clk_rate())); - printf("Master clock : %8s MHz\n", - strmhz(buf, get_mck_clk_rate())); - - return 0; -} -#endif - -#ifdef CONFIG_BOOTCOUNT_LIMIT -/* - * Just as the mpc5xxx, we combine the BOOTCOUNT_MAGIC and boocount - * in one 32-bit register. This is done, as the AT91SAM9260 only has - * 4 GPBR. - */ -void bootcount_store (ulong a) -{ - volatile ulong *save_addr = - (volatile ulong *)(AT91_BASE_SYS + AT91_BOOTCOUNT_ADDRESS); - - *save_addr = (BOOTCOUNT_MAGIC & 0xffff0000) | (a & 0x0000ffff); -} - -ulong bootcount_load (void) -{ - volatile ulong *save_addr = - (volatile ulong *)(AT91_BASE_SYS + AT91_BOOTCOUNT_ADDRESS); - - if ((*save_addr & 0xffff0000) != (BOOTCOUNT_MAGIC & 0xffff0000)) - return 0; - else - return (*save_addr & 0x0000ffff); -} - -#endif /* CONFIG_BOOTCOUNT_LIMIT */ diff --git a/cpu/arm926ejs/at91/led.c b/cpu/arm926ejs/at91/led.c deleted file mode 100644 index 0a315c4971..0000000000 --- a/cpu/arm926ejs/at91/led.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * (C) Copyright 2007-2008 - * Stelian Pop - * Lead Tech Design - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include - -#ifdef CONFIG_RED_LED -void red_LED_on(void) -{ - at91_set_gpio_value(CONFIG_RED_LED, 1); -} - -void red_LED_off(void) -{ - at91_set_gpio_value(CONFIG_RED_LED, 0); -} -#endif - -#ifdef CONFIG_GREEN_LED -void green_LED_on(void) -{ - at91_set_gpio_value(CONFIG_GREEN_LED, 0); -} - -void green_LED_off(void) -{ - at91_set_gpio_value(CONFIG_GREEN_LED, 1); -} -#endif - -#ifdef CONFIG_YELLOW_LED -void yellow_LED_on(void) -{ - at91_set_gpio_value(CONFIG_YELLOW_LED, 0); -} - -void yellow_LED_off(void) -{ - at91_set_gpio_value(CONFIG_YELLOW_LED, 1); -} -#endif diff --git a/cpu/arm926ejs/at91/lowlevel_init.S b/cpu/arm926ejs/at91/lowlevel_init.S deleted file mode 100644 index 559c35c9ee..0000000000 --- a/cpu/arm926ejs/at91/lowlevel_init.S +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Memory Setup stuff - taken from blob memsetup.S - * - * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and - * Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl) - * - * Copyright (C) 2008 Ronetix Ilko Iliev (www.ronetix.at) - * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_AT91_LEGACY -#include -#endif -#ifndef CONFIG_SYS_MATRIX_EBICSA_VAL -#define CONFIG_SYS_MATRIX_EBICSA_VAL CONFIG_SYS_MATRIX_EBI0CSA_VAL -#endif - -_TEXT_BASE: - .word TEXT_BASE - -.globl lowlevel_init -.type lowlevel_init,function -lowlevel_init: - - mov r5, pc /* r5 = POS1 + 4 current */ -POS1: - ldr r0, =POS1 /* r0 = POS1 compile */ - ldr r2, _TEXT_BASE - sub r0, r0, r2 /* r0 = POS1-_TEXT_BASE (POS1 relative) */ - sub r5, r5, r0 /* r0 = TEXT_BASE-1 */ - sub r5, r5, #4 /* r1 = text base - current */ - - /* memory control configuration 1 */ - ldr r0, =SMRDATA - ldr r2, =SMRDATA1 - ldr r1, _TEXT_BASE - sub r0, r0, r1 - sub r2, r2, r1 - add r0, r0, r5 - add r2, r2, r5 -0: - /* the address */ - ldr r1, [r0], #4 - /* the value */ - ldr r3, [r0], #4 - str r3, [r1] - cmp r2, r0 - bne 0b - -/* ---------------------------------------------------------------------------- - * PMC Init Step 1. - * ---------------------------------------------------------------------------- - * - Check if the PLL is already initialized - * ---------------------------------------------------------------------------- - */ - ldr r1, =(AT91_ASM_PMC_MCKR) - ldr r0, [r1] - and r0, r0, #3 - cmp r0, #0 - bne PLL_setup_end - -/* --------------------------------------------------------------------------- - * - Enable the Main Oscillator - * --------------------------------------------------------------------------- - */ - ldr r1, =(AT91_ASM_PMC_MOR) - ldr r2, =(AT91_ASM_PMC_SR) - /* Main oscillator Enable register PMC_MOR: */ - ldr r0, =CONFIG_SYS_MOR_VAL - str r0, [r1] - - /* Reading the PMC Status to detect when the Main Oscillator is enabled */ - mov r4, #AT91_PMC_IXR_MOSCS -MOSCS_Loop: - ldr r3, [r2] - and r3, r4, r3 - cmp r3, #AT91_PMC_IXR_MOSCS - bne MOSCS_Loop - -/* ---------------------------------------------------------------------------- - * PMC Init Step 2. - * ---------------------------------------------------------------------------- - * Setup PLLA - * ---------------------------------------------------------------------------- - */ - ldr r1, =(AT91_ASM_PMC_PLLAR) - ldr r0, =CONFIG_SYS_PLLAR_VAL - str r0, [r1] - - /* Reading the PMC Status register to detect when the PLLA is locked */ - mov r4, #AT91_PMC_IXR_LOCKA -MOSCS_Loop1: - ldr r3, [r2] - and r3, r4, r3 - cmp r3, #AT91_PMC_IXR_LOCKA - bne MOSCS_Loop1 - -/* ---------------------------------------------------------------------------- - * PMC Init Step 3. - * ---------------------------------------------------------------------------- - * - Switch on the Main Oscillator - * ---------------------------------------------------------------------------- - */ - ldr r1, =(AT91_ASM_PMC_MCKR) - - /* -Master Clock Controller register PMC_MCKR */ - ldr r0, =CONFIG_SYS_MCKR1_VAL - str r0, [r1] - - /* Reading the PMC Status to detect when the Master clock is ready */ - mov r4, #AT91_PMC_IXR_MCKRDY -MCKRDY_Loop: - ldr r3, [r2] - and r3, r4, r3 - cmp r3, #AT91_PMC_IXR_MCKRDY - bne MCKRDY_Loop - - ldr r0, =CONFIG_SYS_MCKR2_VAL - str r0, [r1] - - /* Reading the PMC Status to detect when the Master clock is ready */ - mov r4, #AT91_PMC_IXR_MCKRDY -MCKRDY_Loop1: - ldr r3, [r2] - and r3, r4, r3 - cmp r3, #AT91_PMC_IXR_MCKRDY - bne MCKRDY_Loop1 -PLL_setup_end: - -/* ---------------------------------------------------------------------------- - * - memory control configuration 2 - * ---------------------------------------------------------------------------- - */ - ldr r0, =(AT91_ASM_SDRAMC_TR) - ldr r1, [r0] - cmp r1, #0 - bne SDRAM_setup_end - - ldr r0, =SMRDATA1 - ldr r2, =SMRDATA2 - ldr r1, _TEXT_BASE - sub r0, r0, r1 - sub r2, r2, r1 - add r0, r0, r5 - add r2, r2, r5 -2: - /* the address */ - ldr r1, [r0], #4 - /* the value */ - ldr r3, [r0], #4 - str r3, [r1] - cmp r2, r0 - bne 2b - -SDRAM_setup_end: - /* everything is fine now */ - mov pc, lr - - .ltorg - -SMRDATA: - .word AT91_ASM_WDT_MR - .word CONFIG_SYS_WDTC_WDMR_VAL - /* configure PIOx as EBI0 D[16-31] */ -#if defined(CONFIG_AT91SAM9263) - .word AT91_ASM_PIOD_PDR - .word CONFIG_SYS_PIOD_PDR_VAL1 - .word AT91_ASM_PIOD_PUDR - .word CONFIG_SYS_PIOD_PPUDR_VAL - .word AT91_ASM_PIOD_ASR - .word CONFIG_SYS_PIOD_PPUDR_VAL -#elif defined(CONFIG_AT91SAM9260) || defined(CONFIG_AT91SAM9261) \ - || defined(CONFIG_AT91SAM9G20) - .word AT91_ASM_PIOC_PDR - .word CONFIG_SYS_PIOC_PDR_VAL1 - .word AT91_ASM_PIOC_PUDR - .word CONFIG_SYS_PIOC_PPUDR_VAL -#endif - .word AT91_ASM_MATRIX_CSA0 - .word CONFIG_SYS_MATRIX_EBICSA_VAL - - /* flash */ - .word AT91_ASM_SMC_MODE0 - .word CONFIG_SYS_SMC0_MODE0_VAL - - .word AT91_ASM_SMC_CYCLE0 - .word CONFIG_SYS_SMC0_CYCLE0_VAL - - .word AT91_ASM_SMC_PULSE0 - .word CONFIG_SYS_SMC0_PULSE0_VAL - - .word AT91_ASM_SMC_SETUP0 - .word CONFIG_SYS_SMC0_SETUP0_VAL - -SMRDATA1: - .word AT91_ASM_SDRAMC_MR - .word CONFIG_SYS_SDRC_MR_VAL1 - .word AT91_ASM_SDRAMC_TR - .word CONFIG_SYS_SDRC_TR_VAL1 - .word AT91_ASM_SDRAMC_CR - .word CONFIG_SYS_SDRC_CR_VAL - .word AT91_ASM_SDRAMC_MDR - .word CONFIG_SYS_SDRC_MDR_VAL - .word AT91_ASM_SDRAMC_MR - .word CONFIG_SYS_SDRC_MR_VAL2 - .word AT91_SDRAM_BASE - .word CONFIG_SYS_SDRAM_VAL1 - .word AT91_ASM_SDRAMC_MR - .word CONFIG_SYS_SDRC_MR_VAL3 - .word AT91_SDRAM_BASE - .word CONFIG_SYS_SDRAM_VAL2 - .word AT91_SDRAM_BASE - .word CONFIG_SYS_SDRAM_VAL3 - .word AT91_SDRAM_BASE - .word CONFIG_SYS_SDRAM_VAL4 - .word AT91_SDRAM_BASE - .word CONFIG_SYS_SDRAM_VAL5 - .word AT91_SDRAM_BASE - .word CONFIG_SYS_SDRAM_VAL6 - .word AT91_SDRAM_BASE - .word CONFIG_SYS_SDRAM_VAL7 - .word AT91_SDRAM_BASE - .word CONFIG_SYS_SDRAM_VAL8 - .word AT91_SDRAM_BASE - .word CONFIG_SYS_SDRAM_VAL9 - .word AT91_ASM_SDRAMC_MR - .word CONFIG_SYS_SDRC_MR_VAL4 - .word AT91_SDRAM_BASE - .word CONFIG_SYS_SDRAM_VAL10 - .word AT91_ASM_SDRAMC_MR - .word CONFIG_SYS_SDRC_MR_VAL5 - .word AT91_SDRAM_BASE - .word CONFIG_SYS_SDRAM_VAL11 - .word AT91_ASM_SDRAMC_TR - .word CONFIG_SYS_SDRC_TR_VAL2 - .word AT91_SDRAM_BASE - .word CONFIG_SYS_SDRAM_VAL12 - /* User reset enable*/ - .word AT91_ASM_RSTC_MR - .word CONFIG_SYS_RSTC_RMR_VAL -#ifdef CONFIG_SYS_MATRIX_MCFG_REMAP - /* MATRIX_MCFG - REMAP all masters */ - .word AT91_ASM_MATRIX_MCFG - .word 0x1FF -#endif -SMRDATA2: - .word 0 diff --git a/cpu/arm926ejs/at91/reset.c b/cpu/arm926ejs/at91/reset.c deleted file mode 100644 index 1b67e77887..0000000000 --- a/cpu/arm926ejs/at91/reset.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * (C) Copyright 2007-2008 - * Stelian Pop - * Lead Tech Design - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include - -/* - * Reset the cpu by setting up the watchdog timer and let him time out. - */ -void reset_cpu(ulong ignored) -{ - at91_rstc_t *rstc = (at91_rstc_t *) AT91_RSTC_BASE; - - /* this is the way Linux does it */ - - writel(AT91_RSTC_KEY | AT91_RSTC_CR_PROCRST | AT91_RSTC_CR_PERRST, - &rstc->cr); - - while (1); - /* Never reached */ -} diff --git a/cpu/arm926ejs/at91/timer.c b/cpu/arm926ejs/at91/timer.c deleted file mode 100644 index d21eebfb4e..0000000000 --- a/cpu/arm926ejs/at91/timer.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * (C) Copyright 2007-2008 - * Stelian Pop - * Lead Tech Design - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include - -/* - * We're using the AT91CAP9/SAM9 PITC in 32 bit mode, by - * setting the 20 bit counter period to its maximum (0xfffff). - */ -#define TIMER_LOAD_VAL 0xfffff - -static ulong timestamp; -static ulong lastinc; -static ulong timer_freq; - -static inline unsigned long long tick_to_time(unsigned long long tick) -{ - tick *= CONFIG_SYS_HZ; - do_div(tick, timer_freq); - - return tick; -} - -static inline unsigned long long usec_to_tick(unsigned long long usec) -{ - usec *= timer_freq; - do_div(usec, 1000000); - - return usec; -} - -/* nothing really to do with interrupts, just starts up a counter. */ -int timer_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - at91_pit_t *pit = (at91_pit_t *) AT91_PIT_BASE; - /* - * Enable PITC Clock - * The clock is already enabled for system controller in boot - */ - writel(1 << AT91_ID_SYS, &pmc->pcer); - - /* Enable PITC */ - writel(TIMER_LOAD_VAL | AT91_PIT_MR_EN , &pit->mr); - - reset_timer_masked(); - - timer_freq = get_mck_clk_rate() >> 4; - - return 0; -} - -/* - * timer without interrupts - */ -unsigned long long get_ticks(void) -{ - at91_pit_t *pit = (at91_pit_t *) AT91_PIT_BASE; - - ulong now = readl(&pit->piir); - - if (now >= lastinc) /* normal mode (non roll) */ - /* move stamp forward with absolut diff ticks */ - timestamp += (now - lastinc); - else /* we have rollover of incrementer */ - timestamp += (0xFFFFFFFF - lastinc) + now; - lastinc = now; - return timestamp; -} - -void reset_timer_masked(void) -{ - /* reset time */ - at91_pit_t *pit = (at91_pit_t *) AT91_PIT_BASE; - - /* capture current incrementer value time */ - lastinc = readl(&pit->piir); - timestamp = 0; /* start "advancing" time stamp from 0 */ -} - -ulong get_timer_masked(void) -{ - return tick_to_time(get_ticks()); -} - -void __udelay(unsigned long usec) -{ - unsigned long long tmp; - ulong tmo; - - tmo = usec_to_tick(usec); - tmp = get_ticks() + tmo; /* get current timestamp */ - - while (get_ticks() < tmp) /* loop till event */ - /*NOP*/; -} - -void reset_timer(void) -{ - reset_timer_masked(); -} - -ulong get_timer(ulong base) -{ - return get_timer_masked () - base; -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk(void) -{ - ulong tbclk; - - tbclk = CONFIG_SYS_HZ; - return tbclk; -} diff --git a/cpu/arm926ejs/config.mk b/cpu/arm926ejs/config.mk deleted file mode 100644 index f8ef90f2d5..0000000000 --- a/cpu/arm926ejs/config.mk +++ /dev/null @@ -1,32 +0,0 @@ -# -# (C) Copyright 2002 -# Gary Jennejohn, DENX Software Engineering, -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float - -PLATFORM_CPPFLAGS += -march=armv5te -# ========================================================================= -# -# Supply options according to compiler version -# -# ========================================================================= -PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/arm926ejs/cpu.c b/cpu/arm926ejs/cpu.c deleted file mode 100644 index 5c902dfc13..0000000000 --- a/cpu/arm926ejs/cpu.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * CPU specific code - */ - -#include -#include -#include - -static void cache_flush(void); - -int cleanup_before_linux (void) -{ - /* - * this function is called just before we call linux - * it prepares the processor for linux - * - * we turn off caches etc ... - */ - - disable_interrupts (); - - - /* turn off I/D-cache */ - icache_disable(); - dcache_disable(); - /* flush I/D-cache */ - cache_flush(); - - return 0; -} - -/* flush I/D-cache */ -static void cache_flush (void) -{ - unsigned long i = 0; - - asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); -} diff --git a/cpu/arm926ejs/davinci/Makefile b/cpu/arm926ejs/davinci/Makefile deleted file mode 100644 index d7e9e2ca04..0000000000 --- a/cpu/arm926ejs/davinci/Makefile +++ /dev/null @@ -1,59 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# Copyright (C) 2007 Sergey Kubushyn -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(SOC).a - -COBJS-y += cpu.o timer.o psc.o -COBJS-$(CONFIG_SOC_DM355) += dm355.o -COBJS-$(CONFIG_SOC_DM365) += dm365.o -COBJS-$(CONFIG_SOC_DM644X) += dm644x.o -COBJS-$(CONFIG_SOC_DM646X) += dm646x.o -COBJS-$(CONFIG_DRIVER_TI_EMAC) += lxt972.o dp83848.o - -SOBJS = reset.o - -ifndef CONFIG_SKIP_LOWLEVEL_INIT -SOBJS += lowlevel_init.o -endif - -SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS-y:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS-y) $(SOBJS)) -START := $(addprefix $(obj),$(START)) - -all: $(obj).depend $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/arm926ejs/davinci/config.mk b/cpu/arm926ejs/davinci/config.mk deleted file mode 100644 index 565adda11d..0000000000 --- a/cpu/arm926ejs/davinci/config.mk +++ /dev/null @@ -1,32 +0,0 @@ -# -# (C) Copyright 2002 -# Gary Jennejohn, DENX Software Engineering, -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float - -PLATFORM_CPPFLAGS += -march=armv5te -# ========================================================================= -# -# Supply options according to compiler version -# -# ========================================================================= -PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/arm926ejs/davinci/cpu.c b/cpu/arm926ejs/davinci/cpu.c deleted file mode 100644 index fc3551c302..0000000000 --- a/cpu/arm926ejs/davinci/cpu.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (C) 2004 Texas Instruments. - * Copyright (C) 2009 David Brownell - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include - -/* offsets from PLL controller base */ -#define PLLC_PLLCTL 0x100 -#define PLLC_PLLM 0x110 -#define PLLC_PREDIV 0x114 -#define PLLC_PLLDIV1 0x118 -#define PLLC_PLLDIV2 0x11c -#define PLLC_PLLDIV3 0x120 -#define PLLC_POSTDIV 0x128 -#define PLLC_BPDIV 0x12c -#define PLLC_PLLDIV4 0x160 -#define PLLC_PLLDIV5 0x164 -#define PLLC_PLLDIV6 0x168 -#define PLLC_PLLDIV8 0x170 -#define PLLC_PLLDIV9 0x174 - -#define BIT(x) (1 << (x)) - -/* SOC-specific pll info */ -#ifdef CONFIG_SOC_DM355 -#define ARM_PLLDIV PLLC_PLLDIV1 -#define DDR_PLLDIV PLLC_PLLDIV1 -#endif - -#ifdef CONFIG_SOC_DM644X -#define ARM_PLLDIV PLLC_PLLDIV2 -#define DSP_PLLDIV PLLC_PLLDIV1 -#define DDR_PLLDIV PLLC_PLLDIV2 -#endif - -#ifdef CONFIG_SOC_DM6447 -#define ARM_PLLDIV PLLC_PLLDIV2 -#define DSP_PLLDIV PLLC_PLLDIV1 -#define DDR_PLLDIV PLLC_PLLDIV1 -#endif - -#ifdef CONFIG_SOC_DA8XX -const dv_reg * const sysdiv[7] = { - &davinci_pllc_regs->plldiv1, &davinci_pllc_regs->plldiv2, - &davinci_pllc_regs->plldiv3, &davinci_pllc_regs->plldiv4, - &davinci_pllc_regs->plldiv5, &davinci_pllc_regs->plldiv6, - &davinci_pllc_regs->plldiv7 -}; - -int clk_get(enum davinci_clk_ids id) -{ - int pre_div; - int pllm; - int post_div; - int pll_out; - - pll_out = CONFIG_SYS_OSCIN_FREQ; - - if (id == DAVINCI_AUXCLK_CLKID) - goto out; - - /* - * Lets keep this simple. Combining operations can result in - * unexpected approximations - */ - pre_div = (readl(&davinci_pllc_regs->prediv) & - DAVINCI_PLLC_DIV_MASK) + 1; - pllm = readl(&davinci_pllc_regs->pllm) + 1; - - pll_out /= pre_div; - pll_out *= pllm; - - if (id == DAVINCI_PLLM_CLKID) - goto out; - - post_div = (readl(&davinci_pllc_regs->postdiv) & - DAVINCI_PLLC_DIV_MASK) + 1; - - pll_out /= post_div; - - if (id == DAVINCI_PLLC_CLKID) - goto out; - - pll_out /= (readl(sysdiv[id - 1]) & DAVINCI_PLLC_DIV_MASK) + 1; - -out: - return pll_out; -} -#endif /* CONFIG_SOC_DA8XX */ - -#ifdef CONFIG_DISPLAY_CPUINFO - -static unsigned pll_div(volatile void *pllbase, unsigned offset) -{ - u32 div; - - div = REG(pllbase + offset); - return (div & BIT(15)) ? (1 + (div & 0x1f)) : 1; -} - -static inline unsigned pll_prediv(volatile void *pllbase) -{ -#ifdef CONFIG_SOC_DM355 - /* this register read seems to fail on pll0 */ - if (pllbase == (volatile void *)DAVINCI_PLL_CNTRL0_BASE) - return 8; - else - return pll_div(pllbase, PLLC_PREDIV); -#endif - return 1; -} - -static inline unsigned pll_postdiv(volatile void *pllbase) -{ -#ifdef CONFIG_SOC_DM355 - return pll_div(pllbase, PLLC_POSTDIV); -#elif defined(CONFIG_SOC_DM6446) - if (pllbase == (volatile void *)DAVINCI_PLL_CNTRL0_BASE) - return pll_div(pllbase, PLLC_POSTDIV); -#endif - return 1; -} - -static unsigned pll_sysclk_mhz(unsigned pll_addr, unsigned div) -{ - volatile void *pllbase = (volatile void *) pll_addr; - unsigned base = CONFIG_SYS_HZ_CLOCK / 1000; - - /* the PLL might be bypassed */ - if (REG(pllbase + PLLC_PLLCTL) & BIT(0)) { - base /= pll_prediv(pllbase); - base *= 1 + (REG(pllbase + PLLC_PLLM) & 0x0ff); - base /= pll_postdiv(pllbase); - } - return DIV_ROUND_UP(base, 1000 * pll_div(pllbase, div)); -} - -int print_cpuinfo(void) -{ - /* REVISIT fetch and display CPU ID and revision information - * too ... that will matter as more revisions appear. - */ - printf("Cores: ARM %d MHz", - pll_sysclk_mhz(DAVINCI_PLL_CNTRL0_BASE, ARM_PLLDIV)); - -#ifdef DSP_PLLDIV - printf(", DSP %d MHz", - pll_sysclk_mhz(DAVINCI_PLL_CNTRL0_BASE, DSP_PLLDIV)); -#endif - - printf("\nDDR: %d MHz\n", - /* DDR PHY uses an x2 input clock */ - pll_sysclk_mhz(DAVINCI_PLL_CNTRL1_BASE, DDR_PLLDIV) - / 2); - return 0; -} - -#endif - -/* - * Initializes on-chip ethernet controllers. - * to override, implement board_eth_init() - */ -int cpu_eth_init(bd_t *bis) -{ -#if defined(CONFIG_DRIVER_TI_EMAC) - davinci_emac_initialize(); -#endif - return 0; -} diff --git a/cpu/arm926ejs/davinci/dm355.c b/cpu/arm926ejs/davinci/dm355.c deleted file mode 100644 index bc45b67fbe..0000000000 --- a/cpu/arm926ejs/davinci/dm355.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * SoC-specific code for tms320dm355 and similar chips - * - * Copyright (C) 2009 David Brownell - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include - - -void davinci_enable_uart0(void) -{ - lpsc_on(DAVINCI_LPSC_UART0); - - /* Bringup UART0 out of reset */ - REG(UART0_PWREMU_MGMT) = 0x00006001; -} - - -#ifdef CONFIG_DRIVER_DAVINCI_I2C -void davinci_enable_i2c(void) -{ - lpsc_on(DAVINCI_LPSC_I2C); - - /* Enable I2C pin Mux */ - REG(PINMUX3) |= (1 << 20) | (1 << 19); -} -#endif diff --git a/cpu/arm926ejs/davinci/dm365.c b/cpu/arm926ejs/davinci/dm365.c deleted file mode 100644 index 56c1bc032b..0000000000 --- a/cpu/arm926ejs/davinci/dm365.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * SoC-specific code for tms320dm365 and similar chips - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include - -void davinci_enable_uart0(void) -{ - lpsc_on(DAVINCI_LPSC_UART0); -} - -#ifdef CONFIG_DRIVER_DAVINCI_I2C -void davinci_enable_i2c(void) -{ - lpsc_on(DAVINCI_LPSC_I2C); -} -#endif diff --git a/cpu/arm926ejs/davinci/dm644x.c b/cpu/arm926ejs/davinci/dm644x.c deleted file mode 100644 index bb105b56ee..0000000000 --- a/cpu/arm926ejs/davinci/dm644x.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * SoC-specific code for tms320dm644x chips - * - * Copyright (C) 2007 Sergey Kubushyn - * Copyright (C) 2008 Lyrtech - * Copyright (C) 2004 Texas Instruments. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include - - -#define PINMUX0_EMACEN (1 << 31) -#define PINMUX0_AECS5 (1 << 11) -#define PINMUX0_AECS4 (1 << 10) - -#define PINMUX1_I2C (1 << 7) -#define PINMUX1_UART1 (1 << 1) -#define PINMUX1_UART0 (1 << 0) - - -void davinci_enable_uart0(void) -{ - lpsc_on(DAVINCI_LPSC_UART0); - - /* Bringup UART0 out of reset */ - REG(UART0_PWREMU_MGMT) = 0x00006001; - - /* Enable UART0 MUX lines */ - REG(PINMUX1) |= PINMUX1_UART0; -} - -#ifdef CONFIG_DRIVER_TI_EMAC -void davinci_enable_emac(void) -{ - lpsc_on(DAVINCI_LPSC_EMAC); - lpsc_on(DAVINCI_LPSC_EMAC_WRAPPER); - lpsc_on(DAVINCI_LPSC_MDIO); - - /* Enable GIO3.3V cells used for EMAC */ - REG(VDD3P3V_PWDN) = 0; - - /* Enable EMAC. */ - REG(PINMUX0) |= PINMUX0_EMACEN; -} -#endif - -#ifdef CONFIG_DRIVER_DAVINCI_I2C -void davinci_enable_i2c(void) -{ - lpsc_on(DAVINCI_LPSC_I2C); - - /* Enable I2C pin Mux */ - REG(PINMUX1) |= PINMUX1_I2C; -} -#endif - -void davinci_errata_workarounds(void) -{ - /* - * Workaround for TMS320DM6446 errata 1.3.22: - * PSC: PTSTAT Register Does Not Clear After Warm/Maximum Reset - * Revision(s) Affected: 1.3 and earlier - */ - REG(PSC_SILVER_BULLET) = 0; - - /* - * Set the PR_OLD_COUNT bits in the Bus Burst Priority Register (PBBPR) - * as suggested in TMS320DM6446 errata 2.1.2: - * - * On DM6446 Silicon Revision 2.1 and earlier, under certain conditions - * low priority modules can occupy the bus and prevent high priority - * modules like the VPSS from getting the required DDR2 throughput. - * A hex value of 0x20 should provide a good ARM (cache enabled) - * performance and still allow good utilization by the VPSS or other - * modules. - */ - REG(VBPR) = 0x20; -} diff --git a/cpu/arm926ejs/davinci/dm646x.c b/cpu/arm926ejs/davinci/dm646x.c deleted file mode 100644 index 329825f453..0000000000 --- a/cpu/arm926ejs/davinci/dm646x.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * SoC-specific code for TMS320DM646x chips - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include - -void davinci_enable_uart0(void) -{ - lpsc_on(DAVINCI_DM646X_LPSC_UART0); -} - -#ifdef CONFIG_DRIVER_TI_EMAC -void davinci_enable_emac(void) -{ - lpsc_on(DAVINCI_DM646X_LPSC_EMAC); -} -#endif - -#ifdef CONFIG_DRIVER_DAVINCI_I2C -void davinci_enable_i2c(void) -{ - lpsc_on(DAVINCI_DM646X_LPSC_I2C); -} -#endif diff --git a/cpu/arm926ejs/davinci/dp83848.c b/cpu/arm926ejs/davinci/dp83848.c deleted file mode 100644 index c71c685f72..0000000000 --- a/cpu/arm926ejs/davinci/dp83848.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * National Semiconductor DP83848 PHY Driver for TI DaVinci - * (TMS320DM644x) based boards. - * - * Copyright (C) 2007 Sergey Kubushyn - * - * -------------------------------------------------------- - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include - -#ifdef CONFIG_DRIVER_TI_EMAC - -#ifdef CONFIG_CMD_NET - -int dp83848_is_phy_connected(int phy_addr) -{ - u_int16_t id1, id2; - - if (!davinci_eth_phy_read(phy_addr, DP83848_PHYID1_REG, &id1)) - return(0); - if (!davinci_eth_phy_read(phy_addr, DP83848_PHYID2_REG, &id2)) - return(0); - - if ((id1 == DP83848_PHYID1_OUI) && (id2 == DP83848_PHYID2_OUI)) - return(1); - - return(0); -} - -int dp83848_get_link_speed(int phy_addr) -{ - u_int16_t tmp; - volatile emac_regs* emac = (emac_regs *)EMAC_BASE_ADDR; - - if (!davinci_eth_phy_read(phy_addr, DP83848_STAT_REG, &tmp)) - return(0); - - if (!(tmp & DP83848_LINK_STATUS)) /* link up? */ - return(0); - - if (!davinci_eth_phy_read(phy_addr, DP83848_PHY_STAT_REG, &tmp)) - return(0); - - /* Speed doesn't matter, there is no setting for it in EMAC... */ - if (tmp & DP83848_DUPLEX) { - /* set DM644x EMAC for Full Duplex */ - emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE | - EMAC_MACCONTROL_FULLDUPLEX_ENABLE; - } else { - /*set DM644x EMAC for Half Duplex */ - emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE; - } - - return(1); -} - - -int dp83848_init_phy(int phy_addr) -{ - int ret = 1; - - if (!dp83848_get_link_speed(phy_addr)) { - /* Try another time */ - udelay(100000); - ret = dp83848_get_link_speed(phy_addr); - } - - /* Disable PHY Interrupts */ - davinci_eth_phy_write(phy_addr, DP83848_PHY_INTR_CTRL_REG, 0); - - return(ret); -} - - -int dp83848_auto_negotiate(int phy_addr) -{ - u_int16_t tmp; - - - if (!davinci_eth_phy_read(phy_addr, DP83848_CTL_REG, &tmp)) - return(0); - - /* Restart Auto_negotiation */ - tmp &= ~DP83848_AUTONEG; /* remove autonegotiation enable */ - tmp |= DP83848_ISOLATE; /* Electrically isolate PHY */ - davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp); - - /* Set the Auto_negotiation Advertisement Register - * MII advertising for Next page, 100BaseTxFD and HD, - * 10BaseTFD and HD, IEEE 802.3 - */ - tmp = DP83848_NP | DP83848_TX_FDX | DP83848_TX_HDX | - DP83848_10_FDX | DP83848_10_HDX | DP83848_AN_IEEE_802_3; - davinci_eth_phy_write(phy_addr, DP83848_ANA_REG, tmp); - - - /* Read Control Register */ - if (!davinci_eth_phy_read(phy_addr, DP83848_CTL_REG, &tmp)) - return(0); - - tmp |= DP83848_SPEED_SELECT | DP83848_AUTONEG | DP83848_DUPLEX_MODE; - davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp); - - /* Restart Auto_negotiation */ - tmp |= DP83848_RESTART_AUTONEG; - davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp); - - /*check AutoNegotiate complete */ - udelay(10000); - if (!davinci_eth_phy_read(phy_addr, DP83848_STAT_REG, &tmp)) - return(0); - - if (!(tmp & DP83848_AUTONEG_COMP)) - return(0); - - return (dp83848_get_link_speed(phy_addr)); -} - -#endif /* CONFIG_CMD_NET */ - -#endif /* CONFIG_DRIVER_ETHER */ diff --git a/cpu/arm926ejs/davinci/lowlevel_init.S b/cpu/arm926ejs/davinci/lowlevel_init.S deleted file mode 100644 index 0a4b2cf674..0000000000 --- a/cpu/arm926ejs/davinci/lowlevel_init.S +++ /dev/null @@ -1,707 +0,0 @@ -/* - * Low-level board setup code for TI DaVinci SoC based boards. - * - * Copyright (C) 2007 Sergey Kubushyn - * - * Partially based on TI sources, original copyrights follow: - */ - -/* - * Board specific setup info - * - * (C) Copyright 2003 - * Texas Instruments, - * Kshitij Gupta - * - * Modified for OMAP 1610 H2 board by Nishant Kamat, Jan 2004 - * - * Modified for OMAP 5912 OSK board by Rishi Bhattacharya, Apr 2004 - * See file CREDITS for list of people who contributed to this - * project. - * - * Modified for DV-EVM board by Rishi Bhattacharya, Apr 2005 - * See file CREDITS for list of people who contributed to this - * project. - * - * Modified for DV-EVM board by Swaminathan S, Nov 2005 - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include - -.globl lowlevel_init -lowlevel_init: - - /*-------------------------------------------------------* - * Mask all IRQs by setting all bits in the EINT default * - *-------------------------------------------------------*/ - mov r1, $0 - ldr r0, =EINT_ENABLE0 - str r1, [r0] - ldr r0, =EINT_ENABLE1 - str r1, [r0] - - /*------------------------------------------------------* - * Put the GEM in reset * - *------------------------------------------------------*/ - - /* Put the GEM in reset */ - ldr r8, PSC_GEM_FLAG_CLEAR - ldr r6, MDCTL_GEM - ldr r7, [r6] - and r7, r7, r8 - str r7, [r6] - - /* Enable the Power Domain Transition Command */ - ldr r6, PTCMD - ldr r7, [r6] - orr r7, r7, $0x02 - str r7, [r6] - - /* Check for Transition Complete(PTSTAT) */ -checkStatClkStopGem: - ldr r6, PTSTAT - ldr r7, [r6] - ands r7, r7, $0x02 - bne checkStatClkStopGem - - /* Check for GEM Reset Completion */ -checkGemStatClkStop: - ldr r6, MDSTAT_GEM - ldr r7, [r6] - ands r7, r7, $0x100 - bne checkGemStatClkStop - - /* Do this for enabling a WDT initiated reset this is a workaround - for a chip bug. Not required under normal situations */ - ldr r6, P1394 - mov r10, $0 - str r10, [r6] - - /*------------------------------------------------------* - * Enable L1 & L2 Memories in Fast mode * - *------------------------------------------------------*/ - ldr r6, DFT_ENABLE - mov r10, $0x01 - str r10, [r6] - - ldr r6, MMARG_BRF0 - ldr r10, MMARG_BRF0_VAL - str r10, [r6] - - ldr r6, DFT_ENABLE - mov r10, $0 - str r10, [r6] - - /*------------------------------------------------------* - * DDR2 PLL Initialization * - *------------------------------------------------------*/ - - /* Select the Clock Mode Depending on the Value written in the Boot Table by the run script */ - mov r10, $0 - ldr r6, PLL2_CTL - ldr r7, PLL_CLKSRC_MASK - ldr r8, [r6] - and r8, r8, r7 - mov r9, r10, lsl $8 - orr r8, r8, r9 - str r8, [r6] - - /* Select the PLLEN source */ - ldr r7, PLL_ENSRC_MASK - and r8, r8, r7 - str r8, [r6] - - /* Bypass the PLL */ - ldr r7, PLL_BYPASS_MASK - and r8, r8, r7 - str r8, [r6] - - /* Wait for few cycles to allow PLLEN Mux switch properly to bypass Clock */ - mov r10, $0x20 -WaitPPL2Loop: - subs r10, r10, $1 - bne WaitPPL2Loop - - /* Reset the PLL */ - ldr r7, PLL_RESET_MASK - and r8, r8, r7 - str r8, [r6] - - /* Power up the PLL */ - ldr r7, PLL_PWRUP_MASK - and r8, r8, r7 - str r8, [r6] - - /* Enable the PLL from Disable Mode */ - ldr r7, PLL_DISABLE_ENABLE_MASK - and r8, r8, r7 - str r8, [r6] - - /* Program the PLL Multiplier */ - ldr r6, PLL2_PLLM - mov r2, $0x17 /* 162 MHz */ - str r2, [r6] - - /* Program the PLL2 Divisor Value */ - ldr r6, PLL2_DIV2 - mov r3, $0x01 - str r3, [r6] - - /* Program the PLL2 Divisor Value */ - ldr r6, PLL2_DIV1 - mov r4, $0x0b /* 54 MHz */ - str r4, [r6] - - /* PLL2 DIV2 MMR */ - ldr r8, PLL2_DIV_MASK - ldr r6, PLL2_DIV2 - ldr r9, [r6] - and r8, r8, r9 - mov r9, $0x01 - mov r9, r9, lsl $15 - orr r8, r8, r9 - str r8, [r6] - - /* Program the GOSET bit to take new divider values */ - ldr r6, PLL2_PLLCMD - ldr r7, [r6] - orr r7, r7, $0x01 - str r7, [r6] - - /* Wait for Done */ - ldr r6, PLL2_PLLSTAT -doneLoop_0: - ldr r7, [r6] - ands r7, r7, $0x01 - bne doneLoop_0 - - /* PLL2 DIV1 MMR */ - ldr r8, PLL2_DIV_MASK - ldr r6, PLL2_DIV1 - ldr r9, [r6] - and r8, r8, r9 - mov r9, $0x01 - mov r9, r9, lsl $15 - orr r8, r8, r9 - str r8, [r6] - - /* Program the GOSET bit to take new divider values */ - ldr r6, PLL2_PLLCMD - ldr r7, [r6] - orr r7, r7, $0x01 - str r7, [r6] - - /* Wait for Done */ - ldr r6, PLL2_PLLSTAT -doneLoop: - ldr r7, [r6] - ands r7, r7, $0x01 - bne doneLoop - - /* Wait for PLL to Reset Properly */ - mov r10, $0x218 -ResetPPL2Loop: - subs r10, r10, $1 - bne ResetPPL2Loop - - /* Bring PLL out of Reset */ - ldr r6, PLL2_CTL - ldr r8, [r6] - orr r8, r8, $0x08 - str r8, [r6] - - /* Wait for PLL to Lock */ - ldr r10, PLL_LOCK_COUNT -PLL2Lock: - subs r10, r10, $1 - bne PLL2Lock - - /* Enable the PLL */ - ldr r6, PLL2_CTL - ldr r8, [r6] - orr r8, r8, $0x01 - str r8, [r6] - - /*------------------------------------------------------* - * Issue Soft Reset to DDR Module * - *------------------------------------------------------*/ - - /* Shut down the DDR2 LPSC Module */ - ldr r8, PSC_FLAG_CLEAR - ldr r6, MDCTL_DDR2 - ldr r7, [r6] - and r7, r7, r8 - orr r7, r7, $0x03 - str r7, [r6] - - /* Enable the Power Domain Transition Command */ - ldr r6, PTCMD - ldr r7, [r6] - orr r7, r7, $0x01 - str r7, [r6] - - /* Check for Transition Complete(PTSTAT) */ -checkStatClkStop: - ldr r6, PTSTAT - ldr r7, [r6] - ands r7, r7, $0x01 - bne checkStatClkStop - - /* Check for DDR2 Controller Enable Completion */ -checkDDRStatClkStop: - ldr r6, MDSTAT_DDR2 - ldr r7, [r6] - and r7, r7, $0x1f - cmp r7, $0x03 - bne checkDDRStatClkStop - - /*------------------------------------------------------* - * Program DDR2 MMRs for 162MHz Setting * - *------------------------------------------------------*/ - - /* Program PHY Control Register */ - ldr r6, DDRCTL - ldr r7, DDRCTL_VAL - str r7, [r6] - - /* Program SDRAM Bank Config Register */ - ldr r6, SDCFG - ldr r7, SDCFG_VAL - str r7, [r6] - - /* Program SDRAM TIM-0 Config Register */ - ldr r6, SDTIM0 - ldr r7, SDTIM0_VAL_162MHz - str r7, [r6] - - /* Program SDRAM TIM-1 Config Register */ - ldr r6, SDTIM1 - ldr r7, SDTIM1_VAL_162MHz - str r7, [r6] - - /* Program the SDRAM Bank Config Control Register */ - ldr r10, MASK_VAL - ldr r8, SDCFG - ldr r9, SDCFG_VAL - and r9, r9, r10 - str r9, [r8] - - /* Program SDRAM SDREF Config Register */ - ldr r6, SDREF - ldr r7, SDREF_VAL - str r7, [r6] - - /*------------------------------------------------------* - * Issue Soft Reset to DDR Module * - *------------------------------------------------------*/ - - /* Issue a Dummy DDR2 read/write */ - ldr r8, DDR2_START_ADDR - ldr r7, DUMMY_VAL - str r7, [r8] - ldr r7, [r8] - - /* Shut down the DDR2 LPSC Module */ - ldr r8, PSC_FLAG_CLEAR - ldr r6, MDCTL_DDR2 - ldr r7, [r6] - and r7, r7, r8 - orr r7, r7, $0x01 - str r7, [r6] - - /* Enable the Power Domain Transition Command */ - ldr r6, PTCMD - ldr r7, [r6] - orr r7, r7, $0x01 - str r7, [r6] - - /* Check for Transition Complete(PTSTAT) */ -checkStatClkStop2: - ldr r6, PTSTAT - ldr r7, [r6] - ands r7, r7, $0x01 - bne checkStatClkStop2 - - /* Check for DDR2 Controller Enable Completion */ -checkDDRStatClkStop2: - ldr r6, MDSTAT_DDR2 - ldr r7, [r6] - and r7, r7, $0x1f - cmp r7, $0x01 - bne checkDDRStatClkStop2 - - /*------------------------------------------------------* - * Turn DDR2 Controller Clocks On * - *------------------------------------------------------*/ - - /* Enable the DDR2 LPSC Module */ - ldr r6, MDCTL_DDR2 - ldr r7, [r6] - orr r7, r7, $0x03 - str r7, [r6] - - /* Enable the Power Domain Transition Command */ - ldr r6, PTCMD - ldr r7, [r6] - orr r7, r7, $0x01 - str r7, [r6] - - /* Check for Transition Complete(PTSTAT) */ -checkStatClkEn2: - ldr r6, PTSTAT - ldr r7, [r6] - ands r7, r7, $0x01 - bne checkStatClkEn2 - - /* Check for DDR2 Controller Enable Completion */ -checkDDRStatClkEn2: - ldr r6, MDSTAT_DDR2 - ldr r7, [r6] - and r7, r7, $0x1f - cmp r7, $0x03 - bne checkDDRStatClkEn2 - - /* DDR Writes and Reads */ - ldr r6, CFGTEST - mov r3, $0x01 - str r3, [r6] - - /*------------------------------------------------------* - * System PLL Initialization * - *------------------------------------------------------*/ - - /* Select the Clock Mode Depending on the Value written in the Boot Table by the run script */ - mov r2, $0 - ldr r6, PLL1_CTL - ldr r7, PLL_CLKSRC_MASK - ldr r8, [r6] - and r8, r8, r7 - mov r9, r2, lsl $8 - orr r8, r8, r9 - str r8, [r6] - - /* Select the PLLEN source */ - ldr r7, PLL_ENSRC_MASK - and r8, r8, r7 - str r8, [r6] - - /* Bypass the PLL */ - ldr r7, PLL_BYPASS_MASK - and r8, r8, r7 - str r8, [r6] - - /* Wait for few cycles to allow PLLEN Mux switch properly to bypass Clock */ - mov r10, $0x20 - -WaitLoop: - subs r10, r10, $1 - bne WaitLoop - - /* Reset the PLL */ - ldr r7, PLL_RESET_MASK - and r8, r8, r7 - str r8, [r6] - - /* Disable the PLL */ - orr r8, r8, $0x10 - str r8, [r6] - - /* Power up the PLL */ - ldr r7, PLL_PWRUP_MASK - and r8, r8, r7 - str r8, [r6] - - /* Enable the PLL from Disable Mode */ - ldr r7, PLL_DISABLE_ENABLE_MASK - and r8, r8, r7 - str r8, [r6] - - /* Program the PLL Multiplier */ - ldr r6, PLL1_PLLM - mov r3, $0x15 /* For 594MHz */ - str r3, [r6] - - /* Wait for PLL to Reset Properly */ - mov r10, $0xff - -ResetLoop: - subs r10, r10, $1 - bne ResetLoop - - /* Bring PLL out of Reset */ - ldr r6, PLL1_CTL - orr r8, r8, $0x08 - str r8, [r6] - - /* Wait for PLL to Lock */ - ldr r10, PLL_LOCK_COUNT - -PLL1Lock: - subs r10, r10, $1 - bne PLL1Lock - - /* Enable the PLL */ - orr r8, r8, $0x01 - str r8, [r6] - - nop - nop - nop - nop - - /*------------------------------------------------------* - * AEMIF configuration for NOR Flash (double check) * - *------------------------------------------------------*/ - ldr r0, _PINMUX0 - ldr r1, _DEV_SETTING - str r1, [r0] - - ldr r0, WAITCFG - ldr r1, WAITCFG_VAL - ldr r2, [r0] - orr r2, r2, r1 - str r2, [r0] - - ldr r0, ACFG3 - ldr r1, ACFG3_VAL - ldr r2, [r0] - and r1, r2, r1 - str r1, [r0] - - ldr r0, ACFG4 - ldr r1, ACFG4_VAL - ldr r2, [r0] - and r1, r2, r1 - str r1, [r0] - - ldr r0, ACFG5 - ldr r1, ACFG5_VAL - ldr r2, [r0] - and r1, r2, r1 - str r1, [r0] - - /*--------------------------------------* - * VTP manual Calibration * - *--------------------------------------*/ - ldr r0, VTPIOCR - ldr r1, VTP_MMR0 - str r1, [r0] - - ldr r0, VTPIOCR - ldr r1, VTP_MMR1 - str r1, [r0] - - /* Wait for 33 VTP CLK cycles. VRP operates at 27 MHz */ - ldr r10, VTP_LOCK_COUNT -VTPLock: - subs r10, r10, $1 - bne VTPLock - - ldr r6, DFT_ENABLE - mov r10, $0x01 - str r10, [r6] - - ldr r6, DDRVTPR - ldr r7, [r6] - and r7, r7, $0x1f - and r8, r7, $0x3e0 - orr r8, r7, r8 - ldr r7, VTP_RECAL - orr r8, r7, r8 - ldr r7, VTP_EN - orr r8, r7, r8 - str r8, [r0] - - - /* Wait for 33 VTP CLK cycles. VRP operates at 27 MHz */ - ldr r10, VTP_LOCK_COUNT -VTP1Lock: - subs r10, r10, $1 - bne VTP1Lock - - ldr r1, [r0] - ldr r2, VTP_MASK - and r2, r1, r2 - str r2, [r0] - - ldr r6, DFT_ENABLE - mov r10, $0 - str r10, [r6] - - /* - * Call board-specific lowlevel init. - * That MUST be present and THAT returns - * back to arch calling code with "mov pc, lr." - */ - b dv_board_init - -.ltorg - -_PINMUX0: - .word 0x01c40000 /* Device Configuration Registers */ -_PINMUX1: - .word 0x01c40004 /* Device Configuration Registers */ - -_DEV_SETTING: - .word 0x00000c1f - -WAITCFG: - .word 0x01e00004 -WAITCFG_VAL: - .word 0 -ACFG3: - .word 0x01e00014 -ACFG3_VAL: - .word 0x3ffffffd -ACFG4: - .word 0x01e00018 -ACFG4_VAL: - .word 0x3ffffffd -ACFG5: - .word 0x01e0001c -ACFG5_VAL: - .word 0x3ffffffd - -MDCTL_DDR2: - .word 0x01c41a34 -MDSTAT_DDR2: - .word 0x01c41834 - -PTCMD: - .word 0x01c41120 -PTSTAT: - .word 0x01c41128 - -EINT_ENABLE0: - .word 0x01c48018 -EINT_ENABLE1: - .word 0x01c4801c - -PSC_FLAG_CLEAR: - .word 0xffffffe0 -PSC_GEM_FLAG_CLEAR: - .word 0xfffffeff - -/* DDR2 MMR & CONFIGURATION VALUES, 162 MHZ clock */ -DDRCTL: - .word 0x200000e4 -DDRCTL_VAL: - .word 0x50006405 -SDREF: - .word 0x2000000c -SDREF_VAL: - .word 0x000005c3 -SDCFG: - .word 0x20000008 -SDCFG_VAL: -#ifdef DDR_4BANKS - .word 0x00178622 -#elif defined DDR_8BANKS - .word 0x00178632 -#else -#error "Unknown DDR configuration!!!" -#endif -SDTIM0: - .word 0x20000010 -SDTIM0_VAL_162MHz: - .word 0x28923211 -SDTIM1: - .word 0x20000014 -SDTIM1_VAL_162MHz: - .word 0x0016c722 -VTPIOCR: - .word 0x200000f0 /* VTP IO Control register */ -DDRVTPR: - .word 0x01c42030 /* DDR VPTR MMR */ -VTP_MMR0: - .word 0x201f -VTP_MMR1: - .word 0xa01f -DFT_ENABLE: - .word 0x01c4004c -VTP_LOCK_COUNT: - .word 0x5b0 -VTP_MASK: - .word 0xffffdfff -VTP_RECAL: - .word 0x40000 -VTP_EN: - .word 0x02000 -CFGTEST: - .word 0x80010000 -MASK_VAL: - .word 0x00000fff - -/* GEM Power Up & LPSC Control Register */ -MDCTL_GEM: - .word 0x01c41a9c -MDSTAT_GEM: - .word 0x01c4189c - -/* For WDT reset chip bug */ -P1394: - .word 0x01c41a20 - -PLL_CLKSRC_MASK: - .word 0xfffffeff /* Mask the Clock Mode bit */ -PLL_ENSRC_MASK: - .word 0xffffffdf /* Select the PLLEN source */ -PLL_BYPASS_MASK: - .word 0xfffffffe /* Put the PLL in BYPASS */ -PLL_RESET_MASK: - .word 0xfffffff7 /* Put the PLL in Reset Mode */ -PLL_PWRUP_MASK: - .word 0xfffffffd /* PLL Power up Mask Bit */ -PLL_DISABLE_ENABLE_MASK: - .word 0xffffffef /* Enable the PLL from Disable */ -PLL_LOCK_COUNT: - .word 0x2000 - -/* PLL1-SYSTEM PLL MMRs */ -PLL1_CTL: - .word 0x01c40900 -PLL1_PLLM: - .word 0x01c40910 - -/* PLL2-SYSTEM PLL MMRs */ -PLL2_CTL: - .word 0x01c40d00 -PLL2_PLLM: - .word 0x01c40d10 -PLL2_DIV1: - .word 0x01c40d18 -PLL2_DIV2: - .word 0x01c40d1c -PLL2_PLLCMD: - .word 0x01c40d38 -PLL2_PLLSTAT: - .word 0x01c40d3c -PLL2_DIV_MASK: - .word 0xffff7fff - -MMARG_BRF0: - .word 0x01c42010 /* BRF margin mode 0 (R/W)*/ -MMARG_BRF0_VAL: - .word 0x00444400 - -DDR2_START_ADDR: - .word 0x80000000 -DUMMY_VAL: - .word 0xa55aa55a diff --git a/cpu/arm926ejs/davinci/lxt972.c b/cpu/arm926ejs/davinci/lxt972.c deleted file mode 100644 index ce3e41c551..0000000000 --- a/cpu/arm926ejs/davinci/lxt972.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Intel LXT971/LXT972 PHY Driver for TI DaVinci - * (TMS320DM644x) based boards. - * - * Copyright (C) 2007 Sergey Kubushyn - * - * -------------------------------------------------------- - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include - -#ifdef CONFIG_DRIVER_TI_EMAC - -#ifdef CONFIG_CMD_NET - -int lxt972_is_phy_connected(int phy_addr) -{ - u_int16_t id1, id2; - - if (!davinci_eth_phy_read(phy_addr, PHY_PHYIDR1, &id1)) - return(0); - if (!davinci_eth_phy_read(phy_addr, PHY_PHYIDR2, &id2)) - return(0); - - if ((id1 == (0x0013)) && ((id2 & 0xfff0) == 0x78e0)) - return(1); - - return(0); -} - -int lxt972_get_link_speed(int phy_addr) -{ - u_int16_t stat1, tmp; - volatile emac_regs *emac = (emac_regs *)EMAC_BASE_ADDR; - - if (!davinci_eth_phy_read(phy_addr, PHY_LXT971_STAT2, &stat1)) - return(0); - - if (!(stat1 & PHY_LXT971_STAT2_LINK)) /* link up? */ - return(0); - - if (!davinci_eth_phy_read(phy_addr, PHY_LXT971_DIG_CFG, &tmp)) - return(0); - - tmp |= PHY_LXT971_DIG_CFG_MII_DRIVE; - - davinci_eth_phy_write(phy_addr, PHY_LXT971_DIG_CFG, tmp); - /* Read back */ - if (!davinci_eth_phy_read(phy_addr, PHY_LXT971_DIG_CFG, &tmp)) - return(0); - - /* Speed doesn't matter, there is no setting for it in EMAC... */ - if (stat1 & PHY_LXT971_STAT2_DUPLEX_MODE) { - /* set DM644x EMAC for Full Duplex */ - emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE | - EMAC_MACCONTROL_FULLDUPLEX_ENABLE; - } else { - /*set DM644x EMAC for Half Duplex */ - emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE; - } - - return(1); -} - - -int lxt972_init_phy(int phy_addr) -{ - int ret = 1; - - if (!lxt972_get_link_speed(phy_addr)) { - /* Try another time */ - ret = lxt972_get_link_speed(phy_addr); - } - - /* Disable PHY Interrupts */ - davinci_eth_phy_write(phy_addr, PHY_LXT971_INT_ENABLE, 0); - - return(ret); -} - - -int lxt972_auto_negotiate(int phy_addr) -{ - u_int16_t tmp; - - if (!davinci_eth_phy_read(phy_addr, PHY_BMCR, &tmp)) - return(0); - - /* Restart Auto_negotiation */ - tmp |= PHY_BMCR_RST_NEG; - davinci_eth_phy_write(phy_addr, PHY_BMCR, tmp); - - /*check AutoNegotiate complete */ - udelay (10000); - if (!davinci_eth_phy_read(phy_addr, PHY_BMSR, &tmp)) - return(0); - - if (!(tmp & PHY_BMSR_AUTN_COMP)) - return(0); - - return (lxt972_get_link_speed(phy_addr)); -} - -#endif /* CONFIG_CMD_NET */ - -#endif /* CONFIG_DRIVER_ETHER */ diff --git a/cpu/arm926ejs/davinci/psc.c b/cpu/arm926ejs/davinci/psc.c deleted file mode 100644 index 8273a7fae4..0000000000 --- a/cpu/arm926ejs/davinci/psc.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Power and Sleep Controller (PSC) functions. - * - * Copyright (C) 2007 Sergey Kubushyn - * Copyright (C) 2008 Lyrtech - * Copyright (C) 2004 Texas Instruments. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include - -/* - * The PSC manages three inputs to a "module" which may be a peripheral or - * CPU. Those inputs are the module's: clock; reset signal; and sometimes - * its power domain. For our purposes, we only care whether clock and power - * are active, and the module is out of reset. - * - * DaVinci chips may include two separate power domains: "Always On" and "DSP". - * Chips without a DSP generally have only one domain. - * - * The "Always On" power domain is always on when the chip is on, and is - * powered by the VDD pins (on DM644X). The majority of DaVinci modules - * lie within the "Always On" power domain. - * - * A separate domain called the "DSP" domain houses the C64x+ and other video - * hardware such as VICP. In some chips, the "DSP" domain is not always on. - * The "DSP" power domain is powered by the CVDDDSP pins (on DM644X). - */ - -/* Works on Always On power domain only (no PD argument) */ -void lpsc_on(unsigned int id) -{ - dv_reg_p mdstat, mdctl, ptstat, ptcmd; -#ifdef CONFIG_SOC_DA8XX - struct davinci_psc_regs *psc_regs; -#endif - -#ifndef CONFIG_SOC_DA8XX - if (id >= DAVINCI_LPSC_GEM) - return; /* Don't work on DSP Power Domain */ - - mdstat = REG_P(PSC_MDSTAT_BASE + (id * 4)); - mdctl = REG_P(PSC_MDCTL_BASE + (id * 4)); - ptstat = REG_P(PSC_PTSTAT); - ptcmd = REG_P(PSC_PTCMD); -#else - if (id < DAVINCI_LPSC_PSC1_BASE) { - if (id >= PSC_PSC0_MODULE_ID_CNT) - return; - psc_regs = davinci_psc0_regs; - mdstat = &psc_regs->psc0.mdstat[id]; - mdctl = &psc_regs->psc0.mdctl[id]; - } else { - id -= DAVINCI_LPSC_PSC1_BASE; - if (id >= PSC_PSC1_MODULE_ID_CNT) - return; - psc_regs = davinci_psc1_regs; - mdstat = &psc_regs->psc1.mdstat[id]; - mdctl = &psc_regs->psc1.mdctl[id]; - } - ptstat = &psc_regs->ptstat; - ptcmd = &psc_regs->ptcmd; -#endif - - while (readl(ptstat) & 0x01) - continue; - - if ((readl(mdstat) & 0x1f) == 0x03) - return; /* Already on and enabled */ - - writel(readl(mdctl) | 0x03, mdctl); - - switch (id) { -#ifdef CONFIG_SOC_DM644X - /* Special treatment for some modules as for sprue14 p.7.4.2 */ - case DAVINCI_LPSC_VPSSSLV: - case DAVINCI_LPSC_EMAC: - case DAVINCI_LPSC_EMAC_WRAPPER: - case DAVINCI_LPSC_MDIO: - case DAVINCI_LPSC_USB: - case DAVINCI_LPSC_ATA: - case DAVINCI_LPSC_VLYNQ: - case DAVINCI_LPSC_UHPI: - case DAVINCI_LPSC_DDR_EMIF: - case DAVINCI_LPSC_AEMIF: - case DAVINCI_LPSC_MMC_SD: - case DAVINCI_LPSC_MEMSTICK: - case DAVINCI_LPSC_McBSP: - case DAVINCI_LPSC_GPIO: - writel(readl(mdctl) | 0x200, mdctl); - break; -#endif - } - - writel(0x01, ptcmd); - - while (readl(ptstat) & 0x01) - continue; - while ((readl(mdstat) & 0x1f) != 0x03) - continue; -} - -/* Not all DaVinci chips have a DSP power domain. */ -#ifdef CONFIG_SOC_DM644X - -/* If DSPLINK is used, we don't want U-Boot to power on the DSP. */ -#if !defined(CONFIG_SYS_USE_DSPLINK) -void dsp_on(void) -{ - int i; - - if (REG(PSC_PDSTAT1) & 0x1f) - return; /* Already on */ - - REG(PSC_GBLCTL) |= 0x01; - REG(PSC_PDCTL1) |= 0x01; - REG(PSC_PDCTL1) &= ~0x100; - REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_GEM * 4)) |= 0x03; - REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_GEM * 4)) &= 0xfffffeff; - REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_IMCOP * 4)) |= 0x03; - REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_IMCOP * 4)) &= 0xfffffeff; - REG(PSC_PTCMD) = 0x02; - - for (i = 0; i < 100; i++) { - if (REG(PSC_EPCPR) & 0x02) - break; - } - - REG(PSC_CHP_SHRTSW) = 0x01; - REG(PSC_PDCTL1) |= 0x100; - REG(PSC_EPCCR) = 0x02; - - for (i = 0; i < 100; i++) { - if (!(REG(PSC_PTSTAT) & 0x02)) - break; - } - - REG(PSC_GBLCTL) &= ~0x1f; -} -#endif /* CONFIG_SYS_USE_DSPLINK */ - -#endif /* have a DSP */ diff --git a/cpu/arm926ejs/davinci/reset.S b/cpu/arm926ejs/davinci/reset.S deleted file mode 100644 index ba0a7c3b4b..0000000000 --- a/cpu/arm926ejs/davinci/reset.S +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Processor reset using WDT for TI TMS320DM644x SoC. - * - * Copyright (C) 2007 Sergey Kubushyn - * - * ----------------------------------------------------- - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -.globl reset_cpu -reset_cpu: - ldr r0, WDT_TGCR - mov r1, $0x08 - str r1, [r0] - ldr r1, [r0] - orr r1, r1, $0x03 - str r1, [r0] - mov r1, $0 - ldr r0, WDT_TIM12 - str r1, [r0] - ldr r0, WDT_TIM34 - str r1, [r0] - ldr r0, WDT_PRD12 - str r1, [r0] - ldr r0, WDT_PRD34 - str r1, [r0] - ldr r0, WDT_TCR - ldr r1, [r0] - orr r1, r1, $0x40 - str r1, [r0] - ldr r0, WDT_WDTCR - ldr r1, [r0] - orr r1, r1, $0x4000 - str r1, [r0] - ldr r1, WDTCR_VAL1 - str r1, [r0] - ldr r1, WDTCR_VAL2 - str r1, [r0] - /* Write an invalid value to the WDKEY field to trigger - * an immediate watchdog reset */ - mov r1, $0x4000 - str r1, [r0] - nop - nop - nop - nop -reset_cpu_loop: - b reset_cpu_loop - -WDT_TGCR: - .word 0x01c21c24 -WDT_TIM12: - .word 0x01c21c10 -WDT_TIM34: - .word 0x01c21c14 -WDT_PRD12: - .word 0x01c21c18 -WDT_PRD34: - .word 0x01c21c1c -WDT_TCR: - .word 0x01c21c20 -WDT_WDTCR: - .word 0x01c21c28 -WDTCR_VAL1: - .word 0xa5c64000 -WDTCR_VAL2: - .word 0xda7e4000 diff --git a/cpu/arm926ejs/davinci/timer.c b/cpu/arm926ejs/davinci/timer.c deleted file mode 100644 index 9da7443f30..0000000000 --- a/cpu/arm926ejs/davinci/timer.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * (C) Copyright 2003 - * Texas Instruments - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * (C) Copyright 2002-2004 - * Gary Jennejohn, DENX Software Engineering, - * - * (C) Copyright 2004 - * Philippe Robin, ARM Ltd. - * - * Copyright (C) 2007 Sergey Kubushyn - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include - -struct davinci_timer { - u_int32_t pid12; - u_int32_t emumgt; - u_int32_t na1; - u_int32_t na2; - u_int32_t tim12; - u_int32_t tim34; - u_int32_t prd12; - u_int32_t prd34; - u_int32_t tcr; - u_int32_t tgcr; - u_int32_t wdtcr; -}; - -static struct davinci_timer * const timer = - (struct davinci_timer *)CONFIG_SYS_TIMERBASE; - -#define TIMER_LOAD_VAL (CONFIG_SYS_HZ_CLOCK / CONFIG_SYS_HZ) -#define TIM_CLK_DIV 16 - -static ulong timestamp; -static ulong lastinc; - -int timer_init(void) -{ - /* We are using timer34 in unchained 32-bit mode, full speed */ - writel(0x0, &timer->tcr); - writel(0x0, &timer->tgcr); - writel(0x06 | ((TIM_CLK_DIV - 1) << 8), &timer->tgcr); - writel(0x0, &timer->tim34); - writel(TIMER_LOAD_VAL, &timer->prd34); - lastinc = 0; - timestamp = 0; - writel(2 << 22, &timer->tcr); - - return(0); -} - -void reset_timer(void) -{ - writel(0x0, &timer->tcr); - writel(0x0, &timer->tim34); - lastinc = 0; - timestamp = 0; - writel(2 << 22, &timer->tcr); -} - -static ulong get_timer_raw(void) -{ - ulong now = readl(&timer->tim34); - - if (now >= lastinc) { - /* normal mode */ - timestamp += now - lastinc; - } else { - /* overflow ... */ - timestamp += now + TIMER_LOAD_VAL - lastinc; - } - lastinc = now; - return timestamp; -} - -ulong get_timer(ulong base) -{ - return((get_timer_raw() / (TIMER_LOAD_VAL / TIM_CLK_DIV)) - base); -} - -void set_timer(ulong t) -{ - timestamp = t; -} - -void __udelay(unsigned long usec) -{ - ulong tmo; - ulong endtime; - signed long diff; - - tmo = CONFIG_SYS_HZ_CLOCK / 1000; - tmo *= usec; - tmo /= (1000 * TIM_CLK_DIV); - - endtime = get_timer_raw() + tmo; - - do { - ulong now = get_timer_raw(); - diff = endtime - now; - } while (diff >= 0); -} - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return(get_timer(0)); -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk(void) -{ - return CONFIG_SYS_HZ; -} diff --git a/cpu/arm926ejs/kirkwood/Makefile b/cpu/arm926ejs/kirkwood/Makefile deleted file mode 100644 index fc2cc03001..0000000000 --- a/cpu/arm926ejs/kirkwood/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -# -# (C) Copyright 2009 -# Marvell Semiconductor -# Written-by: Prafulla Wadaskar -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, -# MA 02110-1301 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(SOC).a - -COBJS-y = cpu.o -COBJS-y += dram.o -COBJS-y += mpp.o -COBJS-y += timer.o - -SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y)) - -all: $(obj).depend $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/arm926ejs/kirkwood/cpu.c b/cpu/arm926ejs/kirkwood/cpu.c deleted file mode 100644 index 6fc3902580..0000000000 --- a/cpu/arm926ejs/kirkwood/cpu.c +++ /dev/null @@ -1,387 +0,0 @@ -/* - * (C) Copyright 2009 - * Marvell Semiconductor - * Written-by: Prafulla Wadaskar - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include - -#define BUFLEN 16 - -void reset_cpu(unsigned long ignored) -{ - struct kwcpu_registers *cpureg = - (struct kwcpu_registers *)KW_CPU_REG_BASE; - - writel(readl(&cpureg->rstoutn_mask) | (1 << 2), - &cpureg->rstoutn_mask); - writel(readl(&cpureg->sys_soft_rst) | 1, - &cpureg->sys_soft_rst); - while (1) ; -} - -/* - * Generates Ramdom hex number reading some time varient system registers - * and using md5 algorithm - */ -unsigned char get_random_hex(void) -{ - int i; - u32 inbuf[BUFLEN]; - u8 outbuf[BUFLEN]; - - /* - * in case of 88F6281/88F6192 A0, - * Bit7 need to reset to generate random values in KW_REG_UNDOC_0x1470 - * Soc reg offsets KW_REG_UNDOC_0x1470 and KW_REG_UNDOC_0x1478 are reserved regs and - * Does not have names at this moment (no errata available) - */ - writel(readl(KW_REG_UNDOC_0x1478) & ~(1 << 7), KW_REG_UNDOC_0x1478); - for (i = 0; i < BUFLEN; i++) { - inbuf[i] = readl(KW_REG_UNDOC_0x1470); - } - md5((u8 *) inbuf, (BUFLEN * sizeof(u32)), outbuf); - return outbuf[outbuf[7] % 0x0f]; -} - -/* - * Window Size - * Used with the Base register to set the address window size and location. - * Must be programmed from LSB to MSB as sequence of ones followed by - * sequence of zeros. The number of ones specifies the size of the window in - * 64 KByte granularity (e.g., a value of 0x00FF specifies 256 = 16 MByte). - * NOTE: A value of 0x0 specifies 64-KByte size. - */ -unsigned int kw_winctrl_calcsize(unsigned int sizeval) -{ - int i; - unsigned int j = 0; - u32 val = sizeval >> 1; - - for (i = 0; val > 0x10000; i++) { - j |= (1 << i); - val = val >> 1; - } - return (0x0000ffff & j); -} - -/* - * kw_config_adr_windows - Configure address Windows - * - * There are 8 address windows supported by Kirkwood Soc to addess different - * devices. Each window can be configured for size, BAR and remap addr - * Below configuration is standard for most of the cases - * - * If remap function not used, remap_lo must be set as base - * - * Reference Documentation: - * Mbus-L to Mbus Bridge Registers Configuration. - * (Sec 25.1 and 25.3 of Datasheet) - */ -int kw_config_adr_windows(void) -{ - struct kwwin_registers *winregs = - (struct kwwin_registers *)KW_CPU_WIN_BASE; - - /* Window 0: PCIE MEM address space */ - writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 256, KWCPU_TARGET_PCIE, - KWCPU_ATTR_PCIE_MEM, KWCPU_WIN_ENABLE), &winregs[0].ctrl); - - writel(KW_DEFADR_PCI_MEM, &winregs[0].base); - writel(KW_DEFADR_PCI_MEM, &winregs[0].remap_lo); - writel(0x0, &winregs[0].remap_hi); - - /* Window 1: PCIE IO address space */ - writel(KWCPU_WIN_CTRL_DATA(1024 * 64, KWCPU_TARGET_PCIE, - KWCPU_ATTR_PCIE_IO, KWCPU_WIN_ENABLE), &winregs[1].ctrl); - writel(KW_DEFADR_PCI_IO, &winregs[1].base); - writel(KW_DEFADR_PCI_IO_REMAP, &winregs[1].remap_lo); - writel(0x0, &winregs[1].remap_hi); - - /* Window 2: NAND Flash address space */ - writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 128, KWCPU_TARGET_MEMORY, - KWCPU_ATTR_NANDFLASH, KWCPU_WIN_ENABLE), &winregs[2].ctrl); - writel(KW_DEFADR_NANDF, &winregs[2].base); - writel(KW_DEFADR_NANDF, &winregs[2].remap_lo); - writel(0x0, &winregs[2].remap_hi); - - /* Window 3: SPI Flash address space */ - writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 128, KWCPU_TARGET_MEMORY, - KWCPU_ATTR_SPIFLASH, KWCPU_WIN_ENABLE), &winregs[3].ctrl); - writel(KW_DEFADR_SPIF, &winregs[3].base); - writel(KW_DEFADR_SPIF, &winregs[3].remap_lo); - writel(0x0, &winregs[3].remap_hi); - - /* Window 4: BOOT Memory address space */ - writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 128, KWCPU_TARGET_MEMORY, - KWCPU_ATTR_BOOTROM, KWCPU_WIN_ENABLE), &winregs[4].ctrl); - writel(KW_DEFADR_BOOTROM, &winregs[4].base); - - /* Window 5: Security SRAM address space */ - writel(KWCPU_WIN_CTRL_DATA(1024 * 64, KWCPU_TARGET_SASRAM, - KWCPU_ATTR_SASRAM, KWCPU_WIN_ENABLE), &winregs[5].ctrl); - writel(KW_DEFADR_SASRAM, &winregs[5].base); - - /* Window 6-7: Disabled */ - writel(KWCPU_WIN_DISABLE, &winregs[6].ctrl); - writel(KWCPU_WIN_DISABLE, &winregs[7].ctrl); - - return 0; -} - -/* - * kw_config_gpio - GPIO configuration - */ -void kw_config_gpio(u32 gpp0_oe_val, u32 gpp1_oe_val, u32 gpp0_oe, u32 gpp1_oe) -{ - struct kwgpio_registers *gpio0reg = - (struct kwgpio_registers *)KW_GPIO0_BASE; - struct kwgpio_registers *gpio1reg = - (struct kwgpio_registers *)KW_GPIO1_BASE; - - /* Init GPIOS to default values as per board requirement */ - writel(gpp0_oe_val, &gpio0reg->dout); - writel(gpp1_oe_val, &gpio1reg->dout); - writel(gpp0_oe, &gpio0reg->oe); - writel(gpp1_oe, &gpio1reg->oe); -} - -/* - * kw_config_mpp - Multi-Purpose Pins Functionality configuration - * - * Each MPP can be configured to different functionality through - * MPP control register, ref (sec 6.1 of kirkwood h/w specification) - * - * There are maximum 64 Multi-Pourpose Pins on Kirkwood - * Each MPP functionality can be configuration by a 4bit value - * of MPP control reg, the value and associated functionality depends - * upon used SoC varient - */ -int kw_config_mpp(u32 mpp0_7, u32 mpp8_15, u32 mpp16_23, u32 mpp24_31, - u32 mpp32_39, u32 mpp40_47, u32 mpp48_55) -{ - u32 *mppreg = (u32 *) KW_MPP_BASE; - - /* program mpp registers */ - writel(mpp0_7, &mppreg[0]); - writel(mpp8_15, &mppreg[1]); - writel(mpp16_23, &mppreg[2]); - writel(mpp24_31, &mppreg[3]); - writel(mpp32_39, &mppreg[4]); - writel(mpp40_47, &mppreg[5]); - writel(mpp48_55, &mppreg[6]); - return 0; -} - -/* - * SYSRSTn Duration Counter Support - * - * Kirkwood SoC implements a hardware-based SYSRSTn duration counter. - * When SYSRSTn is asserted low, a SYSRSTn duration counter is running. - * The SYSRSTn duration counter is useful for implementing a manufacturer - * or factory reset. Upon a long reset assertion that is greater than a - * pre-configured environment variable value for sysrstdelay, - * The counter value is stored in the SYSRSTn Length Counter Register - * The counter is based on the 25-MHz reference clock (40ns) - * It is a 29-bit counter, yielding a maximum counting duration of - * 2^29/25 MHz (21.4 seconds). When the counter reach its maximum value, - * it remains at this value until counter reset is triggered by setting - * bit 31 of KW_REG_SYSRST_CNT - */ -static void kw_sysrst_action(void) -{ - int ret; - char *s = getenv("sysrstcmd"); - - if (!s) { - debug("Error.. %s failed, check sysrstcmd\n", - __FUNCTION__); - return; - } - - debug("Starting %s process...\n", __FUNCTION__); -#if !defined(CONFIG_SYS_HUSH_PARSER) - ret = run_command (s, 0); -#else - ret = parse_string_outer(s, FLAG_PARSE_SEMICOLON - | FLAG_EXIT_FROM_LOOP); -#endif - if (ret < 0) - debug("Error.. %s failed\n", __FUNCTION__); - else - debug("%s process finished\n", __FUNCTION__); -} - -static void kw_sysrst_check(void) -{ - u32 sysrst_cnt, sysrst_dly; - char *s; - - /* - * no action if sysrstdelay environment variable is not defined - */ - s = getenv("sysrstdelay"); - if (s == NULL) - return; - - /* read sysrstdelay value */ - sysrst_dly = (u32) simple_strtoul(s, NULL, 10); - - /* read SysRst Length counter register (bits 28:0) */ - sysrst_cnt = (0x1fffffff & readl(KW_REG_SYSRST_CNT)); - debug("H/w Rst hold time: %d.%d secs\n", - sysrst_cnt / SYSRST_CNT_1SEC_VAL, - sysrst_cnt % SYSRST_CNT_1SEC_VAL); - - /* clear the counter for next valid read*/ - writel(1 << 31, KW_REG_SYSRST_CNT); - - /* - * sysrst_action: - * if H/w Reset key is pressed and hold for time - * more than sysrst_dly in seconds - */ - if (sysrst_cnt >= SYSRST_CNT_1SEC_VAL * sysrst_dly) - kw_sysrst_action(); -} - -#if defined(CONFIG_DISPLAY_CPUINFO) -int print_cpuinfo(void) -{ - char *name = "Unknown"; - - switch (readl(KW_REG_DEVICE_ID) & 0x03) { - case 1: - name = "88F6192_A0"; - break; - case 2: - name = "88F6281_A0"; - break; - default: - printf("SoC: Unsupported Kirkwood\n"); - return -1; - } - printf("SoC: Kirkwood %s\n", name); - return 0; -} -#endif /* CONFIG_DISPLAY_CPUINFO */ - -#ifdef CONFIG_ARCH_CPU_INIT -int arch_cpu_init(void) -{ - u32 reg; - struct kwcpu_registers *cpureg = - (struct kwcpu_registers *)KW_CPU_REG_BASE; - - /* Linux expects` the internal registers to be at 0xf1000000 */ - writel(KW_REGS_PHY_BASE, KW_OFFSET_REG); - - /* Enable and invalidate L2 cache in write through mode */ - writel(readl(&cpureg->l2_cfg) | 0x18, &cpureg->l2_cfg); - invalidate_l2_cache(); - - kw_config_adr_windows(); - -#ifdef CONFIG_KIRKWOOD_RGMII_PAD_1V8 - /* - * Configures the I/O voltage of the pads connected to Egigabit - * Ethernet interface to 1.8V - * By defult it is set to 3.3V - */ - reg = readl(KW_REG_MPP_OUT_DRV_REG); - reg |= (1 << 7); - writel(reg, KW_REG_MPP_OUT_DRV_REG); -#endif -#ifdef CONFIG_KIRKWOOD_EGIGA_INIT - /* - * Set egiga port0/1 in normal functional mode - * This is required becasue on kirkwood by default ports are in reset mode - * OS egiga driver may not have provision to set them in normal mode - * and if u-boot is build without network support, network may fail at OS level - */ - reg = readl(KWGBE_PORT_SERIAL_CONTROL1_REG(0)); - reg &= ~(1 << 4); /* Clear PortReset Bit */ - writel(reg, (KWGBE_PORT_SERIAL_CONTROL1_REG(0))); - reg = readl(KWGBE_PORT_SERIAL_CONTROL1_REG(1)); - reg &= ~(1 << 4); /* Clear PortReset Bit */ - writel(reg, (KWGBE_PORT_SERIAL_CONTROL1_REG(1))); -#endif -#ifdef CONFIG_KIRKWOOD_PCIE_INIT - /* - * Enable PCI Express Port0 - */ - reg = readl(&cpureg->ctrl_stat); - reg |= (1 << 0); /* Set PEX0En Bit */ - writel(reg, &cpureg->ctrl_stat); -#endif - return 0; -} -#endif /* CONFIG_ARCH_CPU_INIT */ - -/* - * SOC specific misc init - */ -#if defined(CONFIG_ARCH_MISC_INIT) -int arch_misc_init(void) -{ - volatile u32 temp; - - /*CPU streaming & write allocate */ - temp = readfr_extra_feature_reg(); - temp &= ~(1 << 28); /* disable wr alloc */ - writefr_extra_feature_reg(temp); - - temp = readfr_extra_feature_reg(); - temp &= ~(1 << 29); /* streaming disabled */ - writefr_extra_feature_reg(temp); - - /* L2Cache settings */ - temp = readfr_extra_feature_reg(); - /* Disable L2C pre fetch - Set bit 24 */ - temp |= (1 << 24); - /* enable L2C - Set bit 22 */ - temp |= (1 << 22); - writefr_extra_feature_reg(temp); - - icache_enable(); - /* Change reset vector to address 0x0 */ - temp = get_cr(); - set_cr(temp & ~CR_V); - - /* checks and execute resset to factory event */ - kw_sysrst_check(); - - return 0; -} -#endif /* CONFIG_ARCH_MISC_INIT */ - -#ifdef CONFIG_KIRKWOOD_EGIGA -int cpu_eth_init(bd_t *bis) -{ - kirkwood_egiga_initialize(bis); - return 0; -} -#endif diff --git a/cpu/arm926ejs/kirkwood/dram.c b/cpu/arm926ejs/kirkwood/dram.c deleted file mode 100644 index 8f2a18af6b..0000000000 --- a/cpu/arm926ejs/kirkwood/dram.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * (C) Copyright 2009 - * Marvell Semiconductor - * Written-by: Prafulla Wadaskar - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include -#include - -#define KW_REG_CPUCS_WIN_BAR(x) (KW_REGISTER(0x1500) + (x * 0x08)) -#define KW_REG_CPUCS_WIN_SZ(x) (KW_REGISTER(0x1504) + (x * 0x08)) -/* - * kw_sdram_bar - reads SDRAM Base Address Register - */ -u32 kw_sdram_bar(enum memory_bank bank) -{ - u32 result = 0; - u32 enable = 0x01 & readl(KW_REG_CPUCS_WIN_SZ(bank)); - - if ((!enable) || (bank > BANK3)) - return 0; - - result = readl(KW_REG_CPUCS_WIN_BAR(bank)); - return result; -} - -/* - * kw_sdram_bs - reads SDRAM Bank size - */ -u32 kw_sdram_bs(enum memory_bank bank) -{ - u32 result = 0; - u32 enable = 0x01 & readl(KW_REG_CPUCS_WIN_SZ(bank)); - - if ((!enable) || (bank > BANK3)) - return 0; - result = 0xff000000 & readl(KW_REG_CPUCS_WIN_SZ(bank)); - result += 0x01000000; - return result; -} diff --git a/cpu/arm926ejs/kirkwood/mpp.c b/cpu/arm926ejs/kirkwood/mpp.c deleted file mode 100644 index b2f0ad55e3..0000000000 --- a/cpu/arm926ejs/kirkwood/mpp.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * arch/arm/mach-kirkwood/mpp.c - * - * MPP functions for Marvell Kirkwood SoCs - * Referenced from Linux kernel source - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include -#include -#include - -static u32 kirkwood_variant(void) -{ - switch (readl(KW_REG_DEVICE_ID) & 0x03) { - case 1: - return MPP_F6192_MASK; - case 2: - return MPP_F6281_MASK; - default: - debug("MPP setup: unknown kirkwood variant\n"); - return 0; - } -} - -#define MPP_CTRL(i) (KW_MPP_BASE + (i* 4)) -#define MPP_NR_REGS (1 + MPP_MAX/8) - -void kirkwood_mpp_conf(u32 *mpp_list) -{ - u32 mpp_ctrl[MPP_NR_REGS]; - unsigned int variant_mask; - int i; - - variant_mask = kirkwood_variant(); - if (!variant_mask) - return; - - debug( "initial MPP regs:"); - for (i = 0; i < MPP_NR_REGS; i++) { - mpp_ctrl[i] = readl(MPP_CTRL(i)); - debug(" %08x", mpp_ctrl[i]); - } - debug("\n"); - - - while (*mpp_list) { - unsigned int num = MPP_NUM(*mpp_list); - unsigned int sel = MPP_SEL(*mpp_list); - int shift; - - if (num > MPP_MAX) { - debug("kirkwood_mpp_conf: invalid MPP " - "number (%u)\n", num); - continue; - } - if (!(*mpp_list & variant_mask)) { - debug("kirkwood_mpp_conf: requested MPP%u config " - "unavailable on this hardware\n", num); - continue; - } - - shift = (num & 7) << 2; - mpp_ctrl[num / 8] &= ~(0xf << shift); - mpp_ctrl[num / 8] |= sel << shift; - - mpp_list++; - } - - debug(" final MPP regs:"); - for (i = 0; i < MPP_NR_REGS; i++) { - writel(mpp_ctrl[i], MPP_CTRL(i)); - debug(" %08x", mpp_ctrl[i]); - } - debug("\n"); - -} diff --git a/cpu/arm926ejs/kirkwood/timer.c b/cpu/arm926ejs/kirkwood/timer.c deleted file mode 100644 index 2ec6a93807..0000000000 --- a/cpu/arm926ejs/kirkwood/timer.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (C) Marvell International Ltd. and its affiliates - * Written-by: Prafulla Wadaskar - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include -#include - -#define UBOOT_CNTR 0 /* counter to use for uboot timer */ - -/* Timer reload and current value registers */ -struct kwtmr_val { - u32 reload; /* Timer reload reg */ - u32 val; /* Timer value reg */ -}; - -/* Timer registers */ -struct kwtmr_registers { - u32 ctrl; /* Timer control reg */ - u32 pad[3]; - struct kwtmr_val tmr[2]; - u32 wdt_reload; - u32 wdt_val; -}; - -struct kwtmr_registers *kwtmr_regs = (struct kwtmr_registers *)KW_TIMER_BASE; - -/* - * ARM Timers Registers Map - */ -#define CNTMR_CTRL_REG &kwtmr_regs->ctrl -#define CNTMR_RELOAD_REG(tmrnum) &kwtmr_regs->tmr[tmrnum].reload -#define CNTMR_VAL_REG(tmrnum) &kwtmr_regs->tmr[tmrnum].val - -/* - * ARM Timers Control Register - * CPU_TIMERS_CTRL_REG (CTCR) - */ -#define CTCR_ARM_TIMER_EN_OFFS(cntr) (cntr * 2) -#define CTCR_ARM_TIMER_EN_MASK(cntr) (1 << CTCR_ARM_TIMER_EN_OFFS) -#define CTCR_ARM_TIMER_EN(cntr) (1 << CTCR_ARM_TIMER_EN_OFFS(cntr)) -#define CTCR_ARM_TIMER_DIS(cntr) (0 << CTCR_ARM_TIMER_EN_OFFS(cntr)) - -#define CTCR_ARM_TIMER_AUTO_OFFS(cntr) ((cntr * 2) + 1) -#define CTCR_ARM_TIMER_AUTO_MASK(cntr) (1 << 1) -#define CTCR_ARM_TIMER_AUTO_EN(cntr) (1 << CTCR_ARM_TIMER_AUTO_OFFS(cntr)) -#define CTCR_ARM_TIMER_AUTO_DIS(cntr) (0 << CTCR_ARM_TIMER_AUTO_OFFS(cntr)) - -/* - * ARM Timer\Watchdog Reload Register - * CNTMR_RELOAD_REG (TRR) - */ -#define TRG_ARM_TIMER_REL_OFFS 0 -#define TRG_ARM_TIMER_REL_MASK 0xffffffff - -/* - * ARM Timer\Watchdog Register - * CNTMR_VAL_REG (TVRG) - */ -#define TVR_ARM_TIMER_OFFS 0 -#define TVR_ARM_TIMER_MASK 0xffffffff -#define TVR_ARM_TIMER_MAX 0xffffffff -#define TIMER_LOAD_VAL 0xffffffff - -#define READ_TIMER (readl(CNTMR_VAL_REG(UBOOT_CNTR)) / \ - (CONFIG_SYS_TCLK / 1000)) - -static ulong timestamp; -static ulong lastdec; - -void reset_timer_masked(void) -{ - /* reset time */ - lastdec = READ_TIMER; - timestamp = 0; -} - -ulong get_timer_masked(void) -{ - ulong now = READ_TIMER; - - if (lastdec >= now) { - /* normal mode */ - timestamp += lastdec - now; - } else { - /* we have an overflow ... */ - timestamp += lastdec + - (TIMER_LOAD_VAL / (CONFIG_SYS_TCLK / 1000)) - now; - } - lastdec = now; - - return timestamp; -} - -void reset_timer(void) -{ - reset_timer_masked(); -} - -ulong get_timer(ulong base) -{ - return get_timer_masked() - base; -} - -void set_timer(ulong t) -{ - timestamp = t; -} - -void __udelay(unsigned long usec) -{ - uint current; - ulong delayticks; - - current = readl(CNTMR_VAL_REG(UBOOT_CNTR)); - delayticks = (usec * (CONFIG_SYS_TCLK / 1000000)); - - if (current < delayticks) { - delayticks -= current; - while (readl(CNTMR_VAL_REG(UBOOT_CNTR)) < current) ; - while ((TIMER_LOAD_VAL - delayticks) < - readl(CNTMR_VAL_REG(UBOOT_CNTR))) ; - } else { - while (readl(CNTMR_VAL_REG(UBOOT_CNTR)) > - (current - delayticks)) ; - } -} - -/* - * init the counter - */ -int timer_init(void) -{ - unsigned int cntmrctrl; - - /* load value into timer */ - writel(TIMER_LOAD_VAL, CNTMR_RELOAD_REG(UBOOT_CNTR)); - writel(TIMER_LOAD_VAL, CNTMR_VAL_REG(UBOOT_CNTR)); - - /* enable timer in auto reload mode */ - cntmrctrl = readl(CNTMR_CTRL_REG); - cntmrctrl |= CTCR_ARM_TIMER_EN(UBOOT_CNTR); - cntmrctrl |= CTCR_ARM_TIMER_AUTO_EN(UBOOT_CNTR); - writel(cntmrctrl, CNTMR_CTRL_REG); - - /* init the timestamp and lastdec value */ - reset_timer_masked(); - - return 0; -} diff --git a/cpu/arm926ejs/mx25/Makefile b/cpu/arm926ejs/mx25/Makefile deleted file mode 100644 index 55c1e899be..0000000000 --- a/cpu/arm926ejs/mx25/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(SOC).a - -COBJS = generic.o timer.o -MX27OBJS = reset.o - -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -SRCS += $(addprefix $(SRCTREE)/cpu/arm926ejs/mx27/,$(MX27OBJS:.o=.c)) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS) $(MX27OBJS)) - -all: $(obj).depend $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/arm926ejs/mx25/generic.c b/cpu/arm926ejs/mx25/generic.c deleted file mode 100644 index 694841dd10..0000000000 --- a/cpu/arm926ejs/mx25/generic.c +++ /dev/null @@ -1,263 +0,0 @@ -/* - * (C) Copyright 2009 DENX Software Engineering - * Author: John Rigby - * - * Based on mx27/generic.c: - * Copyright (c) 2008 Eric Jarrige - * Copyright (c) 2009 Ilya Yanok - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_MXC_MMC -#include -#endif - -/* - * get the system pll clock in Hz - * - * mfi + mfn / (mfd +1) - * f = 2 * f_ref * -------------------- - * pd + 1 - */ -static unsigned int imx_decode_pll (unsigned int pll, unsigned int f_ref) -{ - unsigned int mfi = (pll >> CCM_PLL_MFI_SHIFT) - & CCM_PLL_MFI_MASK; - unsigned int mfn = (pll >> CCM_PLL_MFN_SHIFT) - & CCM_PLL_MFN_MASK; - unsigned int mfd = (pll >> CCM_PLL_MFD_SHIFT) - & CCM_PLL_MFD_MASK; - unsigned int pd = (pll >> CCM_PLL_PD_SHIFT) - & CCM_PLL_PD_MASK; - - mfi = mfi <= 5 ? 5 : mfi; - - return lldiv (2 * (u64) f_ref * (mfi * (mfd + 1) + mfn), - (mfd + 1) * (pd + 1)); -} - -static ulong imx_get_mpllclk (void) -{ - struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE; - ulong fref = 24000000; - - return imx_decode_pll (readl (&ccm->mpctl), fref); -} - -ulong imx_get_armclk (void) -{ - struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE; - ulong cctl = readl (&ccm->cctl); - ulong fref = imx_get_mpllclk (); - ulong div; - - if (cctl & CCM_CCTL_ARM_SRC) - fref = lldiv ((fref * 3), 4); - - div = ((cctl >> CCM_CCTL_ARM_DIV_SHIFT) - & CCM_CCTL_ARM_DIV_MASK) + 1; - - return lldiv (fref, div); -} - -ulong imx_get_ahbclk (void) -{ - struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE; - ulong cctl = readl (&ccm->cctl); - ulong fref = imx_get_armclk (); - ulong div; - - div = ((cctl >> CCM_CCTL_AHB_DIV_SHIFT) - & CCM_CCTL_AHB_DIV_MASK) + 1; - - return lldiv (fref, div); -} - -ulong imx_get_perclk (int clk) -{ - struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE; - ulong fref = imx_get_ahbclk (); - ulong div; - - div = readl (&ccm->pcdr[CCM_PERCLK_REG (clk)]); - div = ((div >> CCM_PERCLK_SHIFT (clk)) & CCM_PERCLK_MASK) + 1; - - return lldiv (fref, div); -} - -#if defined(CONFIG_DISPLAY_CPUINFO) -int print_cpuinfo (void) -{ - char buf[32]; - - printf ("CPU: Freescale i.MX25 at %s MHz\n\n", - strmhz (buf, imx_get_mpllclk ())); - return 0; -} -#endif - -int cpu_eth_init (bd_t * bis) -{ -#if defined(CONFIG_FEC_MXC) - struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE; - ulong val; - - val = readl (&ccm->cgr0); - val |= (1 << 23); - writel (val, &ccm->cgr0); - return fecmxc_initialize (bis); -#else - return 0; -#endif -} - -/* - * Initializes on-chip MMC controllers. - * to override, implement board_mmc_init() - */ -int cpu_mmc_init (bd_t * bis) -{ -#ifdef CONFIG_MXC_MMC - return mxc_mmc_init (bis); -#else - return 0; -#endif -} - -#ifdef CONFIG_MXC_UART -void mx25_uart_init_pins (void) -{ - struct iomuxc_mux_ctl *muxctl; - struct iomuxc_pad_ctl *padctl; - u32 inpadctl; - u32 outpadctl; - u32 muxmode0; - - muxctl = (struct iomuxc_mux_ctl *)IMX_IOPADMUX_BASE; - padctl = (struct iomuxc_pad_ctl *)IMX_IOPADCTL_BASE; - muxmode0 = MX25_PIN_MUX_MODE (0); - /* - * set up input pins with hysteresis and 100K pull-ups - */ - inpadctl = MX25_PIN_PAD_CTL_HYS - | MX25_PIN_PAD_CTL_PKE - | MX25_PIN_PAD_CTL_PUE | MX25_PIN_PAD_CTL_100K_PU; - - /* - * set up output pins with 100K pull-downs - * FIXME: need to revisit this - * PUE is ignored if PKE is not set - * so the right value here is likely - * 0x0 for no pull up/down - * or - * 0xc0 for 100k pull down - */ - outpadctl = MX25_PIN_PAD_CTL_PUE | MX25_PIN_PAD_CTL_100K_PD; - - /* UART1 */ - /* rxd */ - writel (muxmode0, &muxctl->pad_uart1_rxd); - writel (inpadctl, &padctl->pad_uart1_rxd); - - /* txd */ - writel (muxmode0, &muxctl->pad_uart1_txd); - writel (outpadctl, &padctl->pad_uart1_txd); - - /* rts */ - writel (muxmode0, &muxctl->pad_uart1_rts); - writel (outpadctl, &padctl->pad_uart1_rts); - - /* cts */ - writel (muxmode0, &muxctl->pad_uart1_cts); - writel (inpadctl, &padctl->pad_uart1_cts); -} -#endif /* CONFIG_MXC_UART */ - -#ifdef CONFIG_FEC_MXC -void mx25_fec_init_pins (void) -{ - struct iomuxc_mux_ctl *muxctl; - struct iomuxc_pad_ctl *padctl; - u32 inpadctl_100kpd; - u32 inpadctl_22kpu; - u32 outpadctl; - u32 muxmode0; - - muxctl = (struct iomuxc_mux_ctl *)IMX_IOPADMUX_BASE; - padctl = (struct iomuxc_pad_ctl *)IMX_IOPADCTL_BASE; - muxmode0 = MX25_PIN_MUX_MODE (0); - inpadctl_100kpd = MX25_PIN_PAD_CTL_HYS - | MX25_PIN_PAD_CTL_PKE - | MX25_PIN_PAD_CTL_PUE | MX25_PIN_PAD_CTL_100K_PD; - inpadctl_22kpu = MX25_PIN_PAD_CTL_HYS - | MX25_PIN_PAD_CTL_PKE - | MX25_PIN_PAD_CTL_PUE | MX25_PIN_PAD_CTL_22K_PU; - /* - * set up output pins with 100K pull-downs - * FIXME: need to revisit this - * PUE is ignored if PKE is not set - * so the right value here is likely - * 0x0 for no pull - * or - * 0xc0 for 100k pull down - */ - outpadctl = MX25_PIN_PAD_CTL_PUE | MX25_PIN_PAD_CTL_100K_PD; - - /* FEC_TX_CLK */ - writel (muxmode0, &muxctl->pad_fec_tx_clk); - writel (inpadctl_100kpd, &padctl->pad_fec_tx_clk); - - /* FEC_RX_DV */ - writel (muxmode0, &muxctl->pad_fec_rx_dv); - writel (inpadctl_100kpd, &padctl->pad_fec_rx_dv); - - /* FEC_RDATA0 */ - writel (muxmode0, &muxctl->pad_fec_rdata0); - writel (inpadctl_100kpd, &padctl->pad_fec_rdata0); - - /* FEC_TDATA0 */ - writel (muxmode0, &muxctl->pad_fec_tdata0); - writel (outpadctl, &padctl->pad_fec_tdata0); - - /* FEC_TX_EN */ - writel (muxmode0, &muxctl->pad_fec_tx_en); - writel (outpadctl, &padctl->pad_fec_tx_en); - - /* FEC_MDC */ - writel (muxmode0, &muxctl->pad_fec_mdc); - writel (outpadctl, &padctl->pad_fec_mdc); - - /* FEC_MDIO */ - writel (muxmode0, &muxctl->pad_fec_mdio); - writel (inpadctl_22kpu, &padctl->pad_fec_mdio); - - /* FEC_RDATA1 */ - writel (muxmode0, &muxctl->pad_fec_rdata1); - writel (inpadctl_100kpd, &padctl->pad_fec_rdata1); - - /* FEC_TDATA1 */ - writel (muxmode0, &muxctl->pad_fec_tdata1); - writel (outpadctl, &padctl->pad_fec_tdata1); - -} -#endif /* CONFIG_FEC_MXC */ diff --git a/cpu/arm926ejs/mx25/reset.c b/cpu/arm926ejs/mx25/reset.c deleted file mode 100644 index 1e33150eb9..0000000000 --- a/cpu/arm926ejs/mx25/reset.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * (C) Copyright 2009 - * Ilya Yanok, Emcraft Systems Ltd, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -/* - * Reset the cpu by setting up the watchdog timer and let it time out - */ -void reset_cpu (ulong ignored) -{ - struct wdog_regs *regs = (struct wdog_regs *)IMX_WDT_BASE; - /* Disable watchdog and set Time-Out field to 0 */ - writel (0x00000000, ®s->wcr); - - /* Write Service Sequence */ - writel (0x00005555, ®s->wsr); - writel (0x0000AAAA, ®s->wsr); - - /* Enable watchdog */ - writel (WCR_WDE, ®s->wcr); - - while (1) ; -} diff --git a/cpu/arm926ejs/mx25/timer.c b/cpu/arm926ejs/mx25/timer.c deleted file mode 100644 index 11d41a8bf9..0000000000 --- a/cpu/arm926ejs/mx25/timer.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * (C) Copyright 2009 - * Ilya Yanok, Emcraft Systems Ltd, - * - * (C) Copyright 2009 DENX Software Engineering - * Author: John Rigby - * Add support for MX25 - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include - -static ulong timestamp; -static ulong lastinc; - -/* - * "time" is measured in 1 / CONFIG_SYS_HZ seconds, - * "tick" is internal timer period - */ -#ifdef CONFIG_MX25_TIMER_HIGH_PRECISION -/* ~0.4% error - measured with stop-watch on 100s boot-delay */ -static inline unsigned long long tick_to_time(unsigned long long tick) -{ - tick *= CONFIG_SYS_HZ; - do_div(tick, CONFIG_MX25_CLK32); - return tick; -} - -static inline unsigned long long time_to_tick(unsigned long long time) -{ - time *= CONFIG_MX25_CLK32; - do_div(time, CONFIG_SYS_HZ); - return time; -} - -static inline unsigned long long us_to_tick(unsigned long long us) -{ - us = us * CONFIG_MX25_CLK32 + 999999; - do_div(us, 1000000); - return us; -} -#else -/* ~2% error */ -#define TICK_PER_TIME ((CONFIG_MX25_CLK32 + CONFIG_SYS_HZ / 2) / \ - CONFIG_SYS_HZ) -#define US_PER_TICK (1000000 / CONFIG_MX25_CLK32) - -static inline unsigned long long tick_to_time(unsigned long long tick) -{ - do_div(tick, TICK_PER_TIME); - return tick; -} - -static inline unsigned long long time_to_tick(unsigned long long time) -{ - return time * TICK_PER_TIME; -} - -static inline unsigned long long us_to_tick(unsigned long long us) -{ - us += US_PER_TICK - 1; - do_div(us, US_PER_TICK); - return us; -} -#endif - -/* nothing really to do with interrupts, just starts up a counter. */ -/* The 32KHz 32-bit timer overruns in 134217 seconds */ -int timer_init(void) -{ - int i; - struct gpt_regs *gpt = (struct gpt_regs *)IMX_GPT1_BASE; - struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE; - - /* setup GP Timer 1 */ - writel(GPT_CTRL_SWR, &gpt->ctrl); - - writel(readl(&ccm->cgr1) | CCM_CGR1_GPT1, &ccm->cgr1); - - for (i = 0; i < 100; i++) - writel(0, &gpt->ctrl); /* We have no udelay by now */ - writel(0, &gpt->pre); /* prescaler = 1 */ - /* Freerun Mode, 32KHz input */ - writel(readl(&gpt->ctrl) | GPT_CTRL_CLKSOURCE_32 | GPT_CTRL_FRR, - &gpt->ctrl); - writel(readl(&gpt->ctrl) | GPT_CTRL_TEN, &gpt->ctrl); - - return 0; -} - -void reset_timer_masked(void) -{ - struct gpt_regs *gpt = (struct gpt_regs *)IMX_GPT1_BASE; - /* reset time */ - /* capture current incrementer value time */ - lastinc = readl(&gpt->counter); - timestamp = 0; /* start "advancing" time stamp from 0 */ -} - -void reset_timer(void) -{ - reset_timer_masked(); -} - -unsigned long long get_ticks (void) -{ - struct gpt_regs *gpt = (struct gpt_regs *)IMX_GPT1_BASE; - ulong now = readl(&gpt->counter); /* current tick value */ - - if (now >= lastinc) { - /* - * normal mode (non roll) - * move stamp forward with absolut diff ticks - */ - timestamp += (now - lastinc); - } else { - /* we have rollover of incrementer */ - timestamp += (0xFFFFFFFF - lastinc) + now; - } - lastinc = now; - return timestamp; -} - -ulong get_timer_masked (void) -{ - /* - * get_ticks() returns a long long (64 bit), it wraps in - * 2^64 / CONFIG_MX25_CLK32 = 2^64 / 2^15 = 2^49 ~ 5 * 10^14 (s) ~ - * 5 * 10^9 days... and get_ticks() * CONFIG_SYS_HZ wraps in - * 5 * 10^6 days - long enough. - */ - return tick_to_time(get_ticks()); -} - -ulong get_timer (ulong base) -{ - return get_timer_masked () - base; -} - -void set_timer (ulong t) -{ - timestamp = time_to_tick(t); -} - -/* delay x useconds AND preserve advance timstamp value */ -void __udelay (unsigned long usec) -{ - unsigned long long tmp; - ulong tmo; - - tmo = us_to_tick(usec); - tmp = get_ticks() + tmo; /* get current timestamp */ - - while (get_ticks() < tmp) /* loop till event */ - /*NOP*/; -} diff --git a/cpu/arm926ejs/mx27/Makefile b/cpu/arm926ejs/mx27/Makefile deleted file mode 100644 index 67d1b0e303..0000000000 --- a/cpu/arm926ejs/mx27/Makefile +++ /dev/null @@ -1,44 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(SOC).a - -COBJS = generic.o reset.o timer.o - -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) - -all: $(obj).depend $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/arm926ejs/mx27/generic.c b/cpu/arm926ejs/mx27/generic.c deleted file mode 100644 index 30cf544712..0000000000 --- a/cpu/arm926ejs/mx27/generic.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Copyright (c) 2008 Eric Jarrige - * Copyright (c) 2009 Ilya Yanok - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#ifdef CONFIG_MXC_MMC -#include -#endif - -/* - * get the system pll clock in Hz - * - * mfi + mfn / (mfd +1) - * f = 2 * f_ref * -------------------- - * pd + 1 - */ -unsigned int imx_decode_pll(unsigned int pll, unsigned int f_ref) -{ - unsigned int mfi = (pll >> 10) & 0xf; - unsigned int mfn = pll & 0x3ff; - unsigned int mfd = (pll >> 16) & 0x3ff; - unsigned int pd = (pll >> 26) & 0xf; - - mfi = mfi <= 5 ? 5 : mfi; - - return lldiv(2 * (u64)f_ref * (mfi * (mfd + 1) + mfn), - (mfd + 1) * (pd + 1)); -} - -static ulong clk_in_32k(void) -{ - return 1024 * CONFIG_MX27_CLK32; -} - -static ulong clk_in_26m(void) -{ - struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; - - if (readl(&pll->cscr) & CSCR_OSC26M_DIV1P5) { - /* divide by 1.5 */ - return 26000000 * 2 / 3; - } else { - return 26000000; - } -} - -ulong imx_get_mpllclk(void) -{ - struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; - ulong cscr = readl(&pll->cscr); - ulong fref; - - if (cscr & CSCR_MCU_SEL) - fref = clk_in_26m(); - else - fref = clk_in_32k(); - - return imx_decode_pll(readl(&pll->mpctl0), fref); -} - -ulong imx_get_armclk(void) -{ - struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; - ulong cscr = readl(&pll->cscr); - ulong fref = imx_get_mpllclk(); - ulong div; - - if (!(cscr & CSCR_ARM_SRC_MPLL)) - fref = lldiv((fref * 2), 3); - - div = ((cscr >> 12) & 0x3) + 1; - - return lldiv(fref, div); -} - -ulong imx_get_ahbclk(void) -{ - struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; - ulong cscr = readl(&pll->cscr); - ulong fref = imx_get_mpllclk(); - ulong div; - - div = ((cscr >> 8) & 0x3) + 1; - - return lldiv(fref * 2, 3 * div); -} - -ulong imx_get_spllclk(void) -{ - struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; - ulong cscr = readl(&pll->cscr); - ulong fref; - - if (cscr & CSCR_SP_SEL) - fref = clk_in_26m(); - else - fref = clk_in_32k(); - - return imx_decode_pll(readl(&pll->spctl0), fref); -} - -static ulong imx_decode_perclk(ulong div) -{ - return lldiv((imx_get_mpllclk() * 2), (div * 3)); -} - -ulong imx_get_perclk1(void) -{ - struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; - - return imx_decode_perclk((readl(&pll->pcdr1) & 0x3f) + 1); -} - -ulong imx_get_perclk2(void) -{ - struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; - - return imx_decode_perclk(((readl(&pll->pcdr1) >> 8) & 0x3f) + 1); -} - -ulong imx_get_perclk3(void) -{ - struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; - - return imx_decode_perclk(((readl(&pll->pcdr1) >> 16) & 0x3f) + 1); -} - -ulong imx_get_perclk4(void) -{ - struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; - - return imx_decode_perclk(((readl(&pll->pcdr1) >> 24) & 0x3f) + 1); -} - -#if defined(CONFIG_DISPLAY_CPUINFO) -int print_cpuinfo (void) -{ - char buf[32]; - - printf("CPU: Freescale i.MX27 at %s MHz\n\n", - strmhz(buf, imx_get_mpllclk())); - return 0; -} -#endif - -int cpu_eth_init(bd_t *bis) -{ -#if defined(CONFIG_FEC_MXC) - struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; - - /* enable FEC clock */ - writel(readl(&pll->pccr1) | PCCR1_HCLK_FEC, &pll->pccr1); - writel(readl(&pll->pccr0) | PCCR0_FEC_EN, &pll->pccr0); - return fecmxc_initialize(bis); -#else - return 0; -#endif -} - -/* - * Initializes on-chip MMC controllers. - * to override, implement board_mmc_init() - */ -int cpu_mmc_init(bd_t *bis) -{ -#ifdef CONFIG_MXC_MMC - return mxc_mmc_init(bis); -#else - return 0; -#endif -} - -void imx_gpio_mode(int gpio_mode) -{ - struct gpio_regs *regs = (struct gpio_regs *)IMX_GPIO_BASE; - unsigned int pin = gpio_mode & GPIO_PIN_MASK; - unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; - unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> GPIO_OCR_SHIFT; - unsigned int aout = (gpio_mode & GPIO_AOUT_MASK) >> GPIO_AOUT_SHIFT; - unsigned int bout = (gpio_mode & GPIO_BOUT_MASK) >> GPIO_BOUT_SHIFT; - unsigned int tmp; - - /* Pullup enable */ - if (gpio_mode & GPIO_PUEN) { - writel(readl(®s->port[port].puen) | (1 << pin), - ®s->port[port].puen); - } else { - writel(readl(®s->port[port].puen) & ~(1 << pin), - ®s->port[port].puen); - } - - /* Data direction */ - if (gpio_mode & GPIO_OUT) { - writel(readl(®s->port[port].ddir) | 1 << pin, - ®s->port[port].ddir); - } else { - writel(readl(®s->port[port].ddir) & ~(1 << pin), - ®s->port[port].ddir); - } - - /* Primary / alternate function */ - if (gpio_mode & GPIO_AF) { - writel(readl(®s->port[port].gpr) | (1 << pin), - ®s->port[port].gpr); - } else { - writel(readl(®s->port[port].gpr) & ~(1 << pin), - ®s->port[port].gpr); - } - - /* use as gpio? */ - if (!(gpio_mode & (GPIO_PF | GPIO_AF))) { - writel(readl(®s->port[port].gius) | (1 << pin), - ®s->port[port].gius); - } else { - writel(readl(®s->port[port].gius) & ~(1 << pin), - ®s->port[port].gius); - } - - /* Output / input configuration */ - if (pin < 16) { - tmp = readl(®s->port[port].ocr1); - tmp &= ~(3 << (pin * 2)); - tmp |= (ocr << (pin * 2)); - writel(tmp, ®s->port[port].ocr1); - - writel(readl(®s->port[port].iconfa1) & ~(3 << (pin * 2)), - ®s->port[port].iconfa1); - writel(readl(®s->port[port].iconfa1) | aout << (pin * 2), - ®s->port[port].iconfa1); - writel(readl(®s->port[port].iconfb1) & ~(3 << (pin * 2)), - ®s->port[port].iconfb1); - writel(readl(®s->port[port].iconfb1) | bout << (pin * 2), - ®s->port[port].iconfb1); - } else { - pin -= 16; - - tmp = readl(®s->port[port].ocr2); - tmp &= ~(3 << (pin * 2)); - tmp |= (ocr << (pin * 2)); - writel(tmp, ®s->port[port].ocr2); - - writel(readl(®s->port[port].iconfa2) & ~(3 << (pin * 2)), - ®s->port[port].iconfa2); - writel(readl(®s->port[port].iconfa2) | aout << (pin * 2), - ®s->port[port].iconfa2); - writel(readl(®s->port[port].iconfb2) & ~(3 << (pin * 2)), - ®s->port[port].iconfb2); - writel(readl(®s->port[port].iconfb2) | bout << (pin * 2), - ®s->port[port].iconfb2); - } -} - -#ifdef CONFIG_MXC_UART -void mx27_uart_init_pins(void) -{ - int i; - unsigned int mode[] = { - PE12_PF_UART1_TXD, - PE13_PF_UART1_RXD, - }; - - for (i = 0; i < ARRAY_SIZE(mode); i++) - imx_gpio_mode(mode[i]); - -} -#endif /* CONFIG_MXC_UART */ - -#ifdef CONFIG_FEC_MXC -void mx27_fec_init_pins(void) -{ - int i; - unsigned int mode[] = { - PD0_AIN_FEC_TXD0, - PD1_AIN_FEC_TXD1, - PD2_AIN_FEC_TXD2, - PD3_AIN_FEC_TXD3, - PD4_AOUT_FEC_RX_ER, - PD5_AOUT_FEC_RXD1, - PD6_AOUT_FEC_RXD2, - PD7_AOUT_FEC_RXD3, - PD8_AF_FEC_MDIO, - PD9_AIN_FEC_MDC | GPIO_PUEN, - PD10_AOUT_FEC_CRS, - PD11_AOUT_FEC_TX_CLK, - PD12_AOUT_FEC_RXD0, - PD13_AOUT_FEC_RX_DV, - PD14_AOUT_FEC_CLR, - PD15_AOUT_FEC_COL, - PD16_AIN_FEC_TX_ER, - PF23_AIN_FEC_TX_EN, - }; - - for (i = 0; i < ARRAY_SIZE(mode); i++) - imx_gpio_mode(mode[i]); -} -#endif /* CONFIG_FEC_MXC */ - -#ifdef CONFIG_MXC_MMC -void mx27_sd2_init_pins(void) -{ - int i; - unsigned int mode[] = { - PB4_PF_SD2_D0, - PB5_PF_SD2_D1, - PB6_PF_SD2_D2, - PB7_PF_SD2_D3, - PB8_PF_SD2_CMD, - PB9_PF_SD2_CLK, - }; - - for (i = 0; i < ARRAY_SIZE(mode); i++) - imx_gpio_mode(mode[i]); - -} -#endif /* CONFIG_MXC_MMC */ diff --git a/cpu/arm926ejs/mx27/reset.c b/cpu/arm926ejs/mx27/reset.c deleted file mode 100644 index 6c54eafd37..0000000000 --- a/cpu/arm926ejs/mx27/reset.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * (C) Copyright 2009 - * Ilya Yanok, Emcraft Systems Ltd, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -/* - * Reset the cpu by setting up the watchdog timer and let it time out - */ -void reset_cpu (ulong ignored) -{ - struct wdog_regs *regs = (struct wdog_regs *)IMX_WDT_BASE; - /* Disable watchdog and set Time-Out field to 0 */ - writel(0x00000000, ®s->wcr); - - /* Write Service Sequence */ - writel(0x00005555, ®s->wsr); - writel(0x0000AAAA, ®s->wsr); - - /* Enable watchdog */ - writel(WCR_WDE, ®s->wcr); - - while (1); - /*NOTREACHED*/ -} diff --git a/cpu/arm926ejs/mx27/timer.c b/cpu/arm926ejs/mx27/timer.c deleted file mode 100644 index 8f1d47bba7..0000000000 --- a/cpu/arm926ejs/mx27/timer.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * (C) Copyright 2009 - * Ilya Yanok, Emcraft Systems Ltd, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include - -/* General purpose timers bitfields */ -#define GPTCR_SWR (1 << 15) /* Software reset */ -#define GPTCR_FRR (1 << 8) /* Freerun / restart */ -#define GPTCR_CLKSOURCE_32 (4 << 1) /* Clock source */ -#define GPTCR_TEN 1 /* Timer enable */ - -static ulong timestamp; -static ulong lastinc; - -/* - * "time" is measured in 1 / CONFIG_SYS_HZ seconds, - * "tick" is internal timer period - */ -#ifdef CONFIG_MX27_TIMER_HIGH_PRECISION -/* ~0.4% error - measured with stop-watch on 100s boot-delay */ -static inline unsigned long long tick_to_time(unsigned long long tick) -{ - tick *= CONFIG_SYS_HZ; - do_div(tick, CONFIG_MX27_CLK32); - return tick; -} - -static inline unsigned long long time_to_tick(unsigned long long time) -{ - time *= CONFIG_MX27_CLK32; - do_div(time, CONFIG_SYS_HZ); - return time; -} - -static inline unsigned long long us_to_tick(unsigned long long us) -{ - us = us * CONFIG_MX27_CLK32 + 999999; - do_div(us, 1000000); - return us; -} -#else -/* ~2% error */ -#define TICK_PER_TIME ((CONFIG_MX27_CLK32 + CONFIG_SYS_HZ / 2) / \ - CONFIG_SYS_HZ) -#define US_PER_TICK (1000000 / CONFIG_MX27_CLK32) - -static inline unsigned long long tick_to_time(unsigned long long tick) -{ - do_div(tick, TICK_PER_TIME); - return tick; -} - -static inline unsigned long long time_to_tick(unsigned long long time) -{ - return time * TICK_PER_TIME; -} - -static inline unsigned long long us_to_tick(unsigned long long us) -{ - us += US_PER_TICK - 1; - do_div(us, US_PER_TICK); - return us; -} -#endif - -/* nothing really to do with interrupts, just starts up a counter. */ -/* The 32768Hz 32-bit timer overruns in 131072 seconds */ -int timer_init(void) -{ - int i; - struct gpt_regs *regs = (struct gpt_regs *)IMX_TIM1_BASE; - struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; - - /* setup GP Timer 1 */ - writel(GPTCR_SWR, ®s->gpt_tctl); - - writel(readl(&pll->pccr0) | PCCR0_GPT1_EN, &pll->pccr0); - writel(readl(&pll->pccr1) | PCCR1_PERCLK1_EN, &pll->pccr1); - - for (i = 0; i < 100; i++) - writel(0, ®s->gpt_tctl); /* We have no udelay by now */ - writel(0, ®s->gpt_tprer); /* 32Khz */ - /* Freerun Mode, PERCLK1 input */ - writel(readl(®s->gpt_tctl) | GPTCR_CLKSOURCE_32 | GPTCR_FRR, - ®s->gpt_tctl); - writel(readl(®s->gpt_tctl) | GPTCR_TEN, ®s->gpt_tctl); - - return 0; -} - -void reset_timer_masked(void) -{ - struct gpt_regs *regs = (struct gpt_regs *)IMX_TIM1_BASE; - /* reset time */ - /* capture current incrementer value time */ - lastinc = readl(®s->gpt_tcn); - timestamp = 0; /* start "advancing" time stamp from 0 */ -} - -void reset_timer(void) -{ - reset_timer_masked(); -} - -unsigned long long get_ticks (void) -{ - struct gpt_regs *regs = (struct gpt_regs *)IMX_TIM1_BASE; - ulong now = readl(®s->gpt_tcn); /* current tick value */ - - if (now >= lastinc) { - /* - * normal mode (non roll) - * move stamp forward with absolut diff ticks - */ - timestamp += (now - lastinc); - } else { - /* we have rollover of incrementer */ - timestamp += (0xFFFFFFFF - lastinc) + now; - } - lastinc = now; - return timestamp; -} - -ulong get_timer_masked (void) -{ - /* - * get_ticks() returns a long long (64 bit), it wraps in - * 2^64 / CONFIG_MX27_CLK32 = 2^64 / 2^15 = 2^49 ~ 5 * 10^14 (s) ~ - * 5 * 10^9 days... and get_ticks() * CONFIG_SYS_HZ wraps in - * 5 * 10^6 days - long enough. - */ - return tick_to_time(get_ticks()); -} - -ulong get_timer (ulong base) -{ - return get_timer_masked () - base; -} - -void set_timer (ulong t) -{ - timestamp = time_to_tick(t); -} - -/* delay x useconds AND preserve advance timstamp value */ -void __udelay (unsigned long usec) -{ - unsigned long long tmp; - ulong tmo; - - tmo = us_to_tick(usec); - tmp = get_ticks() + tmo; /* get current timestamp */ - - while (get_ticks() < tmp) /* loop till event */ - /*NOP*/; -} diff --git a/cpu/arm926ejs/nomadik/Makefile b/cpu/arm926ejs/nomadik/Makefile deleted file mode 100644 index 0fc9f2a4c1..0000000000 --- a/cpu/arm926ejs/nomadik/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(SOC).a - -COBJS = timer.o gpio.o -SOBJS = reset.o - -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS)) $(addprefix $(obj),$(SOBJS)) - -all: $(obj).depend $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/arm926ejs/nomadik/gpio.c b/cpu/arm926ejs/nomadik/gpio.c deleted file mode 100644 index 62a375b5b5..0000000000 --- a/cpu/arm926ejs/nomadik/gpio.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * (C) Copyright 2009 Alessandro Rubini - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -static unsigned long gpio_base[4] = { - NOMADIK_GPIO0_BASE, - NOMADIK_GPIO1_BASE, - NOMADIK_GPIO2_BASE, - NOMADIK_GPIO3_BASE -}; - -enum gpio_registers { - GPIO_DAT = 0x00, /* data register */ - GPIO_DATS = 0x04, /* data set */ - GPIO_DATC = 0x08, /* data clear */ - GPIO_PDIS = 0x0c, /* pull disable */ - GPIO_DIR = 0x10, /* direction */ - GPIO_DIRS = 0x14, /* direction set */ - GPIO_DIRC = 0x18, /* direction clear */ - GPIO_AFSLA = 0x20, /* alternate function select A */ - GPIO_AFSLB = 0x24, /* alternate function select B */ -}; - -static inline unsigned long gpio_to_base(int gpio) -{ - return gpio_base[gpio / 32]; -} - -static inline u32 gpio_to_bit(int gpio) -{ - return 1 << (gpio & 0x1f); -} - -void nmk_gpio_af(int gpio, int alternate_function) -{ - unsigned long base = gpio_to_base(gpio); - u32 bit = gpio_to_bit(gpio); - u32 afunc, bfunc; - - /* alternate function is 0..3, with one bit per register */ - afunc = readl(base + GPIO_AFSLA) & ~bit; - bfunc = readl(base + GPIO_AFSLB) & ~bit; - if (alternate_function & 1) afunc |= bit; - if (alternate_function & 2) bfunc |= bit; - writel(afunc, base + GPIO_AFSLA); - writel(bfunc, base + GPIO_AFSLB); -} - -void nmk_gpio_dir(int gpio, int dir) -{ - unsigned long base = gpio_to_base(gpio); - u32 bit = gpio_to_bit(gpio); - - if (dir) - writel(bit, base + GPIO_DIRS); - else - writel(bit, base + GPIO_DIRC); -} - -void nmk_gpio_set(int gpio, int val) -{ - unsigned long base = gpio_to_base(gpio); - u32 bit = gpio_to_bit(gpio); - - if (val) - writel(bit, base + GPIO_DATS); - else - writel(bit, base + GPIO_DATC); -} - -int nmk_gpio_get(int gpio) -{ - unsigned long base = gpio_to_base(gpio); - u32 bit = gpio_to_bit(gpio); - - return readl(base + GPIO_DAT) & bit; -} diff --git a/cpu/arm926ejs/nomadik/reset.S b/cpu/arm926ejs/nomadik/reset.S deleted file mode 100644 index ec954726ae..0000000000 --- a/cpu/arm926ejs/nomadik/reset.S +++ /dev/null @@ -1,14 +0,0 @@ -#include -/* - * Processor reset for Nomadik - */ - - .align 5 -.globl reset_cpu -reset_cpu: - ldr r0, =NOMADIK_SRC_BASE /* System and Reset Controller */ - ldr r1, =0x1 - str r1, [r0, #0x18] - -_loop_forever: - b _loop_forever diff --git a/cpu/arm926ejs/nomadik/timer.c b/cpu/arm926ejs/nomadik/timer.c deleted file mode 100644 index 1d98ef3eb3..0000000000 --- a/cpu/arm926ejs/nomadik/timer.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * (C) Copyright 2009 Alessandro Rubini - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -/* - * The timer is a decrementer, we'll left it free running at 2.4MHz. - * We have 2.4 ticks per microsecond and an overflow in almost 30min - */ -#define TIMER_CLOCK (24 * 100 * 1000) -#define COUNT_TO_USEC(x) ((x) * 5 / 12) /* overflows at 6min */ -#define USEC_TO_COUNT(x) ((x) * 12 / 5) /* overflows at 6min */ -#define TICKS_PER_HZ (TIMER_CLOCK / CONFIG_SYS_HZ) -#define TICKS_TO_HZ(x) ((x) / TICKS_PER_HZ) - -/* macro to read the decrementing 32 bit timer as an increasing count */ -#define READ_TIMER() (0 - readl(CONFIG_SYS_TIMERBASE + MTU_VAL(0))) - -/* Configure a free-running, auto-wrap counter with no prescaler */ -int timer_init(void) -{ - writel(MTU_CRn_ENA | MTU_CRn_PRESCALE_1 | MTU_CRn_32BITS, - CONFIG_SYS_TIMERBASE + MTU_CR(0)); - reset_timer(); - return 0; -} - -/* Restart counting from 0 */ -void reset_timer(void) -{ - ulong val; - writel(0, CONFIG_SYS_TIMERBASE + MTU_LR(0)); - /* - * The load-register isn't really immediate: it changes on clock - * edges, so we must wait for our newly-written value to appear. - * Since we might miss reading 0, wait for any change in value. - */ - val = READ_TIMER(); - while (READ_TIMER() == val) - ; -} - -/* Return how many HZ passed since "base" */ -ulong get_timer(ulong base) -{ - return TICKS_TO_HZ(READ_TIMER()) - base; -} - -/* Delay x useconds */ -void __udelay(unsigned long usec) -{ - ulong ini, end; - - ini = READ_TIMER(); - end = ini + USEC_TO_COUNT(usec); - while ((signed)(end - READ_TIMER()) > 0) - ; -} diff --git a/cpu/arm926ejs/omap/Makefile b/cpu/arm926ejs/omap/Makefile deleted file mode 100644 index 74aea74189..0000000000 --- a/cpu/arm926ejs/omap/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(SOC).a - -COBJS = timer.o cpuinfo.o -SOBJS = reset.o - -SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) -START := $(addprefix $(obj),$(START)) - -all: $(obj).depend $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/arm926ejs/omap/cpuinfo.c b/cpu/arm926ejs/omap/cpuinfo.c deleted file mode 100644 index 0052daba8e..0000000000 --- a/cpu/arm926ejs/omap/cpuinfo.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * OMAP1 CPU identification code - * - * Copyright (C) 2004 Nokia Corporation - * Written by Tony Lindgren - * - * 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. - */ - -#include -#include - -#if defined(CONFIG_DISPLAY_CPUINFO) && defined(CONFIG_OMAP) - -#define omap_readw(x) *(volatile unsigned short *)(x) -#define omap_readl(x) *(volatile unsigned long *)(x) - -#define OMAP_DIE_ID_0 0xfffe1800 -#define OMAP_DIE_ID_1 0xfffe1804 -#define OMAP_PRODUCTION_ID_0 0xfffe2000 -#define OMAP_PRODUCTION_ID_1 0xfffe2004 -#define OMAP32_ID_0 0xfffed400 -#define OMAP32_ID_1 0xfffed404 - -struct omap_id { - u16 jtag_id; /* Used to determine OMAP type */ - u8 die_rev; /* Processor revision */ - u32 omap_id; /* OMAP revision */ - u32 type; /* Cpu id bits [31:08], cpu class bits [07:00] */ -}; - -/* Register values to detect the OMAP version */ -static struct omap_id omap_ids[] = { - { .jtag_id = 0xb574, .die_rev = 0x2, .omap_id = 0x03310315, .type = 0x03100000}, - { .jtag_id = 0x355f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300100}, - { .jtag_id = 0xb55f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300300}, - { .jtag_id = 0xb470, .die_rev = 0x0, .omap_id = 0x03310100, .type = 0x15100000}, - { .jtag_id = 0xb576, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x16100000}, - { .jtag_id = 0xb576, .die_rev = 0x2, .omap_id = 0x03320100, .type = 0x16110000}, - { .jtag_id = 0xb576, .die_rev = 0x3, .omap_id = 0x03320100, .type = 0x16100c00}, - { .jtag_id = 0xb576, .die_rev = 0x0, .omap_id = 0x03320200, .type = 0x16100d00}, - { .jtag_id = 0xb613, .die_rev = 0x0, .omap_id = 0x03320300, .type = 0x1610ef00}, - { .jtag_id = 0xb613, .die_rev = 0x0, .omap_id = 0x03320300, .type = 0x1610ef00}, - { .jtag_id = 0xb576, .die_rev = 0x1, .omap_id = 0x03320100, .type = 0x16110000}, - { .jtag_id = 0xb58c, .die_rev = 0x2, .omap_id = 0x03320200, .type = 0x16110b00}, - { .jtag_id = 0xb58c, .die_rev = 0x3, .omap_id = 0x03320200, .type = 0x16110c00}, - { .jtag_id = 0xb65f, .die_rev = 0x0, .omap_id = 0x03320400, .type = 0x16212300}, - { .jtag_id = 0xb65f, .die_rev = 0x1, .omap_id = 0x03320400, .type = 0x16212300}, - { .jtag_id = 0xb65f, .die_rev = 0x1, .omap_id = 0x03320500, .type = 0x16212300}, - { .jtag_id = 0xb5f7, .die_rev = 0x0, .omap_id = 0x03330000, .type = 0x17100000}, - { .jtag_id = 0xb5f7, .die_rev = 0x1, .omap_id = 0x03330100, .type = 0x17100000}, - { .jtag_id = 0xb5f7, .die_rev = 0x2, .omap_id = 0x03330100, .type = 0x17100000}, -}; - -/* - * Get OMAP type from PROD_ID. - * 1710 has the PROD_ID in bits 15:00, not in 16:01 as documented in TRM. - * 1510 PROD_ID is empty, and 1610 PROD_ID does not make sense. - * Undocumented register in TEST BLOCK is used as fallback; This seems to - * work on 1510, 1610 & 1710. The official way hopefully will work in future - * processors. - */ -static u16 omap_get_jtag_id(void) -{ - u32 prod_id, omap_id; - - prod_id = omap_readl(OMAP_PRODUCTION_ID_1); - omap_id = omap_readl(OMAP32_ID_1); - - /* Check for unusable OMAP_PRODUCTION_ID_1 on 1611B/5912 and 730 */ - if (((prod_id >> 20) == 0) || (prod_id == omap_id)) - prod_id = 0; - else - prod_id &= 0xffff; - - if (prod_id) - return prod_id; - - /* Use OMAP32_ID_1 as fallback */ - prod_id = ((omap_id >> 12) & 0xffff); - - return prod_id; -} - -/* - * Get OMAP revision from DIE_REV. - * Early 1710 processors may have broken OMAP_DIE_ID, it contains PROD_ID. - * Undocumented register in the TEST BLOCK is used as fallback. - * REVISIT: This does not seem to work on 1510 - */ -static u8 omap_get_die_rev(void) -{ - u32 die_rev; - - die_rev = omap_readl(OMAP_DIE_ID_1); - - /* Check for broken OMAP_DIE_ID on early 1710 */ - if (((die_rev >> 12) & 0xffff) == omap_get_jtag_id()) - die_rev = 0; - - die_rev = (die_rev >> 17) & 0xf; - if (die_rev) - return die_rev; - - die_rev = (omap_readl(OMAP32_ID_1) >> 28) & 0xf; - - return die_rev; -} - -static unsigned long dpll1(void) -{ - unsigned short pll_ctl_val = omap_readw(DPLL_CTL_REG); - unsigned long rate; - - rate = CONFIG_SYS_CLK_FREQ; /* Base xtal rate */ - if (pll_ctl_val & 0x10) { - /* PLL enabled, apply multiplier and divisor */ - if (pll_ctl_val & 0xf80) - rate *= (pll_ctl_val & 0xf80) >> 7; - rate /= ((pll_ctl_val & 0x60) >> 5) + 1; - } else { - /* PLL disabled, apply bypass divisor */ - switch (pll_ctl_val & 0xc) { - case 0: - break; - case 0x4: - rate /= 2; - break; - default: - rate /= 4; - break; - } - } - - return rate; -} - -static unsigned long armcore(void) -{ - unsigned short arm_ckctl = omap_readw(ARM_CKCTL); - - return (dpll1() >> ((arm_ckctl & 0x0030) >> 4)); -} - -int print_cpuinfo (void) -{ - int i; - u16 jtag_id; - u8 die_rev; - u32 omap_id; - u8 cpu_type; - u32 system_serial_high; - u32 system_serial_low; - u32 system_rev = 0; - - jtag_id = omap_get_jtag_id(); - die_rev = omap_get_die_rev(); - omap_id = omap_readl(OMAP32_ID_0); - -#ifdef DEBUG - printf("OMAP_DIE_ID_0: 0x%08x\n", omap_readl(OMAP_DIE_ID_0)); - printf("OMAP_DIE_ID_1: 0x%08x DIE_REV: %i\n", - omap_readl(OMAP_DIE_ID_1), - (omap_readl(OMAP_DIE_ID_1) >> 17) & 0xf); - printf("OMAP_PRODUCTION_ID_0: 0x%08x\n", omap_readl(OMAP_PRODUCTION_ID_0)); - printf("OMAP_PRODUCTION_ID_1: 0x%08x JTAG_ID: 0x%04x\n", - omap_readl(OMAP_PRODUCTION_ID_1), - omap_readl(OMAP_PRODUCTION_ID_1) & 0xffff); - printf("OMAP32_ID_0: 0x%08x\n", omap_readl(OMAP32_ID_0)); - printf("OMAP32_ID_1: 0x%08x\n", omap_readl(OMAP32_ID_1)); - printf("JTAG_ID: 0x%04x DIE_REV: %i\n", jtag_id, die_rev); -#endif - - system_serial_high = omap_readl(OMAP_DIE_ID_0); - system_serial_low = omap_readl(OMAP_DIE_ID_1); - - /* First check only the major version in a safe way */ - for (i = 0; i < ARRAY_SIZE(omap_ids); i++) { - if (jtag_id == (omap_ids[i].jtag_id)) { - system_rev = omap_ids[i].type; - break; - } - } - - /* Check if we can find the die revision */ - for (i = 0; i < ARRAY_SIZE(omap_ids); i++) { - if (jtag_id == omap_ids[i].jtag_id && die_rev == omap_ids[i].die_rev) { - system_rev = omap_ids[i].type; - break; - } - } - - /* Finally check also the omap_id */ - for (i = 0; i < ARRAY_SIZE(omap_ids); i++) { - if (jtag_id == omap_ids[i].jtag_id - && die_rev == omap_ids[i].die_rev - && omap_id == omap_ids[i].omap_id) { - system_rev = omap_ids[i].type; - break; - } - } - - /* Add the cpu class info (7xx, 15xx, 16xx, 24xx) */ - cpu_type = system_rev >> 24; - - switch (cpu_type) { - case 0x07: - system_rev |= 0x07; - break; - case 0x03: - case 0x15: - system_rev |= 0x15; - break; - case 0x16: - case 0x17: - system_rev |= 0x16; - break; - case 0x24: - system_rev |= 0x24; - break; - default: - printf("Unknown OMAP cpu type: 0x%02x\n", cpu_type); - } - - printf("CPU: OMAP%04x", system_rev >> 16); - if ((system_rev >> 8) & 0xff) - printf("%x", (system_rev >> 8) & 0xff); -#ifdef DEBUG - printf(" revision %i handled as %02xxx id: %08x%08x", - die_rev, system_rev & 0xff, system_serial_low, system_serial_high); -#endif - printf(" at %ld.%01ld MHz (DPLL1=%ld.%01ld MHz)\n", - armcore() / 1000000, (armcore() / 100000) % 10, - dpll1() / 1000000, (dpll1() / 100000) % 10); - - return 0; -} - -#endif /* #if defined(CONFIG_DISPLAY_CPUINFO) && defined(CONFIG_OMAP) */ diff --git a/cpu/arm926ejs/omap/reset.S b/cpu/arm926ejs/omap/reset.S deleted file mode 100644 index 4b20756d1b..0000000000 --- a/cpu/arm926ejs/omap/reset.S +++ /dev/null @@ -1,45 +0,0 @@ -/* - * armboot - Startup Code for ARM926EJS CPU-core - * - * Copyright (c) 2003 Texas Instruments - * - * ----- Adapted for OMAP1610 OMAP730 from ARM925t code ------ - * - * Copyright (c) 2001 Marius Gröger - * Copyright (c) 2002 Alex Züpke - * Copyright (c) 2002 Gary Jennejohn - * Copyright (c) 2003 Richard Woodruff - * Copyright (c) 2003 Kshitij - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - - .align 5 -.globl reset_cpu -reset_cpu: - ldr r1, rstctl1 /* get clkm1 reset ctl */ - mov r3, #0x0 - strh r3, [r1] /* clear it */ - mov r3, #0x8 - strh r3, [r1] /* force dsp+arm reset */ -_loop_forever: - b _loop_forever - -rstctl1: - .word 0xfffece10 diff --git a/cpu/arm926ejs/omap/timer.c b/cpu/arm926ejs/omap/timer.c deleted file mode 100644 index 2ac38c40b7..0000000000 --- a/cpu/arm926ejs/omap/timer.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * (C) Copyright 2003 - * Texas Instruments - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * (C) Copyright 2002-2004 - * Gary Jennejohn, DENX Software Engineering, - * - * (C) Copyright 2004 - * Philippe Robin, ARM Ltd. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include - -#define TIMER_LOAD_VAL 0xffffffff - -/* macro to read the 32 bit timer */ -#define READ_TIMER (*(volatile ulong *)(CONFIG_SYS_TIMERBASE+8)) - -static ulong timestamp; -static ulong lastdec; - -int timer_init (void) -{ - int32_t val; - - /* Start the decrementer ticking down from 0xffffffff */ - *((int32_t *) (CONFIG_SYS_TIMERBASE + LOAD_TIM)) = TIMER_LOAD_VAL; - val = MPUTIM_ST | MPUTIM_AR | MPUTIM_CLOCK_ENABLE | (CONFIG_SYS_PTV << MPUTIM_PTV_BIT); - *((int32_t *) (CONFIG_SYS_TIMERBASE + CNTL_TIMER)) = val; - - /* init the timestamp and lastdec value */ - reset_timer_masked(); - - return 0; -} - -/* - * timer without interrupts - */ - -void reset_timer (void) -{ - reset_timer_masked (); -} - -ulong get_timer (ulong base) -{ - return get_timer_masked () - base; -} - -void set_timer (ulong t) -{ - timestamp = t; -} - -/* delay x useconds AND perserve advance timstamp value */ -void __udelay (unsigned long usec) -{ - ulong tmo, tmp; - - if(usec >= 1000){ /* if "big" number, spread normalization to seconds */ - tmo = usec / 1000; /* start to normalize for usec to ticks per sec */ - tmo *= CONFIG_SYS_HZ; /* find number of "ticks" to wait to achieve target */ - tmo /= 1000; /* finish normalize. */ - }else{ /* else small number, don't kill it prior to HZ multiply */ - tmo = usec * CONFIG_SYS_HZ; - tmo /= (1000*1000); - } - - tmp = get_timer (0); /* get current timestamp */ - if( (tmo + tmp + 1) < tmp ) /* if setting this fordward will roll time stamp */ - reset_timer_masked (); /* reset "advancing" timestamp to 0, set lastdec value */ - else - tmo += tmp; /* else, set advancing stamp wake up time */ - - while (get_timer_masked () < tmo)/* loop till event */ - /*NOP*/; -} - -void reset_timer_masked (void) -{ - /* reset time */ - lastdec = READ_TIMER; /* capure current decrementer value time */ - timestamp = 0; /* start "advancing" time stamp from 0 */ -} - -ulong get_timer_masked (void) -{ - ulong now = READ_TIMER; /* current tick value */ - - if (lastdec >= now) { /* normal mode (non roll) */ - /* normal mode */ - timestamp += lastdec - now; /* move stamp fordward with absoulte diff ticks */ - } else { /* we have overflow of the count down timer */ - /* nts = ts + ld + (TLV - now) - * ts=old stamp, ld=time that passed before passing through -1 - * (TLV-now) amount of time after passing though -1 - * nts = new "advancing time stamp"...it could also roll and cause problems. - */ - timestamp += lastdec + TIMER_LOAD_VAL - now; - } - lastdec = now; - - return timestamp; -} - -/* waits specified delay value and resets timestamp */ -void udelay_masked (unsigned long usec) -{ - ulong tmo; - ulong endtime; - signed long diff; - - if (usec >= 1000) { /* if "big" number, spread normalization to seconds */ - tmo = usec / 1000; /* start to normalize for usec to ticks per sec */ - tmo *= CONFIG_SYS_HZ; /* find number of "ticks" to wait to achieve target */ - tmo /= 1000; /* finish normalize. */ - } else { /* else small number, don't kill it prior to HZ multiply */ - tmo = usec * CONFIG_SYS_HZ; - tmo /= (1000*1000); - } - - endtime = get_timer_masked () + tmo; - - do { - ulong now = get_timer_masked (); - diff = endtime - now; - } while (diff >= 0); -} - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return get_timer(0); -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk (void) -{ - ulong tbclk; - - tbclk = CONFIG_SYS_HZ; - return tbclk; -} diff --git a/cpu/arm926ejs/spear/Makefile b/cpu/arm926ejs/spear/Makefile deleted file mode 100644 index bf8dfa8c3c..0000000000 --- a/cpu/arm926ejs/spear/Makefile +++ /dev/null @@ -1,52 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(SOC).a - -COBJS := reset.o \ - timer.o -SOBJS := - -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS)) -SOBJS := $(addprefix $(obj),$(SOBJS)) - -$(LIB): $(obj).depend $(OBJS) $(SOBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS) - -clean: - rm -f $(SOBJS) $(OBJS) - -distclean: clean - rm -f $(LIB) core *.bak $(obj).depend - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/arm926ejs/spear/reset.c b/cpu/arm926ejs/spear/reset.c deleted file mode 100644 index 73ad86da30..0000000000 --- a/cpu/arm926ejs/spear/reset.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * (C) Copyright 2009 - * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include - -void reset_cpu(ulong ignored) -{ - struct syscntl_regs *syscntl_regs_p = - (struct syscntl_regs *)CONFIG_SPEAR_SYSCNTLBASE; - - printf("System is going to reboot ...\n"); - - /* - * This 1 second delay will allow the above message - * to be printed before reset - */ - udelay((1000 * 1000)); - - /* Going into slow mode before resetting SOC */ - writel(0x02, &syscntl_regs_p->scctrl); - - /* - * Writing any value to the system status register will - * reset the SoC - */ - writel(0x00, &syscntl_regs_p->scsysstat); - - /* system will restart */ - while (1) - ; -} diff --git a/cpu/arm926ejs/spear/timer.c b/cpu/arm926ejs/spear/timer.c deleted file mode 100644 index 06858b4a13..0000000000 --- a/cpu/arm926ejs/spear/timer.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * (C) Copyright 2009 - * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include - -#define GPT_RESOLUTION (CONFIG_SPEAR_HZ_CLOCK / CONFIG_SPEAR_HZ) -#define READ_TIMER() (readl(&gpt_regs_p->count) & GPT_FREE_RUNNING) - -static struct gpt_regs *const gpt_regs_p = - (struct gpt_regs *)CONFIG_SPEAR_TIMERBASE; - -static struct misc_regs *const misc_regs_p = - (struct misc_regs *)CONFIG_SPEAR_MISCBASE; - -static ulong timestamp; -static ulong lastdec; - -int timer_init(void) -{ - u32 synth; - - /* Prescaler setting */ -#if defined(CONFIG_SPEAR3XX) - writel(MISC_PRSC_CFG, &misc_regs_p->prsc2_clk_cfg); - synth = MISC_GPT4SYNTH; -#elif defined(CONFIG_SPEAR600) - writel(MISC_PRSC_CFG, &misc_regs_p->prsc1_clk_cfg); - synth = MISC_GPT3SYNTH; -#else -# error Incorrect config. Can only be spear{600|300|310|320} -#endif - - writel(readl(&misc_regs_p->periph_clk_cfg) | synth, - &misc_regs_p->periph_clk_cfg); - - /* disable timers */ - writel(GPT_PRESCALER_1 | GPT_MODE_AUTO_RELOAD, &gpt_regs_p->control); - - /* load value for free running */ - writel(GPT_FREE_RUNNING, &gpt_regs_p->compare); - - /* auto reload, start timer */ - writel(readl(&gpt_regs_p->control) | GPT_ENABLE, &gpt_regs_p->control); - - reset_timer_masked(); - - return 0; -} - -/* - * timer without interrupts - */ - -void reset_timer(void) -{ - reset_timer_masked(); -} - -ulong get_timer(ulong base) -{ - return (get_timer_masked() / GPT_RESOLUTION) - base; -} - -void set_timer(ulong t) -{ - timestamp = t; -} - -void __udelay(unsigned long usec) -{ - ulong tmo; - ulong start = get_timer_masked(); - ulong tenudelcnt = CONFIG_SPEAR_HZ_CLOCK / (1000 * 100); - ulong rndoff; - - rndoff = (usec % 10) ? 1 : 0; - - /* tenudelcnt timer tick gives 10 microsecconds delay */ - tmo = ((usec / 10) + rndoff) * tenudelcnt; - - while ((ulong) (get_timer_masked() - start) < tmo) - ; -} - -void reset_timer_masked(void) -{ - /* reset time */ - lastdec = READ_TIMER(); - timestamp = 0; -} - -ulong get_timer_masked(void) -{ - ulong now = READ_TIMER(); - - if (now >= lastdec) { - /* normal mode */ - timestamp += now - lastdec; - } else { - /* we have an overflow ... */ - timestamp += now + GPT_FREE_RUNNING - lastdec; - } - lastdec = now; - - return timestamp; -} - -void udelay_masked(unsigned long usec) -{ - return udelay(usec); -} - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return get_timer(0); -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk(void) -{ - return CONFIG_SPEAR_HZ; -} diff --git a/cpu/arm926ejs/start.S b/cpu/arm926ejs/start.S deleted file mode 100644 index 3b81151f49..0000000000 --- a/cpu/arm926ejs/start.S +++ /dev/null @@ -1,440 +0,0 @@ -/* - * armboot - Startup Code for ARM926EJS CPU-core - * - * Copyright (c) 2003 Texas Instruments - * - * ----- Adapted for OMAP1610 OMAP730 from ARM925t code ------ - * - * Copyright (c) 2001 Marius Gröger - * Copyright (c) 2002 Alex Züpke - * Copyright (c) 2002 Gary Jennejohn - * Copyright (c) 2003 Richard Woodruff - * Copyright (c) 2003 Kshitij - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - - -#include -#include -#include - -#if defined(CONFIG_OMAP1610) -#include <./configs/omap1510.h> -#elif defined(CONFIG_OMAP730) -#include <./configs/omap730.h> -#endif - -/* - ************************************************************************* - * - * Jump vector table as in table 3.1 in [1] - * - ************************************************************************* - */ - - -.globl _start -_start: - b reset -#ifdef CONFIG_PRELOADER -/* No exception handlers in preloader */ - ldr pc, _hang - ldr pc, _hang - ldr pc, _hang - ldr pc, _hang - ldr pc, _hang - ldr pc, _hang - ldr pc, _hang - -_hang: - .word do_hang -/* pad to 64 byte boundary */ - .word 0x12345678 - .word 0x12345678 - .word 0x12345678 - .word 0x12345678 - .word 0x12345678 - .word 0x12345678 - .word 0x12345678 -#else - 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 - -_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 - -#endif /* CONFIG_PRELOADER */ - .balignl 16,0xdeadbeef - - -/* - ************************************************************************* - * - * Startup Code (reset vector) - * - * do important init only if we don't start from memory! - * setup Memory and board specific bits prior to relocation. - * relocate armboot to ram - * setup stack - * - ************************************************************************* - */ - -_TEXT_BASE: - .word TEXT_BASE - -.globl _armboot_start -_armboot_start: - .word _start - -/* - * These are defined in the board-specific linker script. - */ -.globl _bss_start -_bss_start: - .word __bss_start - -.globl _bss_end -_bss_end: - .word _end - -#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 - - -/* - * the actual reset code - */ - -reset: - /* - * set the cpu to SVC32 mode - */ - mrs r0,cpsr - bic r0,r0,#0x1f - orr r0,r0,#0xd3 - msr cpsr,r0 - - /* - * we do sys-critical inits only at reboot, - * not when booting from ram! - */ -#ifndef CONFIG_SKIP_LOWLEVEL_INIT - bl cpu_init_crit -#endif - -#ifndef CONFIG_SKIP_RELOCATE_UBOOT -relocate: /* relocate U-Boot to RAM */ - adr r0, _start /* r0 <- current position of code */ - ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ - cmp r0, r1 /* don't reloc during debug */ - beq stack_setup - ldr r2, _armboot_start - ldr r3, _bss_start - sub r2, r3, r2 /* r2 <- size of armboot */ - add r2, r0, r2 /* r2 <- source end address */ - -copy_loop: - ldmia r0!, {r3-r10} /* copy from source address [r0] */ - stmia r1!, {r3-r10} /* copy to target address [r1] */ - cmp r0, r2 /* until source end addreee [r2] */ - ble copy_loop -#endif /* CONFIG_SKIP_RELOCATE_UBOOT */ - - /* Set up the stack */ -stack_setup: - ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ - sub sp, r0, #128 /* leave 32 words for abort-stack */ -#ifndef CONFIG_PRELOADER - sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */ - sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ -#ifdef CONFIG_USE_IRQ - sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) -#endif -#endif /* CONFIG_PRELOADER */ - sub sp, r0, #12 /* leave 3 words for abort-stack */ - bic sp, r0, #7 /* 8-byte align stack for ABI compliance */ - -clear_bss: - ldr r0, _bss_start /* find start of bss segment */ - ldr r1, _bss_end /* stop here */ - mov r2, #0x00000000 /* clear */ - -#ifndef CONFIG_PRELOADER -clbss_l:str r2, [r0] /* clear loop... */ - add r0, r0, #4 - cmp r0, r1 - ble clbss_l - - bl coloured_LED_init - bl red_LED_on -#endif /* CONFIG_PRELOADER */ - - ldr pc, _start_armboot - -_start_armboot: -#ifdef CONFIG_NAND_SPL - .word nand_boot -#else - .word start_armboot -#endif /* CONFIG_NAND_SPL */ - - -/* - ************************************************************************* - * - * CPU_init_critical registers - * - * setup important registers - * setup memory timing - * - ************************************************************************* - */ -#ifndef CONFIG_SKIP_LOWLEVEL_INIT -cpu_init_crit: - /* - * flush v4 I/D caches - */ - mov r0, #0 - mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ - mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ - - /* - * disable MMU stuff and caches - */ - mrc p15, 0, r0, c1, c0, 0 - bic r0, r0, #0x00002300 /* clear bits 13, 9:8 (--V- --RS) */ - bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */ - orr r0, r0, #0x00000002 /* set bit 2 (A) Align */ - orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */ - mcr p15, 0, r0, c1, c0, 0 - - /* - * Go setup Memory and board specific bits prior to relocation. - */ - mov ip, lr /* perserve link reg across call */ - bl lowlevel_init /* go setup pll,mux,memory */ - mov lr, ip /* restore link */ - mov pc, lr /* back to my caller */ -#endif /* CONFIG_SKIP_LOWLEVEL_INIT */ - -#ifndef CONFIG_PRELOADER -/* - ************************************************************************* - * - * 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 -#define I_BIT 0x80 - -/* - * use bad_save_user_regs for abort/prefetch/undef/swi ... - * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling - */ - - .macro bad_save_user_regs - @ carve out a frame on current user stack - sub sp, sp, #S_FRAME_SIZE - stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12 - - ldr r2, _armboot_start - sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) - sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack - @ get values for "aborted" pc and cpsr (into parm regs) - ldmia r2, {r2 - r3} - add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack - add r5, sp, #S_SP - mov r1, lr - stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr - mov r0, sp @ save current stack into r0 (param register) - .endm - - .macro irq_save_user_regs - sub sp, sp, #S_FRAME_SIZE - stmia sp, {r0 - r12} @ Calling r0-r12 - @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good. - 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, _armboot_start @ setup our mode stack - sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) - sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack - - str lr, [r13] @ save caller lr in position 0 of saved stack - mrs lr, spsr @ get the spsr - str lr, [r13, #4] @ save spsr in position 1 of saved stack - mov r13, #MODE_SVC @ prepare SVC-Mode - @ msr spsr_c, r13 - msr spsr, r13 @ switch modes, make sure moves will execute - mov lr, pc @ capture return pc - movs pc, lr @ jump to next instruction & switch modes. - .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 -#endif /* CONFIG_PRELOADER */ - -/* - * exception handlers - */ -#ifdef CONFIG_PRELOADER - .align 5 -do_hang: - ldr sp, _TEXT_BASE /* switch to abort stack */ -1: - bl 1b /* hang and never return */ -#else /* !CONFIG_PRELOADER */ - .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 - /* someone ought to write a more effiction fiq_save_user_regs */ - irq_save_user_regs - bl do_fiq - 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 -#endif /* CONFIG_PRELOADER */ diff --git a/cpu/arm926ejs/u-boot.lds b/cpu/arm926ejs/u-boot.lds deleted file mode 100644 index ee5eeb590a..0000000000 --- a/cpu/arm926ejs/u-boot.lds +++ /dev/null @@ -1,56 +0,0 @@ -/* - * (C) Copyright 2002-2004 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -ENTRY(_start) -SECTIONS -{ - . = 0x00000000; - - . = ALIGN(4); - .text : - { - cpu/arm926ejs/start.o (.text) - *(.text) - } - - . = ALIGN(4); - .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } - - . = ALIGN(4); - .data : { *(.data) } - - . = ALIGN(4); - .got : { *(.got) } - - . = .; - __u_boot_cmd_start = .; - .u_boot_cmd : { *(.u_boot_cmd) } - __u_boot_cmd_end = .; - - . = ALIGN(4); - __bss_start = .; - .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } - _end = .; -} diff --git a/cpu/arm926ejs/versatile/Makefile b/cpu/arm926ejs/versatile/Makefile deleted file mode 100644 index c335d5c866..0000000000 --- a/cpu/arm926ejs/versatile/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(SOC).a - -COBJS = timer.o -SOBJS = reset.o - -SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) -START := $(addprefix $(obj),$(START)) - -all: $(obj).depend $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/arm926ejs/versatile/reset.S b/cpu/arm926ejs/versatile/reset.S deleted file mode 100644 index 4b20756d1b..0000000000 --- a/cpu/arm926ejs/versatile/reset.S +++ /dev/null @@ -1,45 +0,0 @@ -/* - * armboot - Startup Code for ARM926EJS CPU-core - * - * Copyright (c) 2003 Texas Instruments - * - * ----- Adapted for OMAP1610 OMAP730 from ARM925t code ------ - * - * Copyright (c) 2001 Marius Gröger - * Copyright (c) 2002 Alex Züpke - * Copyright (c) 2002 Gary Jennejohn - * Copyright (c) 2003 Richard Woodruff - * Copyright (c) 2003 Kshitij - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - - .align 5 -.globl reset_cpu -reset_cpu: - ldr r1, rstctl1 /* get clkm1 reset ctl */ - mov r3, #0x0 - strh r3, [r1] /* clear it */ - mov r3, #0x8 - strh r3, [r1] /* force dsp+arm reset */ -_loop_forever: - b _loop_forever - -rstctl1: - .word 0xfffece10 diff --git a/cpu/arm926ejs/versatile/timer.c b/cpu/arm926ejs/versatile/timer.c deleted file mode 100644 index 563db36548..0000000000 --- a/cpu/arm926ejs/versatile/timer.c +++ /dev/null @@ -1,205 +0,0 @@ -/* - * (C) Copyright 2003 - * Texas Instruments - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * (C) Copyright 2002-2004 - * Gary Jennejohn, DENX Software Engineering, - * - * (C) Copyright 2004 - * Philippe Robin, ARM Ltd. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include - -#define TIMER_LOAD_VAL 0xffffffff - -/* macro to read the 32 bit timer */ -#define READ_TIMER (*(volatile ulong *)(CONFIG_SYS_TIMERBASE+4)) - -static ulong timestamp; -static ulong lastdec; - -#define TIMER_ENABLE (1 << 7) -#define TIMER_MODE_MSK (1 << 6) -#define TIMER_MODE_FR (0 << 6) -#define TIMER_MODE_PD (1 << 6) - -#define TIMER_INT_EN (1 << 5) -#define TIMER_PRS_MSK (3 << 2) -#define TIMER_PRS_8S (1 << 3) -#define TIMER_SIZE_MSK (1 << 2) -#define TIMER_ONE_SHT (1 << 0) - -int timer_init (void) -{ - ulong tmr_ctrl_val; - - /* 1st disable the Timer */ - tmr_ctrl_val = *(volatile ulong *)(CONFIG_SYS_TIMERBASE + 8); - tmr_ctrl_val &= ~TIMER_ENABLE; - *(volatile ulong *)(CONFIG_SYS_TIMERBASE + 8) = tmr_ctrl_val; - - /* - * The Timer Control Register has one Undefined/Shouldn't Use Bit - * So we should do read/modify/write Operation - */ - - /* - * Timer Mode : Free Running - * Interrupt : Disabled - * Prescale : 8 Stage, Clk/256 - * Tmr Siz : 16 Bit Counter - * Tmr in Wrapping Mode - */ - tmr_ctrl_val = *(volatile ulong *)(CONFIG_SYS_TIMERBASE + 8); - tmr_ctrl_val &= ~(TIMER_MODE_MSK | TIMER_INT_EN | TIMER_PRS_MSK | TIMER_SIZE_MSK | TIMER_ONE_SHT ); - tmr_ctrl_val |= (TIMER_ENABLE | TIMER_PRS_8S); - - *(volatile ulong *)(CONFIG_SYS_TIMERBASE + 8) = tmr_ctrl_val; - - /* init the timestamp and lastdec value */ - reset_timer_masked(); - - return 0; -} - -/* - * timer without interrupts - */ - -void reset_timer (void) -{ - reset_timer_masked (); -} - -ulong get_timer (ulong base) -{ - return get_timer_masked () - base; -} - -void set_timer (ulong t) -{ - timestamp = t; -} - -/* delay x useconds AND perserve advance timstamp value */ -void __udelay (unsigned long usec) -{ - ulong tmo, tmp; - - if(usec >= 1000){ /* if "big" number, spread normalization to seconds */ - tmo = usec / 1000; /* start to normalize for usec to ticks per sec */ - tmo *= CONFIG_SYS_HZ; /* find number of "ticks" to wait to achieve target */ - tmo /= 1000; /* finish normalize. */ - }else{ /* else small number, don't kill it prior to HZ multiply */ - tmo = usec * CONFIG_SYS_HZ; - tmo /= (1000*1000); - } - - tmp = get_timer (0); /* get current timestamp */ - if( (tmo + tmp + 1) < tmp ) /* if setting this fordward will roll time stamp */ - reset_timer_masked (); /* reset "advancing" timestamp to 0, set lastdec value */ - else - tmo += tmp; /* else, set advancing stamp wake up time */ - - while (get_timer_masked () < tmo)/* loop till event */ - /*NOP*/; -} - -void reset_timer_masked (void) -{ - /* reset time */ - lastdec = READ_TIMER; /* capure current decrementer value time */ - timestamp = 0; /* start "advancing" time stamp from 0 */ -} - -ulong get_timer_masked (void) -{ - ulong now = READ_TIMER; /* current tick value */ - - if (lastdec >= now) { /* normal mode (non roll) */ - /* normal mode */ - timestamp += lastdec - now; /* move stamp fordward with absoulte diff ticks */ - } else { /* we have overflow of the count down timer */ - /* nts = ts + ld + (TLV - now) - * ts=old stamp, ld=time that passed before passing through -1 - * (TLV-now) amount of time after passing though -1 - * nts = new "advancing time stamp"...it could also roll and cause problems. - */ - timestamp += lastdec + TIMER_LOAD_VAL - now; - } - lastdec = now; - - return timestamp; -} - -/* waits specified delay value and resets timestamp */ -void udelay_masked (unsigned long usec) -{ - ulong tmo; - ulong endtime; - signed long diff; - - if (usec >= 1000) { /* if "big" number, spread normalization to seconds */ - tmo = usec / 1000; /* start to normalize for usec to ticks per sec */ - tmo *= CONFIG_SYS_HZ; /* find number of "ticks" to wait to achieve target */ - tmo /= 1000; /* finish normalize. */ - } else { /* else small number, don't kill it prior to HZ multiply */ - tmo = usec * CONFIG_SYS_HZ; - tmo /= (1000*1000); - } - - endtime = get_timer_masked () + tmo; - - do { - ulong now = get_timer_masked (); - diff = endtime - now; - } while (diff >= 0); -} - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return get_timer(0); -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk (void) -{ - ulong tbclk; - - tbclk = CONFIG_SYS_HZ; - return tbclk; -} diff --git a/cpu/arm946es/Makefile b/cpu/arm946es/Makefile deleted file mode 100644 index e81f2da29d..0000000000 --- a/cpu/arm946es/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(CPU).a - -START = start.o - -COBJS = cpu.o - -SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) -START := $(addprefix $(obj),$(START)) - -all: $(obj).depend $(START) $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/arm946es/config.mk b/cpu/arm946es/config.mk deleted file mode 100644 index e783f697a1..0000000000 --- a/cpu/arm946es/config.mk +++ /dev/null @@ -1,32 +0,0 @@ -# -# (C) Copyright 2002 -# Gary Jennejohn, DENX Software Engineering, -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float - -PLATFORM_CPPFLAGS += -march=armv4 -# ========================================================================= -# -# Supply options according to compiler version -# -# ========================================================================= -PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/arm946es/cpu.c b/cpu/arm946es/cpu.c deleted file mode 100644 index c63c98be86..0000000000 --- a/cpu/arm946es/cpu.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * CPU specific code - */ - -#include -#include -#include - -static void cache_flush(void); - -int cleanup_before_linux (void) -{ - /* - * this function is called just before we call linux - * it prepares the processor for linux - * - * we turn off caches etc ... - */ - - disable_interrupts (); - - /* ARM926E-S needs the protection unit enabled for the icache to have - * been enabled - left for possible later use - * should turn off the protection unit as well.... - */ - /* turn off I/D-cache */ - icache_disable(); - dcache_disable(); - /* flush I/D-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)); - asm ("mcr p15, 0, %0, c7, c6, 0": :"r" (i)); -} diff --git a/cpu/arm946es/start.S b/cpu/arm946es/start.S deleted file mode 100644 index 627e3cb94d..0000000000 --- a/cpu/arm946es/start.S +++ /dev/null @@ -1,411 +0,0 @@ -/* - * armboot - Startup Code for ARM926EJS CPU-core - * - * Copyright (c) 2003 Texas Instruments - * - * ----- Adapted for OMAP1610 OMAP730 from ARM925t code ------ - * - * Copyright (c) 2001 Marius Gröger - * Copyright (c) 2002 Alex Züpke - * Copyright (c) 2002 Gary Jennejohn - * Copyright (c) 2003 Richard Woodruff - * Copyright (c) 2003 Kshitij - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - - -#include -#include - -/* - ************************************************************************* - * - * Jump vector table as in table 3.1 in [1] - * - ************************************************************************* - */ - - -.globl _start -_start: - b 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 - -_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! - * setup Memory and board specific bits prior to relocation. - * relocate armboot to ram - * setup stack - * - ************************************************************************* - */ - -_TEXT_BASE: - .word TEXT_BASE - -.globl _armboot_start -_armboot_start: - .word _start - -/* - * These are defined in the board-specific linker script. - */ -.globl _bss_start -_bss_start: - .word __bss_start - -.globl _bss_end -_bss_end: - .word _end - -#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 - - -/* - * the actual reset code - */ - -reset: - /* - * set the cpu to SVC32 mode - */ - mrs r0,cpsr - bic r0,r0,#0x1f - orr r0,r0,#0xd3 - msr cpsr,r0 - - /* - * we do sys-critical inits only at reboot, - * not when booting from ram! - */ -#ifndef CONFIG_SKIP_LOWLEVEL_INIT - bl cpu_init_crit -#endif - -relocate: /* relocate U-Boot to RAM */ - adr r0, _start /* r0 <- current position of code */ - ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ - cmp r0, r1 /* don't reloc during debug */ - beq stack_setup - - ldr r2, _armboot_start - ldr r3, _bss_start - sub r2, r3, r2 /* r2 <- size of armboot */ - add r2, r0, r2 /* r2 <- source end address */ - -copy_loop: - ldmia r0!, {r3-r10} /* copy from source address [r0] */ - stmia r1!, {r3-r10} /* copy to target address [r1] */ - cmp r0, r2 /* until source end addreee [r2] */ - ble copy_loop - - /* Set up the stack */ -stack_setup: - ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ - sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */ - sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ -#ifdef CONFIG_USE_IRQ - sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) -#endif - sub sp, r0, #12 /* leave 3 words for abort-stack */ - -clear_bss: - ldr r0, _bss_start /* find start of bss segment */ - ldr r1, _bss_end /* stop here */ - mov r2, #0x00000000 /* clear */ - -clbss_l:str r2, [r0] /* clear loop... */ - add r0, r0, #4 - cmp r0, r1 - bne clbss_l - - ldr pc, _start_armboot - -_start_armboot: - .word start_armboot - - -/* - ************************************************************************* - * - * CPU_init_critical registers - * - * setup important registers - * setup memory timing - * - ************************************************************************* - */ - - -#ifndef CONFIG_SKIP_LOWLEVEL_INIT -cpu_init_crit: - /* - * flush v4 I/D caches - */ - mov r0, #0 - mcr p15, 0, r0, c7, c5, 0 /* flush v4 I-cache */ - mcr p15, 0, r0, c7, c6, 0 /* flush v4 D-cache */ - - /* - * disable MMU stuff and caches - */ - mrc p15, 0, r0, c1, c0, 0 - bic r0, r0, #0x00002300 /* clear bits 13, 9:8 (--V- --RS) */ - bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */ - orr r0, r0, #0x00000002 /* set bit 2 (A) Align */ - orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */ - mcr p15, 0, r0, c1, c0, 0 - - /* - * Go setup Memory and board specific bits prior to relocation. - */ - mov ip, lr /* perserve link reg across call */ - bl lowlevel_init /* go setup memory */ - mov lr, ip /* restore link */ - mov pc, lr /* back to my caller */ -#endif -/* - ************************************************************************* - * - * 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 -#define I_BIT 0x80 - -/* - * use bad_save_user_regs for abort/prefetch/undef/swi ... - * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling - */ - - .macro bad_save_user_regs - @ carve out a frame on current user stack - sub sp, sp, #S_FRAME_SIZE - stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12 - - ldr r2, _armboot_start - sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) - sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack - @ get values for "aborted" pc and cpsr (into parm regs) - ldmia r2, {r2 - r3} - add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack - add r5, sp, #S_SP - mov r1, lr - stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr - mov r0, sp @ save current stack into r0 (param register) - .endm - - .macro irq_save_user_regs - sub sp, sp, #S_FRAME_SIZE - stmia sp, {r0 - r12} @ Calling r0-r12 - @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good. - 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, _armboot_start @ setup our mode stack - sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) - sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack - - str lr, [r13] @ save caller lr in position 0 of saved stack - mrs lr, spsr @ get the spsr - str lr, [r13, #4] @ save spsr in position 1 of saved stack - mov r13, #MODE_SVC @ prepare SVC-Mode - @ msr spsr_c, r13 - msr spsr, r13 @ switch modes, make sure moves will execute - mov lr, pc @ capture return pc - movs pc, lr @ jump to next instruction & switch modes. - .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 - /* someone ought to write a more effiction fiq_save_user_regs */ - irq_save_user_regs - bl do_fiq - 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 - -# ifdef CONFIG_INTEGRATOR - - /* Satisfied by general board level routine */ - -#else - - .align 5 -.globl reset_cpu -reset_cpu: - - ldr r1, rstctl1 /* get clkm1 reset ctl */ - mov r3, #0x0 - strh r3, [r1] /* clear it */ - mov r3, #0x8 - strh r3, [r1] /* force dsp+arm reset */ -_loop_forever: - b _loop_forever - -rstctl1: - .word 0xfffece10 - -#endif /* #ifdef CONFIG_INTEGRATOR */ diff --git a/cpu/arm946es/u-boot.lds b/cpu/arm946es/u-boot.lds deleted file mode 100644 index 5bd4390fb5..0000000000 --- a/cpu/arm946es/u-boot.lds +++ /dev/null @@ -1,56 +0,0 @@ -/* - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -ENTRY(_start) -SECTIONS -{ - . = 0x00000000; - - . = ALIGN(4); - .text : - { - cpu/arm946es/start.o (.text) - *(.text) - } - - . = ALIGN(4); - .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } - - . = ALIGN(4); - .data : { *(.data) } - - . = ALIGN(4); - .got : { *(.got) } - - . = .; - __u_boot_cmd_start = .; - .u_boot_cmd : { *(.u_boot_cmd) } - __u_boot_cmd_end = .; - - . = ALIGN(4); - __bss_start = .; - .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } - _end = .; -} diff --git a/cpu/arm_cortexa8/Makefile b/cpu/arm_cortexa8/Makefile deleted file mode 100644 index ae20299db7..0000000000 --- a/cpu/arm_cortexa8/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -# -# (C) Copyright 2000-2003 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(CPU).a - -START := start.o -COBJS := cpu.o - -SRCS := $(START:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS)) -START := $(addprefix $(obj),$(START)) - -all: $(obj).depend $(START) $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### \ No newline at end of file diff --git a/cpu/arm_cortexa8/config.mk b/cpu/arm_cortexa8/config.mk deleted file mode 100644 index 49ac9c74ae..0000000000 --- a/cpu/arm_cortexa8/config.mk +++ /dev/null @@ -1,33 +0,0 @@ -# -# (C) Copyright 2002 -# Gary Jennejohn, DENX Software Engineering, -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# -PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float - -# Make ARMv5 to allow more compilers to work, even though its v7a. -PLATFORM_CPPFLAGS += -march=armv5 -# ========================================================================= -# -# Supply options according to compiler version -# -# ========================================================================= -PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,\ - $(call cc-option,-malignment-traps,)) diff --git a/cpu/arm_cortexa8/cpu.c b/cpu/arm_cortexa8/cpu.c deleted file mode 100644 index a01e0d605f..0000000000 --- a/cpu/arm_cortexa8/cpu.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * (C) Copyright 2008 Texas Insturments - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * CPU specific code - */ - -#include -#include -#include -#include -#ifndef CONFIG_L2_OFF -#include -#endif - -static void cache_flush(void); - -int cleanup_before_linux(void) -{ - unsigned int i; - - /* - * this function is called just before we call linux - * it prepares the processor for linux - * - * we turn off caches etc ... - */ - disable_interrupts(); - - /* turn off I/D-cache */ - icache_disable(); - dcache_disable(); - - /* invalidate I-cache */ - cache_flush(); - -#ifndef CONFIG_L2_OFF - /* turn off L2 cache */ - l2_cache_disable(); - /* invalidate L2 cache also */ - invalidate_dcache(get_device_type()); -#endif - i = 0; - /* mem barrier to sync up things */ - asm("mcr p15, 0, %0, c7, c10, 4": :"r"(i)); - -#ifndef CONFIG_L2_OFF - l2_cache_enable(); -#endif - - return 0; -} - -static void cache_flush(void) -{ - asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (0)); -} diff --git a/cpu/arm_cortexa8/mx51/Makefile b/cpu/arm_cortexa8/mx51/Makefile deleted file mode 100644 index 7cfaa2c130..0000000000 --- a/cpu/arm_cortexa8/mx51/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# (C) Copyright 2009 Freescale Semiconductor, Inc. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(SOC).a - -COBJS = soc.o clock.o iomux.o timer.o speed.o -SOBJS = lowlevel_init.o - -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) - -all: $(obj).depend $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/arm_cortexa8/mx51/clock.c b/cpu/arm_cortexa8/mx51/clock.c deleted file mode 100644 index 38480ac5a1..0000000000 --- a/cpu/arm_cortexa8/mx51/clock.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - * (C) Copyright 2007 - * Sascha Hauer, Pengutronix - * - * (C) Copyright 2009 Freescale Semiconductor, Inc. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include - -enum pll_clocks { - PLL1_CLOCK = 0, - PLL2_CLOCK, - PLL3_CLOCK, - PLL_CLOCKS, -}; - -struct mxc_pll_reg *mxc_plls[PLL_CLOCKS] = { - [PLL1_CLOCK] = (struct mxc_pll_reg *)PLL1_BASE_ADDR, - [PLL2_CLOCK] = (struct mxc_pll_reg *)PLL2_BASE_ADDR, - [PLL3_CLOCK] = (struct mxc_pll_reg *)PLL3_BASE_ADDR, -}; - -struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)MXC_CCM_BASE; - -/* - * Calculate the frequency of this pll. - */ -static u32 decode_pll(struct mxc_pll_reg *pll, u32 infreq) -{ - u32 mfi, mfn, mfd, pd; - - mfn = __raw_readl(&pll->mfn); - mfd = __raw_readl(&pll->mfd) + 1; - mfi = __raw_readl(&pll->op); - pd = (mfi & 0xF) + 1; - mfi = (mfi >> 4) & 0xF; - mfi = (mfi >= 5) ? mfi : 5; - - return ((4 * (infreq / 1000) * (mfi * mfd + mfn)) / (mfd * pd)) * 1000; -} - -/* - * Get mcu main rate - */ -u32 get_mcu_main_clk(void) -{ - u32 reg, freq; - - reg = (__raw_readl(&mxc_ccm->cacrr) & MXC_CCM_CACRR_ARM_PODF_MASK) >> - MXC_CCM_CACRR_ARM_PODF_OFFSET; - freq = decode_pll(mxc_plls[PLL1_CLOCK], CONFIG_MX51_HCLK_FREQ); - return freq / (reg + 1); -} - -/* - * Get the rate of peripheral's root clock. - */ -static u32 get_periph_clk(void) -{ - u32 reg; - - reg = __raw_readl(&mxc_ccm->cbcdr); - if (!(reg & MXC_CCM_CBCDR_PERIPH_CLK_SEL)) - return decode_pll(mxc_plls[PLL2_CLOCK], CONFIG_MX51_HCLK_FREQ); - reg = __raw_readl(&mxc_ccm->cbcmr); - switch ((reg & MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK) >> - MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET) { - case 0: - return decode_pll(mxc_plls[PLL1_CLOCK], CONFIG_MX51_HCLK_FREQ); - case 1: - return decode_pll(mxc_plls[PLL3_CLOCK], CONFIG_MX51_HCLK_FREQ); - default: - return 0; - } - /* NOTREACHED */ -} - -/* - * Get the rate of ipg clock. - */ -static u32 get_ipg_clk(void) -{ - u32 ahb_podf, ipg_podf; - - ahb_podf = __raw_readl(&mxc_ccm->cbcdr); - ipg_podf = (ahb_podf & MXC_CCM_CBCDR_IPG_PODF_MASK) >> - MXC_CCM_CBCDR_IPG_PODF_OFFSET; - ahb_podf = (ahb_podf & MXC_CCM_CBCDR_AHB_PODF_MASK) >> - MXC_CCM_CBCDR_AHB_PODF_OFFSET; - return get_periph_clk() / ((ahb_podf + 1) * (ipg_podf + 1)); -} - -/* - * Get the rate of ipg_per clock. - */ -static u32 get_ipg_per_clk(void) -{ - u32 pred1, pred2, podf; - - if (__raw_readl(&mxc_ccm->cbcmr) & MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL) - return get_ipg_clk(); - /* Fixme: not handle what about lpm*/ - podf = __raw_readl(&mxc_ccm->cbcdr); - pred1 = (podf & MXC_CCM_CBCDR_PERCLK_PRED1_MASK) >> - MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET; - pred2 = (podf & MXC_CCM_CBCDR_PERCLK_PRED2_MASK) >> - MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET; - podf = (podf & MXC_CCM_CBCDR_PERCLK_PODF_MASK) >> - MXC_CCM_CBCDR_PERCLK_PODF_OFFSET; - - return get_periph_clk() / ((pred1 + 1) * (pred2 + 1) * (podf + 1)); -} - -/* - * Get the rate of uart clk. - */ -static u32 get_uart_clk(void) -{ - unsigned int freq, reg, pred, podf; - - reg = __raw_readl(&mxc_ccm->cscmr1); - switch ((reg & MXC_CCM_CSCMR1_UART_CLK_SEL_MASK) >> - MXC_CCM_CSCMR1_UART_CLK_SEL_OFFSET) { - case 0x0: - freq = decode_pll(mxc_plls[PLL1_CLOCK], - CONFIG_MX51_HCLK_FREQ); - break; - case 0x1: - freq = decode_pll(mxc_plls[PLL2_CLOCK], - CONFIG_MX51_HCLK_FREQ); - break; - case 0x2: - freq = decode_pll(mxc_plls[PLL3_CLOCK], - CONFIG_MX51_HCLK_FREQ); - break; - default: - return 66500000; - } - - reg = __raw_readl(&mxc_ccm->cscdr1); - - pred = (reg & MXC_CCM_CSCDR1_UART_CLK_PRED_MASK) >> - MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET; - - podf = (reg & MXC_CCM_CSCDR1_UART_CLK_PODF_MASK) >> - MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET; - freq /= (pred + 1) * (podf + 1); - - return freq; -} - -/* - * This function returns the low power audio clock. - */ -u32 get_lp_apm(void) -{ - u32 ret_val = 0; - u32 ccsr = __raw_readl(&mxc_ccm->ccsr); - - if (((ccsr >> 9) & 1) == 0) - ret_val = CONFIG_MX51_HCLK_FREQ; - else - ret_val = ((32768 * 1024)); - - return ret_val; -} - -/* - * get cspi clock rate. - */ -u32 imx_get_cspiclk(void) -{ - u32 ret_val = 0, pdf, pre_pdf, clk_sel; - u32 cscmr1 = __raw_readl(&mxc_ccm->cscmr1); - u32 cscdr2 = __raw_readl(&mxc_ccm->cscdr2); - - pre_pdf = (cscdr2 & MXC_CCM_CSCDR2_CSPI_CLK_PRED_MASK) \ - >> MXC_CCM_CSCDR2_CSPI_CLK_PRED_OFFSET; - pdf = (cscdr2 & MXC_CCM_CSCDR2_CSPI_CLK_PODF_MASK) \ - >> MXC_CCM_CSCDR2_CSPI_CLK_PODF_OFFSET; - clk_sel = (cscmr1 & MXC_CCM_CSCMR1_CSPI_CLK_SEL_MASK) \ - >> MXC_CCM_CSCMR1_CSPI_CLK_SEL_OFFSET; - - switch (clk_sel) { - case 0: - ret_val = decode_pll(mxc_plls[PLL1_CLOCK], - CONFIG_MX51_HCLK_FREQ) / - ((pre_pdf + 1) * (pdf + 1)); - break; - case 1: - ret_val = decode_pll(mxc_plls[PLL2_CLOCK], - CONFIG_MX51_HCLK_FREQ) / - ((pre_pdf + 1) * (pdf + 1)); - break; - case 2: - ret_val = decode_pll(mxc_plls[PLL3_CLOCK], - CONFIG_MX51_HCLK_FREQ) / - ((pre_pdf + 1) * (pdf + 1)); - break; - default: - ret_val = get_lp_apm() / ((pre_pdf + 1) * (pdf + 1)); - break; - } - - return ret_val; -} - -/* - * The API of get mxc clockes. - */ -unsigned int mxc_get_clock(enum mxc_clock clk) -{ - switch (clk) { - case MXC_ARM_CLK: - return get_mcu_main_clk(); - case MXC_AHB_CLK: - break; - case MXC_IPG_CLK: - return get_ipg_clk(); - case MXC_IPG_PERCLK: - return get_ipg_per_clk(); - case MXC_UART_CLK: - return get_uart_clk(); - case MXC_CSPI_CLK: - return imx_get_cspiclk(); - case MXC_FEC_CLK: - return decode_pll(mxc_plls[PLL1_CLOCK], - CONFIG_MX51_HCLK_FREQ); - default: - break; - } - return -1; -} - -u32 imx_get_uartclk(void) -{ - return get_uart_clk(); -} - - -u32 imx_get_fecclk(void) -{ - return mxc_get_clock(MXC_IPG_CLK); -} - -/* - * Dump some core clockes. - */ -int do_mx51_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - u32 freq; - - freq = decode_pll(mxc_plls[PLL1_CLOCK], CONFIG_MX51_HCLK_FREQ); - printf("mx51 pll1: %dMHz\n", freq / 1000000); - freq = decode_pll(mxc_plls[PLL2_CLOCK], CONFIG_MX51_HCLK_FREQ); - printf("mx51 pll2: %dMHz\n", freq / 1000000); - freq = decode_pll(mxc_plls[PLL3_CLOCK], CONFIG_MX51_HCLK_FREQ); - printf("mx51 pll3: %dMHz\n", freq / 1000000); - printf("ipg clock : %dHz\n", mxc_get_clock(MXC_IPG_CLK)); - printf("ipg per clock : %dHz\n", mxc_get_clock(MXC_IPG_PERCLK)); - - return 0; -} - -/***************************************************/ - -U_BOOT_CMD( - clockinfo, CONFIG_SYS_MAXARGS, 1, do_mx51_showclocks, - "display mx51 clocks\n", - "" -); diff --git a/cpu/arm_cortexa8/mx51/iomux.c b/cpu/arm_cortexa8/mx51/iomux.c deleted file mode 100644 index 62b2954be9..0000000000 --- a/cpu/arm_cortexa8/mx51/iomux.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * (C) Copyright 2009 Freescale Semiconductor, Inc. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include - -/* IOMUX register (base) addresses */ -enum iomux_reg_addr { - IOMUXGPR0 = IOMUXC_BASE_ADDR, - IOMUXGPR1 = IOMUXC_BASE_ADDR + 0x004, - IOMUXSW_MUX_CTL = IOMUXC_BASE_ADDR, - IOMUXSW_MUX_END = IOMUXC_BASE_ADDR + MUX_I_END, - IOMUXSW_PAD_CTL = IOMUXC_BASE_ADDR + PAD_I_START, - IOMUXSW_INPUT_CTL = IOMUXC_BASE_ADDR, -}; - -#define MUX_PIN_NUM_MAX (((MUX_I_END - MUX_I_START) >> 2) + 1) - -/* Get the iomux register address of this pin */ -static inline u32 get_mux_reg(iomux_pin_name_t pin) -{ - u32 mux_reg = PIN_TO_IOMUX_MUX(pin); - - if (is_soc_rev(CHIP_REV_2_0) < 0) { - /* - * Fixup register address: - * i.MX51 TO1 has offset with the register - * which is define as TO2. - */ - if ((pin == MX51_PIN_NANDF_RB5) || - (pin == MX51_PIN_NANDF_RB6) || - (pin == MX51_PIN_NANDF_RB7)) - ; /* Do nothing */ - else if (mux_reg >= 0x2FC) - mux_reg += 8; - else if (mux_reg >= 0x130) - mux_reg += 0xC; - } - mux_reg += IOMUXSW_MUX_CTL; - return mux_reg; -} - -/* Get the pad register address of this pin */ -static inline u32 get_pad_reg(iomux_pin_name_t pin) -{ - u32 pad_reg = PIN_TO_IOMUX_PAD(pin); - - if (is_soc_rev(CHIP_REV_2_0) < 0) { - /* - * Fixup register address: - * i.MX51 TO1 has offset with the register - * which is define as TO2. - */ - if ((pin == MX51_PIN_NANDF_RB5) || - (pin == MX51_PIN_NANDF_RB6) || - (pin == MX51_PIN_NANDF_RB7)) - ; /* Do nothing */ - else if (pad_reg == 0x4D0 - PAD_I_START) - pad_reg += 0x4C; - else if (pad_reg == 0x860 - PAD_I_START) - pad_reg += 0x9C; - else if (pad_reg >= 0x804 - PAD_I_START) - pad_reg += 0xB0; - else if (pad_reg >= 0x7FC - PAD_I_START) - pad_reg += 0xB4; - else if (pad_reg >= 0x4E4 - PAD_I_START) - pad_reg += 0xCC; - else - pad_reg += 8; - } - pad_reg += IOMUXSW_PAD_CTL; - return pad_reg; -} - -/* Get the last iomux register address */ -static inline u32 get_mux_end(void) -{ - if (is_soc_rev(CHIP_REV_2_0) < 0) - return IOMUXC_BASE_ADDR + (0x3F8 - 4); - else - return IOMUXC_BASE_ADDR + (0x3F0 - 4); -} - -/* - * This function is used to configure a pin through the IOMUX module. - * @param pin a pin number as defined in iomux_pin_name_t - * @param cfg an output function as defined in iomux_pin_cfg_t - * - * @return 0 if successful; Non-zero otherwise - */ -static void iomux_config_mux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg) -{ - u32 mux_reg = get_mux_reg(pin); - - if ((mux_reg > get_mux_end()) || (mux_reg < IOMUXSW_MUX_CTL)) - return ; - if (cfg == IOMUX_CONFIG_GPIO) - writel(PIN_TO_ALT_GPIO(pin), mux_reg); - else - writel(cfg, mux_reg); -} - -/* - * Request ownership for an IO pin. This function has to be the first one - * being called before that pin is used. The caller has to check the - * return value to make sure it returns 0. - * - * @param pin a name defined by iomux_pin_name_t - * @param cfg an input function as defined in iomux_pin_cfg_t - * - */ -void mxc_request_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg) -{ - iomux_config_mux(pin, cfg); -} - -/* - * Release ownership for an IO pin - * - * @param pin a name defined by iomux_pin_name_t - * @param cfg an input function as defined in iomux_pin_cfg_t - */ -void mxc_free_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg) -{ -} - -/* - * This function configures the pad value for a IOMUX pin. - * - * @param pin a pin number as defined in iomux_pin_name_t - * @param config the ORed value of elements defined in iomux_pad_config_t - */ -void mxc_iomux_set_pad(iomux_pin_name_t pin, u32 config) -{ - u32 pad_reg = get_pad_reg(pin); - writel(config, pad_reg); -} - -unsigned int mxc_iomux_get_pad(iomux_pin_name_t pin) -{ - u32 pad_reg = get_pad_reg(pin); - return readl(pad_reg); -} diff --git a/cpu/arm_cortexa8/mx51/lowlevel_init.S b/cpu/arm_cortexa8/mx51/lowlevel_init.S deleted file mode 100644 index 31af9e2b58..0000000000 --- a/cpu/arm_cortexa8/mx51/lowlevel_init.S +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright (C) 2007, Guennadi Liakhovetski - * - * (C) Copyright 2009 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -/* - * L2CC Cache setup/invalidation/disable - */ -.macro init_l2cc - /* explicitly disable L2 cache */ - mrc 15, 0, r0, c1, c0, 1 - bic r0, r0, #0x2 - mcr 15, 0, r0, c1, c0, 1 - - /* reconfigure L2 cache aux control reg */ - mov r0, #0xC0 /* tag RAM */ - add r0, r0, #0x4 /* data RAM */ - orr r0, r0, #(1 << 24) /* disable write allocate delay */ - orr r0, r0, #(1 << 23) /* disable write allocate combine */ - orr r0, r0, #(1 << 22) /* disable write allocate */ - - cmp r3, #0x10 /* r3 contains the silicon rev */ - - /* disable write combine for TO 2 and lower revs */ - orrls r0, r0, #(1 << 25) - - mcr 15, 1, r0, c9, c0, 2 -.endm /* init_l2cc */ - -/* AIPS setup - Only setup MPROTx registers. - * The PACR default values are good.*/ -.macro init_aips - /* - * Set all MPROTx to be non-bufferable, trusted for R/W, - * not forced to user-mode. - */ - ldr r0, =AIPS1_BASE_ADDR - ldr r1, =0x77777777 - str r1, [r0, #0x0] - str r1, [r0, #0x4] - ldr r0, =AIPS2_BASE_ADDR - str r1, [r0, #0x0] - str r1, [r0, #0x4] - /* - * Clear the on and off peripheral modules Supervisor Protect bit - * for SDMA to access them. Did not change the AIPS control registers - * (offset 0x20) access type - */ -.endm /* init_aips */ - -/* M4IF setup */ -.macro init_m4if - /* VPU and IPU given higher priority (0x4) - * IPU accesses with ID=0x1 given highest priority (=0xA) - */ - ldr r0, =M4IF_BASE_ADDR - - ldr r1, =0x00000203 - str r1, [r0, #0x40] - - ldr r1, =0x0 - str r1, [r0, #0x44] - - ldr r1, =0x00120125 - str r1, [r0, #0x9C] - - ldr r1, =0x001901A3 - str r1, [r0, #0x48] - -.endm /* init_m4if */ - -.macro setup_pll pll, freq - ldr r2, =\pll - ldr r1, =0x00001232 - str r1, [r2, #PLL_DP_CTL] /* Set DPLL ON (set UPEN bit): BRMO=1 */ - mov r1, #0x2 - str r1, [r2, #PLL_DP_CONFIG] /* Enable auto-restart AREN bit */ - - str r3, [r2, #PLL_DP_OP] - str r3, [r2, #PLL_DP_HFS_OP] - - str r4, [r2, #PLL_DP_MFD] - str r4, [r2, #PLL_DP_HFS_MFD] - - str r5, [r2, #PLL_DP_MFN] - str r5, [r2, #PLL_DP_HFS_MFN] - - ldr r1, =0x00001232 - str r1, [r2, #PLL_DP_CTL] -1: ldr r1, [r2, #PLL_DP_CTL] - ands r1, r1, #0x1 - beq 1b -.endm - -.macro init_clock - ldr r0, =CCM_BASE_ADDR - - /* Gate of clocks to the peripherals first */ - ldr r1, =0x3FFFFFFF - str r1, [r0, #CLKCTL_CCGR0] - ldr r1, =0x0 - str r1, [r0, #CLKCTL_CCGR1] - str r1, [r0, #CLKCTL_CCGR2] - str r1, [r0, #CLKCTL_CCGR3] - - ldr r1, =0x00030000 - str r1, [r0, #CLKCTL_CCGR4] - ldr r1, =0x00FFF030 - str r1, [r0, #CLKCTL_CCGR5] - ldr r1, =0x00000300 - str r1, [r0, #CLKCTL_CCGR6] - - /* Disable IPU and HSC dividers */ - mov r1, #0x60000 - str r1, [r0, #CLKCTL_CCDR] - - /* Make sure to switch the DDR away from PLL 1 */ - ldr r1, =0x19239145 - str r1, [r0, #CLKCTL_CBCDR] - /* make sure divider effective */ -1: ldr r1, [r0, #CLKCTL_CDHIPR] - cmp r1, #0x0 - bne 1b - - /* Switch ARM to step clock */ - mov r1, #0x4 - str r1, [r0, #CLKCTL_CCSR] - mov r3, #DP_OP_800 - mov r4, #DP_MFD_800 - mov r5, #DP_MFN_800 - setup_pll PLL1_BASE_ADDR - - mov r3, #DP_OP_665 - mov r4, #DP_MFD_665 - mov r5, #DP_MFN_665 - setup_pll PLL3_BASE_ADDR - - /* Switch peripheral to PLL 3 */ - ldr r0, =CCM_BASE_ADDR - ldr r1, =0x000010C0 - str r1, [r0, #CLKCTL_CBCMR] - ldr r1, =0x13239145 - str r1, [r0, #CLKCTL_CBCDR] - mov r3, #DP_OP_665 - mov r4, #DP_MFD_665 - mov r5, #DP_MFN_665 - setup_pll PLL2_BASE_ADDR - - /* Switch peripheral to PLL2 */ - ldr r0, =CCM_BASE_ADDR - ldr r1, =0x19239145 - str r1, [r0, #CLKCTL_CBCDR] - ldr r1, =0x000020C0 - str r1, [r0, #CLKCTL_CBCMR] - - mov r3, #DP_OP_216 - mov r4, #DP_MFD_216 - mov r5, #DP_MFN_216 - setup_pll PLL3_BASE_ADDR - - - /* Set the platform clock dividers */ - ldr r0, =ARM_BASE_ADDR - ldr r1, =0x00000725 - str r1, [r0, #0x14] - - ldr r0, =CCM_BASE_ADDR - - /* Run 3.0 at Full speed, for other TO's wait till we increase VDDGP */ - ldr r1, =0x0 - ldr r3, [r1, #ROM_SI_REV] - cmp r3, #0x10 - movls r1, #0x1 - movhi r1, #0 - str r1, [r0, #CLKCTL_CACRR] - - /* Switch ARM back to PLL 1 */ - mov r1, #0 - str r1, [r0, #CLKCTL_CCSR] - - /* setup the rest */ - /* Use lp_apm (24MHz) source for perclk */ - ldr r1, =0x000020C2 - str r1, [r0, #CLKCTL_CBCMR] - /* ddr clock from PLL 1, all perclk dividers are 1 since using 24MHz */ - ldr r1, =0x59E35100 - str r1, [r0, #CLKCTL_CBCDR] - - /* Restore the default values in the Gate registers */ - ldr r1, =0xFFFFFFFF - str r1, [r0, #CLKCTL_CCGR0] - str r1, [r0, #CLKCTL_CCGR1] - str r1, [r0, #CLKCTL_CCGR2] - str r1, [r0, #CLKCTL_CCGR3] - str r1, [r0, #CLKCTL_CCGR4] - str r1, [r0, #CLKCTL_CCGR5] - str r1, [r0, #CLKCTL_CCGR6] - - /* Use PLL 2 for UART's, get 66.5MHz from it */ - ldr r1, =0xA5A2A020 - str r1, [r0, #CLKCTL_CSCMR1] - ldr r1, =0x00C30321 - str r1, [r0, #CLKCTL_CSCDR1] - - /* make sure divider effective */ -1: ldr r1, [r0, #CLKCTL_CDHIPR] - cmp r1, #0x0 - bne 1b - - mov r1, #0x0 - str r1, [r0, #CLKCTL_CCDR] - - /* for cko - for ARM div by 8 */ - mov r1, #0x000A0000 - add r1, r1, #0x00000F0 - str r1, [r0, #CLKCTL_CCOSR] -.endm - -.macro setup_wdog - ldr r0, =WDOG1_BASE_ADDR - mov r1, #0x30 - strh r1, [r0] -.endm - -.section ".text.init", "x" - -.globl lowlevel_init -lowlevel_init: - ldr r0, =GPIO1_BASE_ADDR - ldr r1, [r0, #0x0] - orr r1, r1, #(1 << 23) - str r1, [r0, #0x0] - ldr r1, [r0, #0x4] - orr r1, r1, #(1 << 23) - str r1, [r0, #0x4] - -#ifdef ENABLE_IMPRECISE_ABORT - mrs r1, spsr /* save old spsr */ - mrs r0, cpsr /* read out the cpsr */ - bic r0, r0, #0x100 /* clear the A bit */ - msr spsr, r0 /* update spsr */ - add lr, pc, #0x8 /* update lr */ - movs pc, lr /* update cpsr */ - nop - nop - nop - nop - msr spsr, r1 /* restore old spsr */ -#endif - - init_l2cc - - init_aips - - init_m4if - - init_clock - - /* r12 saved upper lr*/ - mov pc,lr - -/* Board level setting value */ -DDR_PERCHARGE_CMD: .word 0x04008008 -DDR_REFRESH_CMD: .word 0x00008010 -DDR_LMR1_W: .word 0x00338018 -DDR_LMR_CMD: .word 0xB2220000 -DDR_TIMING_W: .word 0xB02567A9 -DDR_MISC_W: .word 0x000A0104 diff --git a/cpu/arm_cortexa8/mx51/soc.c b/cpu/arm_cortexa8/mx51/soc.c deleted file mode 100644 index 2a139b21d5..0000000000 --- a/cpu/arm_cortexa8/mx51/soc.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * (C) Copyright 2007 - * Sascha Hauer, Pengutronix - * - * (C) Copyright 2009 Freescale Semiconductor, Inc. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include - -#ifdef CONFIG_FSL_ESDHC -#include -#endif - -u32 get_cpu_rev(void) -{ - int reg; - int system_rev; - - reg = __raw_readl(ROM_SI_REV); - switch (reg) { - case 0x02: - system_rev = 0x51000 | CHIP_REV_1_1; - break; - case 0x10: - if ((__raw_readl(GPIO1_BASE_ADDR + 0x0) & (0x1 << 22)) == 0) - system_rev = 0x51000 | CHIP_REV_2_5; - else - system_rev = 0x51000 | CHIP_REV_2_0; - break; - case 0x20: - system_rev = 0x51000 | CHIP_REV_3_0; - break; - return system_rev; - default: - system_rev = 0x51000 | CHIP_REV_1_0; - break; - } - return system_rev; -} - - -#if defined(CONFIG_DISPLAY_CPUINFO) -int print_cpuinfo(void) -{ - u32 cpurev; - - cpurev = get_cpu_rev(); - printf("CPU: Freescale i.MX51 family %d.%dV at %d MHz\n", - (cpurev & 0xF0) >> 4, - (cpurev & 0x0F) >> 4, - mxc_get_clock(MXC_ARM_CLK) / 1000000); - return 0; -} -#endif - -/* - * Initializes on-chip ethernet controllers. - * to override, implement board_eth_init() - */ -#if defined(CONFIG_FEC_MXC) -extern int fecmxc_initialize(bd_t *bis); -#endif - -int cpu_eth_init(bd_t *bis) -{ - int rc = -ENODEV; - -#if defined(CONFIG_FEC_MXC) - rc = fecmxc_initialize(bis); -#endif - - return rc; -} - -/* - * Initializes on-chip MMC controllers. - * to override, implement board_mmc_init() - */ -int cpu_mmc_init(bd_t *bis) -{ -#ifdef CONFIG_FSL_ESDHC - return fsl_esdhc_mmc_init(bis); -#else - return 0; -#endif -} - - -void reset_cpu(ulong addr) -{ - __raw_writew(4, WDOG1_BASE_ADDR); -} diff --git a/cpu/arm_cortexa8/mx51/speed.c b/cpu/arm_cortexa8/mx51/speed.c deleted file mode 100644 index a444def7eb..0000000000 --- a/cpu/arm_cortexa8/mx51/speed.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * (C) Copyright 2000-2003 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. - * TsiChung Liew (Tsi-Chung.Liew@freescale.com) - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -int get_clocks(void) -{ - DECLARE_GLOBAL_DATA_PTR; - -#ifdef CONFIG_FSL_ESDHC - gd->sdhc_clk = mxc_get_clock(MXC_IPG_PERCLK); -#endif - return 0; -} diff --git a/cpu/arm_cortexa8/mx51/timer.c b/cpu/arm_cortexa8/mx51/timer.c deleted file mode 100644 index 8ecfec66da..0000000000 --- a/cpu/arm_cortexa8/mx51/timer.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * (C) Copyright 2007 - * Sascha Hauer, Pengutronix - * - * (C) Copyright 2009 Freescale Semiconductor, Inc. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -/* General purpose timers registers */ -struct mxc_gpt { - unsigned int control; - unsigned int prescaler; - unsigned int status; - unsigned int nouse[6]; - unsigned int counter; -}; - -static struct mxc_gpt *cur_gpt = (struct mxc_gpt *)GPT1_BASE_ADDR; - -/* General purpose timers bitfields */ -#define GPTCR_SWR (1<<15) /* Software reset */ -#define GPTCR_FRR (1<<9) /* Freerun / restart */ -#define GPTCR_CLKSOURCE_32 (4<<6) /* Clock source */ -#define GPTCR_TEN (1) /* Timer enable */ - -static ulong timestamp; -static ulong lastinc; - -int timer_init(void) -{ - int i; - - /* setup GP Timer 1 */ - __raw_writel(GPTCR_SWR, &cur_gpt->control); - - /* We have no udelay by now */ - for (i = 0; i < 100; i++) - __raw_writel(0, &cur_gpt->control); - - __raw_writel(0, &cur_gpt->prescaler); /* 32Khz */ - - /* Freerun Mode, PERCLK1 input */ - i = __raw_readl(&cur_gpt->control); - __raw_writel(i | GPTCR_CLKSOURCE_32 | GPTCR_TEN, &cur_gpt->control); - reset_timer_masked(); - return 0; -} - -void reset_timer(void) -{ - reset_timer_masked(); -} - -void reset_timer_masked(void) -{ - ulong val = __raw_readl(&cur_gpt->counter); - lastinc = val / (CONFIG_MX51_CLK32 / CONFIG_SYS_HZ); - timestamp = 0; -} - -ulong get_timer_masked(void) -{ - ulong val = __raw_readl(&cur_gpt->counter); - val /= (CONFIG_MX51_CLK32 / CONFIG_SYS_HZ); - if (val >= lastinc) - timestamp += (val - lastinc); - else - timestamp += ((0xFFFFFFFF / (CONFIG_MX51_CLK32 / CONFIG_SYS_HZ)) - - lastinc) + val; - lastinc = val; - return val; -} - -ulong get_timer(ulong base) -{ - return get_timer_masked() - base; -} - -void set_timer(ulong t) -{ - timestamp = t; -} - -/* delay x useconds AND perserve advance timstamp value */ -void __udelay(unsigned long usec) -{ - unsigned long now, start, tmo; - tmo = usec * (CONFIG_MX51_CLK32 / 1000) / 1000; - - if (!tmo) - tmo = 1; - - now = start = readl(&cur_gpt->counter); - - while ((now - start) < tmo) - now = readl(&cur_gpt->counter); - -} diff --git a/cpu/arm_cortexa8/mx51/u-boot.lds b/cpu/arm_cortexa8/mx51/u-boot.lds deleted file mode 100644 index 84c173ac71..0000000000 --- a/cpu/arm_cortexa8/mx51/u-boot.lds +++ /dev/null @@ -1,61 +0,0 @@ -/* - * January 2004 - Changed to support H4 device - * Copyright (c) 2004 Texas Instruments - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * (C) Copyright 2009 Freescale Semiconductor, Inc. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -ENTRY(_start) -SECTIONS -{ - . = 0x00000000; - - . = ALIGN(4); - .text : - { - cpu/arm_cortexa8/start.o - *(.text) - } - - . = ALIGN(4); - .rodata : { *(.rodata) } - - . = ALIGN(4); - .data : { *(.data) } - - . = ALIGN(4); - .got : { *(.got) } - - . = .; - __u_boot_cmd_start = .; - .u_boot_cmd : { *(.u_boot_cmd) } - __u_boot_cmd_end = .; - - . = ALIGN(4); - __bss_start = .; - .bss : { *(.bss) } - _end = .; -} diff --git a/cpu/arm_cortexa8/omap3/Makefile b/cpu/arm_cortexa8/omap3/Makefile deleted file mode 100644 index 136b163ad7..0000000000 --- a/cpu/arm_cortexa8/omap3/Makefile +++ /dev/null @@ -1,55 +0,0 @@ -# -# (C) Copyright 2000-2003 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(SOC).a - -SOBJS := lowlevel_init.o -SOBJS += cache.o -SOBJS += reset.o - -COBJS += board.o -COBJS += clock.o -COBJS += gpio.o -COBJS += mem.o -COBJS += syslib.o -COBJS += sys_info.o -COBJS += timer.o - -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) - -all: $(obj).depend $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/arm_cortexa8/omap3/board.c b/cpu/arm_cortexa8/omap3/board.c deleted file mode 100644 index 7b78fa448b..0000000000 --- a/cpu/arm_cortexa8/omap3/board.c +++ /dev/null @@ -1,361 +0,0 @@ -/* - * - * Common board functions for OMAP3 based boards. - * - * (C) Copyright 2004-2008 - * Texas Instruments, - * - * Author : - * Sunil Kumar - * Shashi Ranjan - * - * Derived from Beagle Board and 3430 SDP code by - * Richard Woodruff - * Syed Mohammed Khasim - * - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ -#include -#include -#include -#include -#include - -extern omap3_sysinfo sysinfo; - -extern u32 is_mem_sdr(void); - -/****************************************************************************** - * Routine: delay - * Description: spinning delay to use before udelay works - *****************************************************************************/ -static inline void delay(unsigned long loops) -{ - __asm__ volatile ("1:\n" "subs %0, %1, #1\n" - "bne 1b":"=r" (loops):"0"(loops)); -} - -/****************************************************************************** - * Routine: secure_unlock - * Description: Setup security registers for access - * (GP Device only) - *****************************************************************************/ -void secure_unlock_mem(void) -{ - struct pm *pm_rt_ape_base = (struct pm *)PM_RT_APE_BASE_ADDR_ARM; - struct pm *pm_gpmc_base = (struct pm *)PM_GPMC_BASE_ADDR_ARM; - struct pm *pm_ocm_ram_base = (struct pm *)PM_OCM_RAM_BASE_ADDR_ARM; - struct pm *pm_iva2_base = (struct pm *)PM_IVA2_BASE_ADDR_ARM; - struct sms *sms_base = (struct sms *)OMAP34XX_SMS_BASE; - - /* Protection Module Register Target APE (PM_RT) */ - writel(UNLOCK_1, &pm_rt_ape_base->req_info_permission_1); - writel(UNLOCK_1, &pm_rt_ape_base->read_permission_0); - writel(UNLOCK_1, &pm_rt_ape_base->wirte_permission_0); - writel(UNLOCK_2, &pm_rt_ape_base->addr_match_1); - - writel(UNLOCK_3, &pm_gpmc_base->req_info_permission_0); - writel(UNLOCK_3, &pm_gpmc_base->read_permission_0); - writel(UNLOCK_3, &pm_gpmc_base->wirte_permission_0); - - writel(UNLOCK_3, &pm_ocm_ram_base->req_info_permission_0); - writel(UNLOCK_3, &pm_ocm_ram_base->read_permission_0); - writel(UNLOCK_3, &pm_ocm_ram_base->wirte_permission_0); - writel(UNLOCK_2, &pm_ocm_ram_base->addr_match_2); - - /* IVA Changes */ - writel(UNLOCK_3, &pm_iva2_base->req_info_permission_0); - writel(UNLOCK_3, &pm_iva2_base->read_permission_0); - writel(UNLOCK_3, &pm_iva2_base->wirte_permission_0); - - /* SDRC region 0 public */ - writel(UNLOCK_1, &sms_base->rg_att0); -} - -/****************************************************************************** - * Routine: secureworld_exit() - * Description: If chip is EMU and boot type is external - * configure secure registers and exit secure world - * general use. - *****************************************************************************/ -void secureworld_exit() -{ - unsigned long i; - - /* configrue non-secure access control register */ - __asm__ __volatile__("mrc p15, 0, %0, c1, c1, 2":"=r"(i)); - /* enabling co-processor CP10 and CP11 accesses in NS world */ - __asm__ __volatile__("orr %0, %0, #0xC00":"=r"(i)); - /* - * allow allocation of locked TLBs and L2 lines in NS world - * allow use of PLE registers in NS world also - */ - __asm__ __volatile__("orr %0, %0, #0x70000":"=r"(i)); - __asm__ __volatile__("mcr p15, 0, %0, c1, c1, 2":"=r"(i)); - - /* Enable ASA in ACR register */ - __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1":"=r"(i)); - __asm__ __volatile__("orr %0, %0, #0x10":"=r"(i)); - __asm__ __volatile__("mcr p15, 0, %0, c1, c0, 1":"=r"(i)); - - /* Exiting secure world */ - __asm__ __volatile__("mrc p15, 0, %0, c1, c1, 0":"=r"(i)); - __asm__ __volatile__("orr %0, %0, #0x31":"=r"(i)); - __asm__ __volatile__("mcr p15, 0, %0, c1, c1, 0":"=r"(i)); -} - -/****************************************************************************** - * Routine: setup_auxcr() - * Description: Write to AuxCR desired value using SMI. - * general use. - *****************************************************************************/ -void setup_auxcr() -{ - unsigned long i; - volatile unsigned int j; - /* Save r0, r12 and restore them after usage */ - __asm__ __volatile__("mov %0, r12":"=r"(j)); - __asm__ __volatile__("mov %0, r0":"=r"(i)); - - /* - * GP Device ROM code API usage here - * r12 = AUXCR Write function and r0 value - */ - __asm__ __volatile__("mov r12, #0x3"); - __asm__ __volatile__("mrc p15, 0, r0, c1, c0, 1"); - /* Enabling ASA */ - __asm__ __volatile__("orr r0, r0, #0x10"); - /* Enable L1NEON */ - __asm__ __volatile__("orr r0, r0, #1 << 5"); - /* SMI instruction to call ROM Code API */ - __asm__ __volatile__(".word 0xE1600070"); - /* Set PLD_FWD bit in L2AUXCR (Cortex-A8 erratum 725233 workaround) */ - __asm__ __volatile__("mov r12, #0x2"); - __asm__ __volatile__("mrc p15, 1, r0, c9, c0, 2"); - __asm__ __volatile__("orr r0, r0, #1 << 27"); - /* SMI instruction to call ROM Code API */ - __asm__ __volatile__(".word 0xE1600070"); - __asm__ __volatile__("mov r0, %0":"=r"(i)); - __asm__ __volatile__("mov r12, %0":"=r"(j)); -} - -/****************************************************************************** - * Routine: try_unlock_sram() - * Description: If chip is GP/EMU(special) type, unlock the SRAM for - * general use. - *****************************************************************************/ -void try_unlock_memory() -{ - int mode; - int in_sdram = is_running_in_sdram(); - - /* - * if GP device unlock device SRAM for general use - * secure code breaks for Secure/Emulation device - HS/E/T - */ - mode = get_device_type(); - if (mode == GP_DEVICE) - secure_unlock_mem(); - - /* - * If device is EMU and boot is XIP external booting - * Unlock firewalls and disable L2 and put chip - * out of secure world - * - * Assuming memories are unlocked by the demon who put us in SDRAM - */ - if ((mode <= EMU_DEVICE) && (get_boot_type() == 0x1F) - && (!in_sdram)) { - secure_unlock_mem(); - secureworld_exit(); - } - - return; -} - -/****************************************************************************** - * Routine: s_init - * Description: Does early system init of muxing and clocks. - * - Called path is with SRAM stack. - *****************************************************************************/ -void s_init(void) -{ - int in_sdram = is_running_in_sdram(); - - watchdog_init(); - - try_unlock_memory(); - - /* - * Right now flushing at low MPU speed. - * Need to move after clock init - */ - invalidate_dcache(get_device_type()); -#ifndef CONFIG_ICACHE_OFF - icache_enable(); -#endif - -#ifdef CONFIG_L2_OFF - l2_cache_disable(); -#else - l2_cache_enable(); -#endif - /* - * Writing to AuxCR in U-boot using SMI for GP DEV - * Currently SMI in Kernel on ES2 devices seems to have an issue - * Once that is resolved, we can postpone this config to kernel - */ - if (get_device_type() == GP_DEVICE) - setup_auxcr(); - - set_muxconf_regs(); - delay(100); - - prcm_init(); - - per_clocks_enable(); - - if (!in_sdram) - sdrc_init(); -} - -/****************************************************************************** - * Routine: wait_for_command_complete - * Description: Wait for posting to finish on watchdog - *****************************************************************************/ -void wait_for_command_complete(struct watchdog *wd_base) -{ - int pending = 1; - do { - pending = readl(&wd_base->wwps); - } while (pending); -} - -/****************************************************************************** - * Routine: watchdog_init - * Description: Shut down watch dogs - *****************************************************************************/ -void watchdog_init(void) -{ - struct watchdog *wd2_base = (struct watchdog *)WD2_BASE; - struct prcm *prcm_base = (struct prcm *)PRCM_BASE; - - /* - * There are 3 watch dogs WD1=Secure, WD2=MPU, WD3=IVA. WD1 is - * either taken care of by ROM (HS/EMU) or not accessible (GP). - * We need to take care of WD2-MPU or take a PRCM reset. WD3 - * should not be running and does not generate a PRCM reset. - */ - - sr32(&prcm_base->fclken_wkup, 5, 1, 1); - sr32(&prcm_base->iclken_wkup, 5, 1, 1); - wait_on_value(ST_WDT2, 0x20, &prcm_base->idlest_wkup, 5); - - writel(WD_UNLOCK1, &wd2_base->wspr); - wait_for_command_complete(wd2_base); - writel(WD_UNLOCK2, &wd2_base->wspr); -} - -/****************************************************************************** - * Routine: dram_init - * Description: sets uboots idea of sdram size - *****************************************************************************/ -int dram_init(void) -{ - DECLARE_GLOBAL_DATA_PTR; - unsigned int size0 = 0, size1 = 0; - - /* - * If a second bank of DDR is attached to CS1 this is - * where it can be started. Early init code will init - * memory on CS0. - */ - if ((sysinfo.mtype == DDR_COMBO) || (sysinfo.mtype == DDR_STACKED)) { - do_sdrc_init(CS1, NOT_EARLY); - make_cs1_contiguous(); - } - - size0 = get_sdr_cs_size(CS0); - size1 = get_sdr_cs_size(CS1); - - gd->bd->bi_dram[0].start = PHYS_SDRAM_1; - gd->bd->bi_dram[0].size = size0; - gd->bd->bi_dram[1].start = PHYS_SDRAM_1 + get_sdr_cs_offset(CS1); - gd->bd->bi_dram[1].size = size1; - - return 0; -} - -/****************************************************************************** - * Dummy function to handle errors for EABI incompatibility - *****************************************************************************/ -void abort(void) -{ -} - -#ifdef CONFIG_NAND_OMAP_GPMC -/****************************************************************************** - * OMAP3 specific command to switch between NAND HW and SW ecc - *****************************************************************************/ -static int do_switch_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) -{ - if (argc != 2) - goto usage; - if (strncmp(argv[1], "hw", 2) == 0) - omap_nand_switch_ecc(1); - else if (strncmp(argv[1], "sw", 2) == 0) - omap_nand_switch_ecc(0); - else - goto usage; - - return 0; - -usage: - printf ("Usage: nandecc %s\n", cmdtp->usage); - return 1; -} - -U_BOOT_CMD( - nandecc, 2, 1, do_switch_ecc, - "switch OMAP3 NAND ECC calculation algorithm", - "[hw/sw] - Switch between NAND hardware (hw) or software (sw) ecc algorithm" -); - -#endif /* CONFIG_NAND_OMAP_GPMC */ - -#ifdef CONFIG_DISPLAY_BOARDINFO -/** - * Print board information - */ -int checkboard (void) -{ - char *mem_s ; - - if (is_mem_sdr()) - mem_s = "mSDR"; - else - mem_s = "LPDDR"; - - printf("%s + %s/%s\n", sysinfo.board_string, mem_s, - sysinfo.nand_string); - - return 0; -} -#endif /* CONFIG_DISPLAY_BOARDINFO */ diff --git a/cpu/arm_cortexa8/omap3/cache.S b/cpu/arm_cortexa8/omap3/cache.S deleted file mode 100644 index 0f63815359..0000000000 --- a/cpu/arm_cortexa8/omap3/cache.S +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2009 Wind River Systems, Inc. - * Tom Rix - * - * This file is based on and replaces the existing cache.c file - * The copyrights for the cache.c file are: - * - * (C) Copyright 2008 Texas Insturments - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include - -/* - * omap3 cache code - */ - -.align 5 -.global invalidate_dcache -.global l2_cache_enable -.global l2_cache_disable - -/* - * invalidate_dcache() - * - * Invalidate the whole D-cache. - * - * Corrupted registers: r0-r5, r7, r9-r11 - * - * - mm - mm_struct describing address space - */ -invalidate_dcache: - stmfd r13!, {r0 - r5, r7, r9 - r12, r14} - - mov r7, r0 @ take a backup of device type - cmp r0, #0x3 @ check if the device type is - @ GP - moveq r12, #0x1 @ set up to invalide L2 -smi: .word 0x01600070 @ Call SMI monitor (smieq) - cmp r7, #0x3 @ compare again in case its - @ lost - beq finished_inval @ if GP device, inval done - @ above - - mrc p15, 1, r0, c0, c0, 1 @ read clidr - ands r3, r0, #0x7000000 @ extract loc from clidr - mov r3, r3, lsr #23 @ left align loc bit field - beq finished_inval @ if loc is 0, then no need to - @ clean - mov r10, #0 @ start clean at cache level 0 -inval_loop1: - add r2, r10, r10, lsr #1 @ work out 3x current cache - @ level - mov r1, r0, lsr r2 @ extract cache type bits from - @ clidr - and r1, r1, #7 @ mask of the bits for current - @ cache only - cmp r1, #2 @ see what cache we have at - @ this level - blt skip_inval @ skip if no cache, or just - @ i-cache - mcr p15, 2, r10, c0, c0, 0 @ select current cache level - @ in cssr - mov r2, #0 @ operand for mcr SBZ - mcr p15, 0, r2, c7, c5, 4 @ flush prefetch buffer to - @ sych the new cssr&csidr, - @ with armv7 this is 'isb', - @ but we compile with armv5 - mrc p15, 1, r1, c0, c0, 0 @ read the new csidr - and r2, r1, #7 @ extract the length of the - @ cache lines - add r2, r2, #4 @ add 4 (line length offset) - ldr r4, =0x3ff - ands r4, r4, r1, lsr #3 @ find maximum number on the - @ way size - clz r5, r4 @ find bit position of way - @ size increment - ldr r7, =0x7fff - ands r7, r7, r1, lsr #13 @ extract max number of the - @ index size -inval_loop2: - mov r9, r4 @ create working copy of max - @ way size -inval_loop3: - orr r11, r10, r9, lsl r5 @ factor way and cache number - @ into r11 - orr r11, r11, r7, lsl r2 @ factor index number into r11 - mcr p15, 0, r11, c7, c6, 2 @ invalidate by set/way - subs r9, r9, #1 @ decrement the way - bge inval_loop3 - subs r7, r7, #1 @ decrement the index - bge inval_loop2 -skip_inval: - add r10, r10, #2 @ increment cache number - cmp r3, r10 - bgt inval_loop1 -finished_inval: - mov r10, #0 @ swith back to cache level 0 - mcr p15, 2, r10, c0, c0, 0 @ select current cache level - @ in cssr - mcr p15, 0, r10, c7, c5, 4 @ flush prefetch buffer, - @ with armv7 this is 'isb', - @ but we compile with armv5 - - ldmfd r13!, {r0 - r5, r7, r9 - r12, pc} - - -l2_cache_enable: - push {r0, r1, r2, lr} - @ ES2 onwards we can disable/enable L2 ourselves - bl get_cpu_rev - cmp r0, #CPU_3XX_ES20 - blt l2_cache_disable_EARLIER_THAN_ES2 - mrc 15, 0, r3, cr1, cr0, 1 - orr r3, r3, #2 - mcr 15, 0, r3, cr1, cr0, 1 - b l2_cache_enable_END -l2_cache_enable_EARLIER_THAN_ES2: - @ Save r0, r12 and restore them after usage - mov r3, ip - str r3, [sp, #4] - mov r3, r0 - @ - @ GP Device ROM code API usage here - @ r12 = AUXCR Write function and r0 value - @ - mov ip, #3 - mrc 15, 0, r0, cr1, cr0, 1 - orr r0, r0, #2 - @ SMI instruction to call ROM Code API - .word 0xe1600070 - mov r0, r3 - mov ip, r3 - str r3, [sp, #4] -l2_cache_enable_END: - pop {r1, r2, r3, pc} - - -l2_cache_disable: - push {r0, r1, r2, lr} - @ ES2 onwards we can disable/enable L2 ourselves - bl get_cpu_rev - cmp r0, #CPU_3XX_ES20 - blt l2_cache_disable_EARLIER_THAN_ES2 - mrc 15, 0, r3, cr1, cr0, 1 - bic r3, r3, #2 - mcr 15, 0, r3, cr1, cr0, 1 - b l2_cache_disable_END -l2_cache_disable_EARLIER_THAN_ES2: - @ Save r0, r12 and restore them after usage - mov r3, ip - str r3, [sp, #4] - mov r3, r0 - @ - @ GP Device ROM code API usage here - @ r12 = AUXCR Write function and r0 value - @ - mov ip, #3 - mrc 15, 0, r0, cr1, cr0, 1 - bic r0, r0, #2 - @ SMI instruction to call ROM Code API - .word 0xe1600070 - mov r0, r3 - mov ip, r3 - str r3, [sp, #4] -l2_cache_disable_END: - pop {r1, r2, r3, pc} diff --git a/cpu/arm_cortexa8/omap3/clock.c b/cpu/arm_cortexa8/omap3/clock.c deleted file mode 100644 index 6330c9e5da..0000000000 --- a/cpu/arm_cortexa8/omap3/clock.c +++ /dev/null @@ -1,416 +0,0 @@ -/* - * (C) Copyright 2008 - * Texas Instruments, - * - * Author : - * Manikandan Pillai - * - * Derived from Beagle Board and OMAP3 SDP code by - * Richard Woodruff - * Syed Mohammed Khasim - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/****************************************************************************** - * get_sys_clk_speed() - determine reference oscillator speed - * based on known 32kHz clock and gptimer. - *****************************************************************************/ -u32 get_osc_clk_speed(void) -{ - u32 start, cstart, cend, cdiff, cdiv, val; - struct prcm *prcm_base = (struct prcm *)PRCM_BASE; - struct prm *prm_base = (struct prm *)PRM_BASE; - struct gptimer *gpt1_base = (struct gptimer *)OMAP34XX_GPT1; - struct s32ktimer *s32k_base = (struct s32ktimer *)SYNC_32KTIMER_BASE; - - val = readl(&prm_base->clksrc_ctrl); - - if (val & SYSCLKDIV_2) - cdiv = 2; - else if (val & SYSCLKDIV_1) - cdiv = 1; - else - /* - * Should never reach here! (Assume divider as 1) - */ - cdiv = 1; - - /* enable timer2 */ - val = readl(&prcm_base->clksel_wkup) | CLKSEL_GPT1; - - /* select sys_clk for GPT1 */ - writel(val, &prcm_base->clksel_wkup); - - /* Enable I and F Clocks for GPT1 */ - val = readl(&prcm_base->iclken_wkup) | EN_GPT1 | EN_32KSYNC; - writel(val, &prcm_base->iclken_wkup); - - val = readl(&prcm_base->fclken_wkup) | EN_GPT1; - writel(val, &prcm_base->fclken_wkup); - - writel(0, &gpt1_base->tldr); /* start counting at 0 */ - writel(GPT_EN, &gpt1_base->tclr); /* enable clock */ - - /* enable 32kHz source, determine sys_clk via gauging */ - - /* start time in 20 cycles */ - start = 20 + readl(&s32k_base->s32k_cr); - - /* dead loop till start time */ - while (readl(&s32k_base->s32k_cr) < start); - - /* get start sys_clk count */ - cstart = readl(&gpt1_base->tcrr); - - /* wait for 40 cycles */ - while (readl(&s32k_base->s32k_cr) < (start + 20)) ; - cend = readl(&gpt1_base->tcrr); /* get end sys_clk count */ - cdiff = cend - cstart; /* get elapsed ticks */ - - if (cdiv == 2) - { - cdiff *= 2; - } - - /* based on number of ticks assign speed */ - if (cdiff > 19000) - return S38_4M; - else if (cdiff > 15200) - return S26M; - else if (cdiff > 13000) - return S24M; - else if (cdiff > 9000) - return S19_2M; - else if (cdiff > 7600) - return S13M; - else - return S12M; -} - -/****************************************************************************** - * get_sys_clkin_sel() - returns the sys_clkin_sel field value based on - * input oscillator clock frequency. - *****************************************************************************/ -void get_sys_clkin_sel(u32 osc_clk, u32 *sys_clkin_sel) -{ - switch(osc_clk) { - case S38_4M: - *sys_clkin_sel = 4; - break; - case S26M: - *sys_clkin_sel = 3; - break; - case S19_2M: - *sys_clkin_sel = 2; - break; - case S13M: - *sys_clkin_sel = 1; - break; - case S12M: - default: - *sys_clkin_sel = 0; - } -} - -/****************************************************************************** - * prcm_init() - inits clocks for PRCM as defined in clocks.h - * called from SRAM, or Flash (using temp SRAM stack). - *****************************************************************************/ -void prcm_init(void) -{ - void (*f_lock_pll) (u32, u32, u32, u32); - int xip_safe, p0, p1, p2, p3; - u32 osc_clk = 0, sys_clkin_sel; - u32 clk_index, sil_index = 0; - struct prm *prm_base = (struct prm *)PRM_BASE; - struct prcm *prcm_base = (struct prcm *)PRCM_BASE; - dpll_param *dpll_param_p; - - f_lock_pll = (void *) ((u32) &_end_vect - (u32) &_start + - SRAM_VECT_CODE); - - xip_safe = is_running_in_sram(); - - /* - * Gauge the input clock speed and find out the sys_clkin_sel - * value corresponding to the input clock. - */ - osc_clk = get_osc_clk_speed(); - get_sys_clkin_sel(osc_clk, &sys_clkin_sel); - - /* set input crystal speed */ - sr32(&prm_base->clksel, 0, 3, sys_clkin_sel); - - /* If the input clock is greater than 19.2M always divide/2 */ - if (sys_clkin_sel > 2) { - /* input clock divider */ - sr32(&prm_base->clksrc_ctrl, 6, 2, 2); - clk_index = sys_clkin_sel / 2; - } else { - /* input clock divider */ - sr32(&prm_base->clksrc_ctrl, 6, 2, 1); - clk_index = sys_clkin_sel; - } - - /* - * The DPLL tables are defined according to sysclk value and - * silicon revision. The clk_index value will be used to get - * the values for that input sysclk from the DPLL param table - * and sil_index will get the values for that SysClk for the - * appropriate silicon rev. - */ - if (get_cpu_rev()) - sil_index = 1; - - /* Unlock MPU DPLL (slows things down, and needed later) */ - sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOW_POWER_BYPASS); - wait_on_value(ST_MPU_CLK, 0, &prcm_base->idlest_pll_mpu, LDELAY); - - /* Getting the base address of Core DPLL param table */ - dpll_param_p = (dpll_param *) get_core_dpll_param(); - - /* Moving it to the right sysclk and ES rev base */ - dpll_param_p = dpll_param_p + 3 * clk_index + sil_index; - if (xip_safe) { - /* - * CORE DPLL - * sr32(CM_CLKSEL2_EMU) set override to work when asleep - */ - sr32(&prcm_base->clken_pll, 0, 3, PLL_FAST_RELOCK_BYPASS); - wait_on_value(ST_CORE_CLK, 0, &prcm_base->idlest_ckgen, - LDELAY); - - /* - * For OMAP3 ES1.0 Errata 1.50, default value directly doesn't - * work. write another value and then default value. - */ - - /* m3x2 */ - sr32(&prcm_base->clksel1_emu, 16, 5, CORE_M3X2 + 1); - /* m3x2 */ - sr32(&prcm_base->clksel1_emu, 16, 5, CORE_M3X2); - /* Set M2 */ - sr32(&prcm_base->clksel1_pll, 27, 2, dpll_param_p->m2); - /* Set M */ - sr32(&prcm_base->clksel1_pll, 16, 11, dpll_param_p->m); - /* Set N */ - sr32(&prcm_base->clksel1_pll, 8, 7, dpll_param_p->n); - /* 96M Src */ - sr32(&prcm_base->clksel1_pll, 6, 1, 0); - /* ssi */ - sr32(&prcm_base->clksel_core, 8, 4, CORE_SSI_DIV); - /* fsusb */ - sr32(&prcm_base->clksel_core, 4, 2, CORE_FUSB_DIV); - /* l4 */ - sr32(&prcm_base->clksel_core, 2, 2, CORE_L4_DIV); - /* l3 */ - sr32(&prcm_base->clksel_core, 0, 2, CORE_L3_DIV); - /* gfx */ - sr32(&prcm_base->clksel_gfx, 0, 3, GFX_DIV); - /* reset mgr */ - sr32(&prcm_base->clksel_wkup, 1, 2, WKUP_RSM); - /* FREQSEL */ - sr32(&prcm_base->clken_pll, 4, 4, dpll_param_p->fsel); - /* lock mode */ - sr32(&prcm_base->clken_pll, 0, 3, PLL_LOCK); - - wait_on_value(ST_CORE_CLK, 1, &prcm_base->idlest_ckgen, - LDELAY); - } else if (is_running_in_flash()) { - /* - * if running from flash, jump to small relocated code - * area in SRAM. - */ - p0 = readl(&prcm_base->clken_pll); - sr32(&p0, 0, 3, PLL_FAST_RELOCK_BYPASS); - sr32(&p0, 4, 4, dpll_param_p->fsel); /* FREQSEL */ - - p1 = readl(&prcm_base->clksel1_pll); - sr32(&p1, 27, 2, dpll_param_p->m2); /* Set M2 */ - sr32(&p1, 16, 11, dpll_param_p->m); /* Set M */ - sr32(&p1, 8, 7, dpll_param_p->n); /* Set N */ - sr32(&p1, 6, 1, 0); /* set source for 96M */ - - p2 = readl(&prcm_base->clksel_core); - sr32(&p2, 8, 4, CORE_SSI_DIV); /* ssi */ - sr32(&p2, 4, 2, CORE_FUSB_DIV); /* fsusb */ - sr32(&p2, 2, 2, CORE_L4_DIV); /* l4 */ - sr32(&p2, 0, 2, CORE_L3_DIV); /* l3 */ - - p3 = (u32)&prcm_base->idlest_ckgen; - - (*f_lock_pll) (p0, p1, p2, p3); - } - - /* PER DPLL */ - sr32(&prcm_base->clken_pll, 16, 3, PLL_STOP); - wait_on_value(ST_PERIPH_CLK, 0, &prcm_base->idlest_ckgen, LDELAY); - - /* Getting the base address to PER DPLL param table */ - - /* Set N */ - dpll_param_p = (dpll_param *) get_per_dpll_param(); - - /* Moving it to the right sysclk base */ - dpll_param_p = dpll_param_p + clk_index; - - /* - * Errata 1.50 Workaround for OMAP3 ES1.0 only - * If using default divisors, write default divisor + 1 - * and then the actual divisor value - */ - sr32(&prcm_base->clksel1_emu, 24, 5, PER_M6X2 + 1); /* set M6 */ - sr32(&prcm_base->clksel1_emu, 24, 5, PER_M6X2); /* set M6 */ - sr32(&prcm_base->clksel_cam, 0, 5, PER_M5X2 + 1); /* set M5 */ - sr32(&prcm_base->clksel_cam, 0, 5, PER_M5X2); /* set M5 */ - sr32(&prcm_base->clksel_dss, 0, 5, PER_M4X2 + 1); /* set M4 */ - sr32(&prcm_base->clksel_dss, 0, 5, PER_M4X2); /* set M4 */ - sr32(&prcm_base->clksel_dss, 8, 5, PER_M3X2 + 1); /* set M3 */ - sr32(&prcm_base->clksel_dss, 8, 5, PER_M3X2); /* set M3 */ - sr32(&prcm_base->clksel3_pll, 0, 5, dpll_param_p->m2 + 1); /* set M2 */ - sr32(&prcm_base->clksel3_pll, 0, 5, dpll_param_p->m2); /* set M2 */ - /* Workaround end */ - - sr32(&prcm_base->clksel2_pll, 8, 11, dpll_param_p->m); /* set m */ - sr32(&prcm_base->clksel2_pll, 0, 7, dpll_param_p->n); /* set n */ - sr32(&prcm_base->clken_pll, 20, 4, dpll_param_p->fsel); /* FREQSEL */ - sr32(&prcm_base->clken_pll, 16, 3, PLL_LOCK); /* lock mode */ - wait_on_value(ST_PERIPH_CLK, 2, &prcm_base->idlest_ckgen, LDELAY); - - /* Getting the base address to MPU DPLL param table */ - dpll_param_p = (dpll_param *) get_mpu_dpll_param(); - - /* Moving it to the right sysclk and ES rev base */ - dpll_param_p = dpll_param_p + 3 * clk_index + sil_index; - - /* MPU DPLL (unlocked already) */ - - /* Set M2 */ - sr32(&prcm_base->clksel2_pll_mpu, 0, 5, dpll_param_p->m2); - /* Set M */ - sr32(&prcm_base->clksel1_pll_mpu, 8, 11, dpll_param_p->m); - /* Set N */ - sr32(&prcm_base->clksel1_pll_mpu, 0, 7, dpll_param_p->n); - /* FREQSEL */ - sr32(&prcm_base->clken_pll_mpu, 4, 4, dpll_param_p->fsel); - /* lock mode */ - sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOCK); - wait_on_value(ST_MPU_CLK, 1, &prcm_base->idlest_pll_mpu, LDELAY); - - /* Getting the base address to IVA DPLL param table */ - dpll_param_p = (dpll_param *) get_iva_dpll_param(); - - /* Moving it to the right sysclk and ES rev base */ - dpll_param_p = dpll_param_p + 3 * clk_index + sil_index; - - /* IVA DPLL (set to 12*20=240MHz) */ - sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_STOP); - wait_on_value(ST_IVA2_CLK, 0, &prcm_base->idlest_pll_iva2, LDELAY); - /* set M2 */ - sr32(&prcm_base->clksel2_pll_iva2, 0, 5, dpll_param_p->m2); - /* set M */ - sr32(&prcm_base->clksel1_pll_iva2, 8, 11, dpll_param_p->m); - /* set N */ - sr32(&prcm_base->clksel1_pll_iva2, 0, 7, dpll_param_p->n); - /* FREQSEL */ - sr32(&prcm_base->clken_pll_iva2, 4, 4, dpll_param_p->fsel); - /* lock mode */ - sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_LOCK); - wait_on_value(ST_IVA2_CLK, 1, &prcm_base->idlest_pll_iva2, LDELAY); - - /* Set up GPTimers to sys_clk source only */ - sr32(&prcm_base->clksel_per, 0, 8, 0xff); - sr32(&prcm_base->clksel_wkup, 0, 1, 1); - - sdelay(5000); -} - -/****************************************************************************** - * peripheral_enable() - Enable the clks & power for perifs (GPT2, UART1,...) - *****************************************************************************/ -void per_clocks_enable(void) -{ - struct prcm *prcm_base = (struct prcm *)PRCM_BASE; - - /* Enable GP2 timer. */ - sr32(&prcm_base->clksel_per, 0, 1, 0x1); /* GPT2 = sys clk */ - sr32(&prcm_base->iclken_per, 3, 1, 0x1); /* ICKen GPT2 */ - sr32(&prcm_base->fclken_per, 3, 1, 0x1); /* FCKen GPT2 */ - -#ifdef CONFIG_SYS_NS16550 - /* Enable UART1 clocks */ - sr32(&prcm_base->fclken1_core, 13, 1, 0x1); - sr32(&prcm_base->iclken1_core, 13, 1, 0x1); - - /* UART 3 Clocks */ - sr32(&prcm_base->fclken_per, 11, 1, 0x1); - sr32(&prcm_base->iclken_per, 11, 1, 0x1); -#endif - -#ifdef CONFIG_OMAP3_GPIO_2 - sr32(&prcm_base->fclken_per, 13, 1, 1); - sr32(&prcm_base->iclken_per, 13, 1, 1); -#endif -#ifdef CONFIG_OMAP3_GPIO_3 - sr32(&prcm_base->fclken_per, 14, 1, 1); - sr32(&prcm_base->iclken_per, 14, 1, 1); -#endif -#ifdef CONFIG_OMAP3_GPIO_4 - sr32(&prcm_base->fclken_per, 15, 1, 1); - sr32(&prcm_base->iclken_per, 15, 1, 1); -#endif -#ifdef CONFIG_OMAP3_GPIO_5 - sr32(&prcm_base->fclken_per, 16, 1, 1); - sr32(&prcm_base->iclken_per, 16, 1, 1); -#endif -#ifdef CONFIG_OMAP3_GPIO_6 - sr32(&prcm_base->fclken_per, 17, 1, 1); - sr32(&prcm_base->iclken_per, 17, 1, 1); -#endif - -#ifdef CONFIG_DRIVER_OMAP34XX_I2C - /* Turn on all 3 I2C clocks */ - sr32(&prcm_base->fclken1_core, 15, 3, 0x7); - sr32(&prcm_base->iclken1_core, 15, 3, 0x7); /* I2C1,2,3 = on */ -#endif - /* Enable the ICLK for 32K Sync Timer as its used in udelay */ - sr32(&prcm_base->iclken_wkup, 2, 1, 0x1); - - sr32(&prcm_base->fclken_iva2, 0, 32, FCK_IVA2_ON); - sr32(&prcm_base->fclken1_core, 0, 32, FCK_CORE1_ON); - sr32(&prcm_base->iclken1_core, 0, 32, ICK_CORE1_ON); - sr32(&prcm_base->iclken2_core, 0, 32, ICK_CORE2_ON); - sr32(&prcm_base->fclken_wkup, 0, 32, FCK_WKUP_ON); - sr32(&prcm_base->iclken_wkup, 0, 32, ICK_WKUP_ON); - sr32(&prcm_base->fclken_dss, 0, 32, FCK_DSS_ON); - sr32(&prcm_base->iclken_dss, 0, 32, ICK_DSS_ON); - sr32(&prcm_base->fclken_cam, 0, 32, FCK_CAM_ON); - sr32(&prcm_base->iclken_cam, 0, 32, ICK_CAM_ON); - sr32(&prcm_base->fclken_per, 0, 32, FCK_PER_ON); - sr32(&prcm_base->iclken_per, 0, 32, ICK_PER_ON); - - sdelay(1000); -} diff --git a/cpu/arm_cortexa8/omap3/gpio.c b/cpu/arm_cortexa8/omap3/gpio.c deleted file mode 100644 index aeb6066d89..0000000000 --- a/cpu/arm_cortexa8/omap3/gpio.c +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (c) 2009 Wind River Systems, Inc. - * Tom Rix - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - * This work is derived from the linux 2.6.27 kernel source - * To fetch, use the kernel repository - * git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git - * Use the v2.6.27 tag. - * - * Below is the original's header including its copyright - * - * linux/arch/arm/plat-omap/gpio.c - * - * Support functions for OMAP GPIO - * - * Copyright (C) 2003-2005 Nokia Corporation - * Written by Juha Yrjölä - * - * 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. - */ -#include -#include -#include -#include - -static struct gpio_bank gpio_bank_34xx[6] = { - { (void *)OMAP34XX_GPIO1_BASE, METHOD_GPIO_24XX }, - { (void *)OMAP34XX_GPIO2_BASE, METHOD_GPIO_24XX }, - { (void *)OMAP34XX_GPIO3_BASE, METHOD_GPIO_24XX }, - { (void *)OMAP34XX_GPIO4_BASE, METHOD_GPIO_24XX }, - { (void *)OMAP34XX_GPIO5_BASE, METHOD_GPIO_24XX }, - { (void *)OMAP34XX_GPIO6_BASE, METHOD_GPIO_24XX }, -}; - -static struct gpio_bank *gpio_bank = &gpio_bank_34xx[0]; - -static inline struct gpio_bank *get_gpio_bank(int gpio) -{ - return &gpio_bank[gpio >> 5]; -} - -static inline int get_gpio_index(int gpio) -{ - return gpio & 0x1f; -} - -static inline int gpio_valid(int gpio) -{ - if (gpio < 0) - return -1; - if (gpio < 192) - return 0; - return -1; -} - -static int check_gpio(int gpio) -{ - if (gpio_valid(gpio) < 0) { - printf("ERROR : check_gpio: invalid GPIO %d\n", gpio); - return -1; - } - return 0; -} - -static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input) -{ - void *reg = bank->base; - u32 l; - - switch (bank->method) { - case METHOD_GPIO_24XX: - reg += OMAP24XX_GPIO_OE; - break; - default: - return; - } - l = __raw_readl(reg); - if (is_input) - l |= 1 << gpio; - else - l &= ~(1 << gpio); - __raw_writel(l, reg); -} - -void omap_set_gpio_direction(int gpio, int is_input) -{ - struct gpio_bank *bank; - - if (check_gpio(gpio) < 0) - return; - bank = get_gpio_bank(gpio); - _set_gpio_direction(bank, get_gpio_index(gpio), is_input); -} - -static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) -{ - void *reg = bank->base; - u32 l = 0; - - switch (bank->method) { - case METHOD_GPIO_24XX: - if (enable) - reg += OMAP24XX_GPIO_SETDATAOUT; - else - reg += OMAP24XX_GPIO_CLEARDATAOUT; - l = 1 << gpio; - break; - default: - printf("omap3-gpio unknown bank method %s %d\n", - __FILE__, __LINE__); - return; - } - __raw_writel(l, reg); -} - -void omap_set_gpio_dataout(int gpio, int enable) -{ - struct gpio_bank *bank; - - if (check_gpio(gpio) < 0) - return; - bank = get_gpio_bank(gpio); - _set_gpio_dataout(bank, get_gpio_index(gpio), enable); -} - -int omap_get_gpio_datain(int gpio) -{ - struct gpio_bank *bank; - void *reg; - - if (check_gpio(gpio) < 0) - return -EINVAL; - bank = get_gpio_bank(gpio); - reg = bank->base; - switch (bank->method) { - case METHOD_GPIO_24XX: - reg += OMAP24XX_GPIO_DATAIN; - break; - default: - return -EINVAL; - } - return (__raw_readl(reg) - & (1 << get_gpio_index(gpio))) != 0; -} - -static void _reset_gpio(struct gpio_bank *bank, int gpio) -{ - _set_gpio_direction(bank, get_gpio_index(gpio), 1); -} - -int omap_request_gpio(int gpio) -{ - if (check_gpio(gpio) < 0) - return -EINVAL; - - return 0; -} - -void omap_free_gpio(int gpio) -{ - struct gpio_bank *bank; - - if (check_gpio(gpio) < 0) - return; - bank = get_gpio_bank(gpio); - - _reset_gpio(bank, gpio); -} diff --git a/cpu/arm_cortexa8/omap3/lowlevel_init.S b/cpu/arm_cortexa8/omap3/lowlevel_init.S deleted file mode 100644 index 73063ec8e6..0000000000 --- a/cpu/arm_cortexa8/omap3/lowlevel_init.S +++ /dev/null @@ -1,361 +0,0 @@ -/* - * Board specific setup info - * - * (C) Copyright 2008 - * Texas Instruments, - * - * Initial Code by: - * Richard Woodruff - * Syed Mohammed Khasim - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include - -_TEXT_BASE: - .word TEXT_BASE /* sdram load addr from config.mk */ - -#if !defined(CONFIG_SYS_NAND_BOOT) && !defined(CONFIG_SYS_NAND_BOOT) -/************************************************************************** - * cpy_clk_code: relocates clock code into SRAM where its safer to execute - * R1 = SRAM destination address. - *************************************************************************/ -.global cpy_clk_code - cpy_clk_code: - /* Copy DPLL code into SRAM */ - adr r0, go_to_speed /* get addr of clock setting code */ - mov r2, #384 /* r2 size to copy (div by 32 bytes) */ - mov r1, r1 /* r1 <- dest address (passed in) */ - add r2, r2, r0 /* r2 <- source end address */ -next2: - ldmia r0!, {r3 - r10} /* copy from source address [r0] */ - stmia r1!, {r3 - r10} /* copy to target address [r1] */ - cmp r0, r2 /* until source end address [r2] */ - bne next2 - mov pc, lr /* back to caller */ - -/* *************************************************************************** - * go_to_speed: -Moves to bypass, -Commits clock dividers, -puts dpll at speed - * -executed from SRAM. - * R0 = CM_CLKEN_PLL-bypass value - * R1 = CM_CLKSEL1_PLL-m, n, and divider values - * R2 = CM_CLKSEL_CORE-divider values - * R3 = CM_IDLEST_CKGEN - addr dpll lock wait - * - * Note: If core unlocks/relocks and SDRAM is running fast already it gets - * confused. A reset of the controller gets it back. Taking away its - * L3 when its not in self refresh seems bad for it. Normally, this - * code runs from flash before SDR is init so that should be ok. - ****************************************************************************/ -.global go_to_speed - go_to_speed: - stmfd sp!, {r4 - r6} - - /* move into fast relock bypass */ - ldr r4, pll_ctl_add - str r0, [r4] -wait1: - ldr r5, [r3] /* get status */ - and r5, r5, #0x1 /* isolate core status */ - cmp r5, #0x1 /* still locked? */ - beq wait1 /* if lock, loop */ - - /* set new dpll dividers _after_ in bypass */ - ldr r5, pll_div_add1 - str r1, [r5] /* set m, n, m2 */ - ldr r5, pll_div_add2 - str r2, [r5] /* set l3/l4/.. dividers*/ - ldr r5, pll_div_add3 /* wkup */ - ldr r2, pll_div_val3 /* rsm val */ - str r2, [r5] - ldr r5, pll_div_add4 /* gfx */ - ldr r2, pll_div_val4 - str r2, [r5] - ldr r5, pll_div_add5 /* emu */ - ldr r2, pll_div_val5 - str r2, [r5] - - /* now prepare GPMC (flash) for new dpll speed */ - /* flash needs to be stable when we jump back to it */ - ldr r5, flash_cfg3_addr - ldr r2, flash_cfg3_val - str r2, [r5] - ldr r5, flash_cfg4_addr - ldr r2, flash_cfg4_val - str r2, [r5] - ldr r5, flash_cfg5_addr - ldr r2, flash_cfg5_val - str r2, [r5] - ldr r5, flash_cfg1_addr - ldr r2, [r5] - orr r2, r2, #0x3 /* up gpmc divider */ - str r2, [r5] - - /* lock DPLL3 and wait a bit */ - orr r0, r0, #0x7 /* set up for lock mode */ - str r0, [r4] /* lock */ - nop /* ARM slow at this point working at sys_clk */ - nop - nop - nop -wait2: - ldr r5, [r3] /* get status */ - and r5, r5, #0x1 /* isolate core status */ - cmp r5, #0x1 /* still locked? */ - bne wait2 /* if lock, loop */ - nop - nop - nop - nop - ldmfd sp!, {r4 - r6} - mov pc, lr /* back to caller, locked */ - -_go_to_speed: .word go_to_speed - -/* these constants need to be close for PIC code */ -/* The Nor has to be in the Flash Base CS0 for this condition to happen */ -flash_cfg1_addr: - .word (GPMC_CONFIG_CS0_BASE + GPMC_CONFIG1) -flash_cfg3_addr: - .word (GPMC_CONFIG_CS0_BASE + GPMC_CONFIG3) -flash_cfg3_val: - .word STNOR_GPMC_CONFIG3 -flash_cfg4_addr: - .word (GPMC_CONFIG_CS0_BASE + GPMC_CONFIG4) -flash_cfg4_val: - .word STNOR_GPMC_CONFIG4 -flash_cfg5_val: - .word STNOR_GPMC_CONFIG5 -flash_cfg5_addr: - .word (GPMC_CONFIG_CS0_BASE + GPMC_CONFIG5) -pll_ctl_add: - .word CM_CLKEN_PLL -pll_div_add1: - .word CM_CLKSEL1_PLL -pll_div_add2: - .word CM_CLKSEL_CORE -pll_div_add3: - .word CM_CLKSEL_WKUP -pll_div_val3: - .word (WKUP_RSM << 1) -pll_div_add4: - .word CM_CLKSEL_GFX -pll_div_val4: - .word (GFX_DIV << 0) -pll_div_add5: - .word CM_CLKSEL1_EMU -pll_div_val5: - .word CLSEL1_EMU_VAL - -#endif - -.globl lowlevel_init -lowlevel_init: - ldr sp, SRAM_STACK - str ip, [sp] /* stash old link register */ - mov ip, lr /* save link reg across call */ - bl s_init /* go setup pll, mux, memory */ - ldr ip, [sp] /* restore save ip */ - mov lr, ip /* restore link reg */ - - /* back to arch calling code */ - mov pc, lr - - /* the literal pools origin */ - .ltorg - -REG_CONTROL_STATUS: - .word CONTROL_STATUS -SRAM_STACK: - .word LOW_LEVEL_SRAM_STACK - -/* DPLL(1-4) PARAM TABLES */ - -/* - * Each of the tables has M, N, FREQSEL, M2 values defined for nominal - * OPP (1.2V). The fields are defined according to dpll_param struct (clock.c). - * The values are defined for all possible sysclk and for ES1 and ES2. - */ - -mpu_dpll_param: -/* 12MHz */ -/* ES1 */ -.word MPU_M_12_ES1, MPU_N_12_ES1, MPU_FSEL_12_ES1, MPU_M2_12_ES1 -/* ES2 */ -.word MPU_M_12_ES2, MPU_N_12_ES2, MPU_FSEL_12_ES2, MPU_M2_ES2 -/* 3410 */ -.word MPU_M_12, MPU_N_12, MPU_FSEL_12, MPU_M2_12 - -/* 13MHz */ -/* ES1 */ -.word MPU_M_13_ES1, MPU_N_13_ES1, MPU_FSEL_13_ES1, MPU_M2_13_ES1 -/* ES2 */ -.word MPU_M_13_ES2, MPU_N_13_ES2, MPU_FSEL_13_ES2, MPU_M2_13_ES2 -/* 3410 */ -.word MPU_M_13, MPU_N_13, MPU_FSEL_13, MPU_M2_13 - -/* 19.2MHz */ -/* ES1 */ -.word MPU_M_19P2_ES1, MPU_N_19P2_ES1, MPU_FSEL_19P2_ES1, MPU_M2_19P2_ES1 -/* ES2 */ -.word MPU_M_19P2_ES2, MPU_N_19P2_ES2, MPU_FSEL_19P2_ES2, MPU_M2_19P2_ES2 -/* 3410 */ -.word MPU_M_19P2, MPU_N_19P2, MPU_FSEL_19P2, MPU_M2_19P2 - -/* 26MHz */ -/* ES1 */ -.word MPU_M_26_ES1, MPU_N_26_ES1, MPU_FSEL_26_ES1, MPU_M2_26_ES1 -/* ES2 */ -.word MPU_M_26_ES2, MPU_N_26_ES2, MPU_FSEL_26_ES2, MPU_M2_26_ES2 -/* 3410 */ -.word MPU_M_26, MPU_N_26, MPU_FSEL_26, MPU_M2_26 - -/* 38.4MHz */ -/* ES1 */ -.word MPU_M_38P4_ES1, MPU_N_38P4_ES1, MPU_FSEL_38P4_ES1, MPU_M2_38P4_ES1 -/* ES2 */ -.word MPU_M_38P4_ES2, MPU_N_38P4_ES2, MPU_FSEL_38P4_ES2, MPU_M2_38P4_ES2 -/* 3410 */ -.word MPU_M_38P4, MPU_N_38P4, MPU_FSEL_38P4, MPU_M2_38P4 - - -.globl get_mpu_dpll_param -get_mpu_dpll_param: - adr r0, mpu_dpll_param - mov pc, lr - -iva_dpll_param: -/* 12MHz */ -/* ES1 */ -.word IVA_M_12_ES1, IVA_N_12_ES1, IVA_FSEL_12_ES1, IVA_M2_12_ES1 -/* ES2 */ -.word IVA_M_12_ES2, IVA_N_12_ES2, IVA_FSEL_12_ES2, IVA_M2_12_ES2 -/* 3410 */ -.word IVA_M_12, IVA_N_12, IVA_FSEL_12, IVA_M2_12 - -/* 13MHz */ -/* ES1 */ -.word IVA_M_13_ES1, IVA_N_13_ES1, IVA_FSEL_13_ES1, IVA_M2_13_ES1 -/* ES2 */ -.word IVA_M_13_ES2, IVA_N_13_ES2, IVA_FSEL_13_ES2, IVA_M2_13_ES2 -/* 3410 */ -.word IVA_M_13, IVA_N_13, IVA_FSEL_13, IVA_M2_13 - -/* 19.2MHz */ -/* ES1 */ -.word IVA_M_19P2_ES1, IVA_N_19P2_ES1, IVA_FSEL_19P2_ES1, IVA_M2_19P2_ES1 -/* ES2 */ -.word IVA_M_19P2_ES2, IVA_N_19P2_ES2, IVA_FSEL_19P2_ES2, IVA_M2_19P2_ES2 -/* 3410 */ -.word IVA_M_19P2, IVA_N_19P2, IVA_FSEL_19P2, IVA_M2_19P2 - -/* 26MHz */ -/* ES1 */ -.word IVA_M_26_ES1, IVA_N_26_ES1, IVA_FSEL_26_ES1, IVA_M2_26_ES1 -/* ES2 */ -.word IVA_M_26_ES2, IVA_N_26_ES2, IVA_FSEL_26_ES2, IVA_M2_26_ES2 -/* 3410 */ -.word IVA_M_26, IVA_N_26, IVA_FSEL_26, IVA_M2_26 - -/* 38.4MHz */ -/* ES1 */ -.word IVA_M_38P4_ES1, IVA_N_38P4_ES1, IVA_FSEL_38P4_ES1, IVA_M2_38P4_ES1 -/* ES2 */ -.word IVA_M_38P4_ES2, IVA_N_38P4_ES2, IVA_FSEL_38P4_ES2, IVA_M2_38P4_ES2 -/* 3410 */ -.word IVA_M_38P4, IVA_N_38P4, IVA_FSEL_38P4, IVA_M2_38P4 - - -.globl get_iva_dpll_param -get_iva_dpll_param: - adr r0, iva_dpll_param - mov pc, lr - -/* Core DPLL targets for L3 at 166 & L133 */ -core_dpll_param: -/* 12MHz */ -/* ES1 */ -.word CORE_M_12_ES1, CORE_N_12_ES1, CORE_FSL_12_ES1, CORE_M2_12_ES1 -/* ES2 */ -.word CORE_M_12, CORE_N_12, CORE_FSEL_12, CORE_M2_12 -/* 3410 */ -.word CORE_M_12, CORE_N_12, CORE_FSEL_12, CORE_M2_12 - -/* 13MHz */ -/* ES1 */ -.word CORE_M_13_ES1, CORE_N_13_ES1, CORE_FSL_13_ES1, CORE_M2_13_ES1 -/* ES2 */ -.word CORE_M_13, CORE_N_13, CORE_FSEL_13, CORE_M2_13 -/* 3410 */ -.word CORE_M_13, CORE_N_13, CORE_FSEL_13, CORE_M2_13 - -/* 19.2MHz */ -/* ES1 */ -.word CORE_M_19P2_ES1, CORE_N_19P2_ES1, CORE_FSL_19P2_ES1, CORE_M2_19P2_ES1 -/* ES2 */ -.word CORE_M_19P2, CORE_N_19P2, CORE_FSEL_19P2, CORE_M2_19P2 -/* 3410 */ -.word CORE_M_19P2, CORE_N_19P2, CORE_FSEL_19P2, CORE_M2_19P2 - -/* 26MHz */ -/* ES1 */ -.word CORE_M_26_ES1, CORE_N_26_ES1, CORE_FSL_26_ES1, CORE_M2_26_ES1 -/* ES2 */ -.word CORE_M_26, CORE_N_26, CORE_FSEL_26, CORE_M2_26 -/* 3410 */ -.word CORE_M_26, CORE_N_26, CORE_FSEL_26, CORE_M2_26 - -/* 38.4MHz */ -/* ES1 */ -.word CORE_M_38P4_ES1, CORE_N_38P4_ES1, CORE_FSL_38P4_ES1, CORE_M2_38P4_ES1 -/* ES2 */ -.word CORE_M_38P4, CORE_N_38P4, CORE_FSEL_38P4, CORE_M2_38P4 -/* 3410 */ -.word CORE_M_38P4, CORE_N_38P4, CORE_FSEL_38P4, CORE_M2_38P4 - -.globl get_core_dpll_param -get_core_dpll_param: - adr r0, core_dpll_param - mov pc, lr - -/* PER DPLL values are same for both ES1 and ES2 */ -per_dpll_param: -/* 12MHz */ -.word PER_M_12, PER_N_12, PER_FSEL_12, PER_M2_12 - -/* 13MHz */ -.word PER_M_13, PER_N_13, PER_FSEL_13, PER_M2_13 - -/* 19.2MHz */ -.word PER_M_19P2, PER_N_19P2, PER_FSEL_19P2, PER_M2_19P2 - -/* 26MHz */ -.word PER_M_26, PER_N_26, PER_FSEL_26, PER_M2_26 - -/* 38.4MHz */ -.word PER_M_38P4, PER_N_38P4, PER_FSEL_38P4, PER_M2_38P4 - -.globl get_per_dpll_param -get_per_dpll_param: - adr r0, per_dpll_param - mov pc, lr diff --git a/cpu/arm_cortexa8/omap3/mem.c b/cpu/arm_cortexa8/omap3/mem.c deleted file mode 100644 index dfb7e4c2ad..0000000000 --- a/cpu/arm_cortexa8/omap3/mem.c +++ /dev/null @@ -1,281 +0,0 @@ -/* - * (C) Copyright 2008 - * Texas Instruments, - * - * Author : - * Manikandan Pillai - * - * Initial Code from: - * Richard Woodruff - * Syed Mohammed Khasim - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include - -/* - * Only One NAND allowed on board at a time. - * The GPMC CS Base for the same - */ -unsigned int boot_flash_base; -unsigned int boot_flash_off; -unsigned int boot_flash_sec; -unsigned int boot_flash_type; -volatile unsigned int boot_flash_env_addr; - -struct gpmc *gpmc_cfg; - -#if defined(CONFIG_CMD_NAND) -static const u32 gpmc_m_nand[GPMC_MAX_REG] = { - M_NAND_GPMC_CONFIG1, - M_NAND_GPMC_CONFIG2, - M_NAND_GPMC_CONFIG3, - M_NAND_GPMC_CONFIG4, - M_NAND_GPMC_CONFIG5, - M_NAND_GPMC_CONFIG6, 0 -}; - -#if defined(CONFIG_ENV_IS_IN_NAND) -#define GPMC_CS 0 -#else -#define GPMC_CS 1 -#endif - -#endif - -#if defined(CONFIG_CMD_ONENAND) -static const u32 gpmc_onenand[GPMC_MAX_REG] = { - ONENAND_GPMC_CONFIG1, - ONENAND_GPMC_CONFIG2, - ONENAND_GPMC_CONFIG3, - ONENAND_GPMC_CONFIG4, - ONENAND_GPMC_CONFIG5, - ONENAND_GPMC_CONFIG6, 0 -}; - -#if defined(CONFIG_ENV_IS_IN_ONENAND) -#define GPMC_CS 0 -#else -#define GPMC_CS 1 -#endif - -#endif - -static struct sdrc *sdrc_base = (struct sdrc *)OMAP34XX_SDRC_BASE; - -/************************************************************************** - * make_cs1_contiguous() - for es2 and above remap cs1 behind cs0 to allow - * command line mem=xyz use all memory with out discontinuous support - * compiled in. Could do it at the ATAG, but there really is two banks... - * Called as part of 2nd phase DDR init. - **************************************************************************/ -void make_cs1_contiguous(void) -{ - u32 size, a_add_low, a_add_high; - - size = get_sdr_cs_size(CS0); - size >>= 25; /* divide by 32 MiB to find size to offset CS1 */ - a_add_high = (size & 3) << 8; /* set up low field */ - a_add_low = (size & 0x3C) >> 2; /* set up high field */ - writel((a_add_high | a_add_low), &sdrc_base->cs_cfg); - -} - -/******************************************************** - * mem_ok() - test used to see if timings are correct - * for a part. Helps in guessing which part - * we are currently using. - *******************************************************/ -u32 mem_ok(u32 cs) -{ - u32 val1, val2, addr; - u32 pattern = 0x12345678; - - addr = OMAP34XX_SDRC_CS0 + get_sdr_cs_offset(cs); - - writel(0x0, addr + 0x400); /* clear pos A */ - writel(pattern, addr); /* pattern to pos B */ - writel(0x0, addr + 4); /* remove pattern off the bus */ - val1 = readl(addr + 0x400); /* get pos A value */ - val2 = readl(addr); /* get val2 */ - - if ((val1 != 0) || (val2 != pattern)) /* see if pos A val changed */ - return 0; - else - return 1; -} - -/******************************************************** - * sdrc_init() - init the sdrc chip selects CS0 and CS1 - * - early init routines, called from flash or - * SRAM. - *******************************************************/ -void sdrc_init(void) -{ - /* only init up first bank here */ - do_sdrc_init(CS0, EARLY_INIT); -} - -/************************************************************************* - * do_sdrc_init(): initialize the SDRAM for use. - * -code sets up SDRAM basic SDRC timings for CS0 - * -optimal settings can be placed here, or redone after i2c - * inspection of board info - * - * - code called once in C-Stack only context for CS0 and a possible 2nd - * time depending on memory configuration from stack+global context - **************************************************************************/ - -void do_sdrc_init(u32 cs, u32 early) -{ - struct sdrc_actim *sdrc_actim_base; - - if(cs) - sdrc_actim_base = (struct sdrc_actim *)SDRC_ACTIM_CTRL1_BASE; - else - sdrc_actim_base = (struct sdrc_actim *)SDRC_ACTIM_CTRL0_BASE; - - if (early) { - /* reset sdrc controller */ - writel(SOFTRESET, &sdrc_base->sysconfig); - wait_on_value(RESETDONE, RESETDONE, &sdrc_base->status, - 12000000); - writel(0, &sdrc_base->sysconfig); - - /* setup sdrc to ball mux */ - writel(SDRC_SHARING, &sdrc_base->sharing); - - /* Disable Power Down of CKE cuz of 1 CKE on combo part */ - writel(WAKEUPPROC | PWDNEN | SRFRONRESET | PAGEPOLICY_HIGH, - &sdrc_base->power); - - writel(ENADLL | DLLPHASE_90, &sdrc_base->dlla_ctrl); - sdelay(0x20000); - } - - writel(RASWIDTH_13BITS | CASWIDTH_10BITS | ADDRMUXLEGACY | - RAMSIZE_128 | BANKALLOCATION | B32NOT16 | B32NOT16 | - DEEPPD | DDR_SDRAM, &sdrc_base->cs[cs].mcfg); - writel(ARCV | ARE_ARCV_1, &sdrc_base->cs[cs].rfr_ctrl); - writel(V_ACTIMA_165, &sdrc_actim_base->ctrla); - writel(V_ACTIMB_165, &sdrc_actim_base->ctrlb); - - writel(CMD_NOP, &sdrc_base ->cs[cs].manual); - writel(CMD_PRECHARGE, &sdrc_base->cs[cs].manual); - writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual); - writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual); - - /* - * CAS latency 3, Write Burst = Read Burst, Serial Mode, - * Burst length = 4 - */ - writel(CASL3 | BURSTLENGTH4, &sdrc_base->cs[cs].mr); - - if (!mem_ok(cs)) - writel(0, &sdrc_base->cs[cs].mcfg); -} - -void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base, - u32 size) -{ - writel(0, &cs->config7); - sdelay(1000); - /* Delay for settling */ - writel(gpmc_config[0], &cs->config1); - writel(gpmc_config[1], &cs->config2); - writel(gpmc_config[2], &cs->config3); - writel(gpmc_config[3], &cs->config4); - writel(gpmc_config[4], &cs->config5); - writel(gpmc_config[5], &cs->config6); - /* Enable the config */ - writel((((size & 0xF) << 8) | ((base >> 24) & 0x3F) | - (1 << 6)), &cs->config7); - sdelay(2000); -} - -/***************************************************** - * gpmc_init(): init gpmc bus - * Init GPMC for x16, MuxMode (SDRAM in x32). - * This code can only be executed from SRAM or SDRAM. - *****************************************************/ -void gpmc_init(void) -{ - /* putting a blanket check on GPMC based on ZeBu for now */ - gpmc_cfg = (struct gpmc *)GPMC_BASE; -#if defined(CONFIG_CMD_NAND) || defined(CONFIG_CMD_ONENAND) - const u32 *gpmc_config = NULL; - u32 base = 0; - u32 size = 0; -#if defined(CONFIG_ENV_IS_IN_NAND) || defined(CONFIG_ENV_IS_IN_ONENAND) - u32 f_off = CONFIG_SYS_MONITOR_LEN; - u32 f_sec = 0; -#endif -#endif - u32 config = 0; - - /* global settings */ - writel(0, &gpmc_cfg->irqenable); /* isr's sources masked */ - writel(0, &gpmc_cfg->timeout_control);/* timeout disable */ - - config = readl(&gpmc_cfg->config); - config &= (~0xf00); - writel(config, &gpmc_cfg->config); - - /* - * Disable the GPMC0 config set by ROM code - * It conflicts with our MPDB (both at 0x08000000) - */ - writel(0, &gpmc_cfg->cs[0].config7); - sdelay(1000); - -#if defined(CONFIG_CMD_NAND) /* CS 0 */ - gpmc_config = gpmc_m_nand; - - base = PISMO1_NAND_BASE; - size = PISMO1_NAND_SIZE; - enable_gpmc_cs_config(gpmc_config, &gpmc_cfg->cs[0], base, size); -#if defined(CONFIG_ENV_IS_IN_NAND) - f_off = SMNAND_ENV_OFFSET; - f_sec = (128 << 10); /* 128 KiB */ - /* env setup */ - boot_flash_base = base; - boot_flash_off = f_off; - boot_flash_sec = f_sec; - boot_flash_env_addr = f_off; -#endif -#endif - -#if defined(CONFIG_CMD_ONENAND) - gpmc_config = gpmc_onenand; - base = PISMO1_ONEN_BASE; - size = PISMO1_ONEN_SIZE; - enable_gpmc_cs_config(gpmc_config, &gpmc_cfg->cs[0], base, size); -#if defined(CONFIG_ENV_IS_IN_ONENAND) - f_off = ONENAND_ENV_OFFSET; - f_sec = (128 << 10); /* 128 KiB */ - /* env setup */ - boot_flash_base = base; - boot_flash_off = f_off; - boot_flash_sec = f_sec; - boot_flash_env_addr = f_off; -#endif -#endif -} diff --git a/cpu/arm_cortexa8/omap3/reset.S b/cpu/arm_cortexa8/omap3/reset.S deleted file mode 100644 index a53c408195..0000000000 --- a/cpu/arm_cortexa8/omap3/reset.S +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2009 Samsung Electronics. - * Minkyu Kang - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include - -.global reset_cpu -reset_cpu: - ldr r1, rstctl @ get addr for global reset - @ reg - mov r3, #0x2 @ full reset pll + mpu - str r3, [r1] @ force reset - mov r0, r0 -_loop_forever: - b _loop_forever -rstctl: - .word PRM_RSTCTRL diff --git a/cpu/arm_cortexa8/omap3/sys_info.c b/cpu/arm_cortexa8/omap3/sys_info.c deleted file mode 100644 index 08fb32eaae..0000000000 --- a/cpu/arm_cortexa8/omap3/sys_info.c +++ /dev/null @@ -1,299 +0,0 @@ -/* - * (C) Copyright 2008 - * Texas Instruments, - * - * Author : - * Manikandan Pillai - * - * Derived from Beagle Board and 3430 SDP code by - * Richard Woodruff - * Syed Mohammed Khasim - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include /* get mem tables */ -#include -#include - -extern omap3_sysinfo sysinfo; -static struct sdrc *sdrc_base = (struct sdrc *)OMAP34XX_SDRC_BASE; -static struct ctrl *ctrl_base = (struct ctrl *)OMAP34XX_CTRL_BASE; -static char *rev_s[CPU_3XX_MAX_REV] = { - "1.0", - "2.0", - "2.1", - "3.0", - "3.1"}; - -/***************************************************************** - * dieid_num_r(void) - read and set die ID - *****************************************************************/ -void dieid_num_r(void) -{ - struct ctrl_id *id_base = (struct ctrl_id *)OMAP34XX_ID_L4_IO_BASE; - char *uid_s, die_id[34]; - u32 id[4]; - - memset(die_id, 0, sizeof(die_id)); - - uid_s = getenv("dieid#"); - - if (uid_s == NULL) { - id[3] = readl(&id_base->die_id_0); - id[2] = readl(&id_base->die_id_1); - id[1] = readl(&id_base->die_id_2); - id[0] = readl(&id_base->die_id_3); - sprintf(die_id, "%08x%08x%08x%08x", id[0], id[1], id[2], id[3]); - setenv("dieid#", die_id); - uid_s = die_id; - } - - printf("Die ID #%s\n", uid_s); -} - -/****************************************** - * get_cpu_type(void) - extract cpu info - ******************************************/ -u32 get_cpu_type(void) -{ - return readl(&ctrl_base->ctrl_omap_stat); -} - -/****************************************** - * get_cpu_rev(void) - extract version info - ******************************************/ -u32 get_cpu_rev(void) -{ - u32 cpuid = 0; - struct ctrl_id *id_base; - - /* - * On ES1.0 the IDCODE register is not exposed on L4 - * so using CPU ID to differentiate between ES1.0 and > ES1.0. - */ - __asm__ __volatile__("mrc p15, 0, %0, c0, c0, 0":"=r"(cpuid)); - if ((cpuid & 0xf) == 0x0) - return CPU_3XX_ES10; - else { - /* Decode the IDs on > ES1.0 */ - id_base = (struct ctrl_id *) OMAP34XX_ID_L4_IO_BASE; - - cpuid = (readl(&id_base->idcode) >> CPU_3XX_ID_SHIFT) & 0xf; - - /* Some early ES2.0 seem to report ID 0, fix this */ - if(cpuid == 0) - cpuid = CPU_3XX_ES20; - - return cpuid; - } -} - -/**************************************************** - * is_mem_sdr() - return 1 if mem type in use is SDR - ****************************************************/ -u32 is_mem_sdr(void) -{ - if (readl(&sdrc_base->cs[CS0].mr) == SDRC_MR_0_SDR) - return 1; - return 0; -} - -/*********************************************************************** - * get_cs0_size() - get size of chip select 0/1 - ************************************************************************/ -u32 get_sdr_cs_size(u32 cs) -{ - u32 size; - - /* get ram size field */ - size = readl(&sdrc_base->cs[cs].mcfg) >> 8; - size &= 0x3FF; /* remove unwanted bits */ - size <<= 21; /* multiply by 2 MiB to find size in MB */ - return size; -} - -/*********************************************************************** - * get_sdr_cs_offset() - get offset of cs from cs0 start - ************************************************************************/ -u32 get_sdr_cs_offset(u32 cs) -{ - u32 offset; - - if (!cs) - return 0; - - offset = readl(&sdrc_base->cs_cfg); - offset = (offset & 15) << 27 | (offset & 0x30) >> 17; - - return offset; -} - -/*************************************************************************** - * get_gpmc0_base() - Return current address hardware will be - * fetching from. The below effectively gives what is correct, its a bit - * mis-leading compared to the TRM. For the most general case the mask - * needs to be also taken into account this does work in practice. - * - for u-boot we currently map: - * -- 0 to nothing, - * -- 4 to flash - * -- 8 to enent - * -- c to wifi - ****************************************************************************/ -u32 get_gpmc0_base(void) -{ - u32 b; - - b = readl(&gpmc_cfg->cs[0].config7); - b &= 0x1F; /* keep base [5:0] */ - b = b << 24; /* ret 0x0b000000 */ - return b; -} - -/******************************************************************* - * get_gpmc0_width() - See if bus is in x8 or x16 (mainly for nand) - *******************************************************************/ -u32 get_gpmc0_width(void) -{ - return WIDTH_16BIT; -} - -/************************************************************************* - * get_board_rev() - setup to pass kernel board revision information - * returns:(bit[0-3] sub version, higher bit[7-4] is higher version) - *************************************************************************/ -u32 get_board_rev(void) -{ - return 0x20; -} - -/******************************************************** - * get_base(); get upper addr of current execution - *******************************************************/ -u32 get_base(void) -{ - u32 val; - - __asm__ __volatile__("mov %0, pc \n":"=r"(val)::"memory"); - val &= 0xF0000000; - val >>= 28; - return val; -} - -/******************************************************** - * is_running_in_flash() - tell if currently running in - * FLASH. - *******************************************************/ -u32 is_running_in_flash(void) -{ - if (get_base() < 4) - return 1; /* in FLASH */ - - return 0; /* running in SRAM or SDRAM */ -} - -/******************************************************** - * is_running_in_sram() - tell if currently running in - * SRAM. - *******************************************************/ -u32 is_running_in_sram(void) -{ - if (get_base() == 4) - return 1; /* in SRAM */ - - return 0; /* running in FLASH or SDRAM */ -} - -/******************************************************** - * is_running_in_sdram() - tell if currently running in - * SDRAM. - *******************************************************/ -u32 is_running_in_sdram(void) -{ - if (get_base() > 4) - return 1; /* in SDRAM */ - - return 0; /* running in SRAM or FLASH */ -} - -/*************************************************************** - * get_boot_type() - Is this an XIP type device or a stream one - * bits 4-0 specify type. Bit 5 says mem/perif - ***************************************************************/ -u32 get_boot_type(void) -{ - return (readl(&ctrl_base->status) & SYSBOOT_MASK); -} - -/************************************************************* - * get_device_type(): tell if GP/HS/EMU/TST - *************************************************************/ -u32 get_device_type(void) -{ - return ((readl(&ctrl_base->status) & (DEVICE_MASK)) >> 8); -} - -#ifdef CONFIG_DISPLAY_CPUINFO -/** - * Print CPU information - */ -int print_cpuinfo (void) -{ - char *cpu_s, *sec_s; - - switch (get_cpu_type()) { - case OMAP3503: - cpu_s = "3503"; - break; - case OMAP3515: - cpu_s = "3515"; - break; - case OMAP3525: - cpu_s = "3525"; - break; - case OMAP3530: - cpu_s = "3530"; - break; - default: - cpu_s = "35XX"; - break; - } - - switch (get_device_type()) { - case TST_DEVICE: - sec_s = "TST"; - break; - case EMU_DEVICE: - sec_s = "EMU"; - break; - case HS_DEVICE: - sec_s = "HS"; - break; - case GP_DEVICE: - sec_s = "GP"; - break; - default: - sec_s = "?"; - } - - printf("OMAP%s-%s ES%s, CPU-OPP2 L3-165MHz\n", - cpu_s, sec_s, rev_s[get_cpu_rev()]); - - return 0; -} -#endif /* CONFIG_DISPLAY_CPUINFO */ diff --git a/cpu/arm_cortexa8/omap3/syslib.c b/cpu/arm_cortexa8/omap3/syslib.c deleted file mode 100644 index 9ced495c8d..0000000000 --- a/cpu/arm_cortexa8/omap3/syslib.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * (C) Copyright 2008 - * Texas Instruments, - * - * Richard Woodruff - * Syed Mohammed Khasim - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include - -/************************************************************ - * sdelay() - simple spin loop. Will be constant time as - * its generally used in bypass conditions only. This - * is necessary until timers are accessible. - * - * not inline to increase chances its in cache when called - *************************************************************/ -void sdelay(unsigned long loops) -{ - __asm__ volatile ("1:\n" "subs %0, %1, #1\n" - "bne 1b":"=r" (loops):"0"(loops)); -} - -/***************************************************************** - * sr32 - clear & set a value in a bit range for a 32 bit address - *****************************************************************/ -void sr32(void *addr, u32 start_bit, u32 num_bits, u32 value) -{ - u32 tmp, msk = 0; - msk = 1 << num_bits; - --msk; - tmp = readl((u32)addr) & ~(msk << start_bit); - tmp |= value << start_bit; - writel(tmp, (u32)addr); -} - -/********************************************************************* - * wait_on_value() - common routine to allow waiting for changes in - * volatile regs. - *********************************************************************/ -u32 wait_on_value(u32 read_bit_mask, u32 match_value, void *read_addr, - u32 bound) -{ - u32 i = 0, val; - do { - ++i; - val = readl((u32)read_addr) & read_bit_mask; - if (val == match_value) - return 1; - if (i == bound) - return 0; - } while (1); -} diff --git a/cpu/arm_cortexa8/omap3/timer.c b/cpu/arm_cortexa8/omap3/timer.c deleted file mode 100644 index 401bfe6d09..0000000000 --- a/cpu/arm_cortexa8/omap3/timer.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * (C) Copyright 2008 - * Texas Instruments - * - * Richard Woodruff - * Syed Moahmmed Khasim - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * Alex Zuepke - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include - -static ulong timestamp; -static ulong lastinc; -static struct gptimer *timer_base = (struct gptimer *)CONFIG_SYS_TIMERBASE; - -/* - * Nothing really to do with interrupts, just starts up a counter. - * We run the counter with 13MHz, divided by 8, resulting in timer - * frequency of 1.625MHz. With 32bit counter register, counter - * overflows in ~44min - */ - -/* 13MHz / 8 = 1.625MHz */ -#define TIMER_CLOCK (V_SCLK / (2 << CONFIG_SYS_PTV)) -#define TIMER_LOAD_VAL 0xffffffff - -int timer_init(void) -{ - /* start the counter ticking up, reload value on overflow */ - writel(TIMER_LOAD_VAL, &timer_base->tldr); - /* enable timer */ - writel((CONFIG_SYS_PTV << 2) | TCLR_PRE | TCLR_AR | TCLR_ST, - &timer_base->tclr); - - reset_timer_masked(); /* init the timestamp and lastinc value */ - - return 0; -} - -/* - * timer without interrupts - */ -void reset_timer(void) -{ - reset_timer_masked(); -} - -ulong get_timer(ulong base) -{ - return get_timer_masked() - base; -} - -void set_timer(ulong t) -{ - timestamp = t; -} - -/* delay x useconds */ -void __udelay(unsigned long usec) -{ - long tmo = usec * (TIMER_CLOCK / 1000) / 1000; - unsigned long now, last = readl(&timer_base->tcrr); - - while (tmo > 0) { - now = readl(&timer_base->tcrr); - if (last > now) /* count up timer overflow */ - tmo -= TIMER_LOAD_VAL - last + now; - else - tmo -= now - last; - last = now; - } -} - -void reset_timer_masked(void) -{ - /* reset time, capture current incrementer value time */ - lastinc = readl(&timer_base->tcrr) / (TIMER_CLOCK / CONFIG_SYS_HZ); - timestamp = 0; /* start "advancing" time stamp from 0 */ -} - -ulong get_timer_masked(void) -{ - /* current tick value */ - ulong now = readl(&timer_base->tcrr) / (TIMER_CLOCK / CONFIG_SYS_HZ); - - if (now >= lastinc) /* normal mode (non roll) */ - /* move stamp fordward with absoulte diff ticks */ - timestamp += (now - lastinc); - else /* we have rollover of incrementer */ - timestamp += ((TIMER_LOAD_VAL / (TIMER_CLOCK / CONFIG_SYS_HZ)) - - lastinc) + now; - lastinc = now; - return timestamp; -} - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return get_timer(0); -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk(void) -{ - return CONFIG_SYS_HZ; -} diff --git a/cpu/arm_cortexa8/s5pc1xx/Makefile b/cpu/arm_cortexa8/s5pc1xx/Makefile deleted file mode 100644 index 01c93feda8..0000000000 --- a/cpu/arm_cortexa8/s5pc1xx/Makefile +++ /dev/null @@ -1,55 +0,0 @@ -# -# (C) Copyright 2000-2003 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# (C) Copyright 2008 -# Guennadi Liakhovetki, DENX Software Engineering, -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(SOC).a - -SOBJS = cache.o -SOBJS += reset.o - -COBJS += clock.o -COBJS += cpu_info.o -COBJS += gpio.o -COBJS += sromc.o -COBJS += timer.o - -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) - -all: $(obj).depend $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/arm_cortexa8/s5pc1xx/cache.S b/cpu/arm_cortexa8/s5pc1xx/cache.S deleted file mode 100644 index 23f527a485..0000000000 --- a/cpu/arm_cortexa8/s5pc1xx/cache.S +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2009 Samsung Electronics - * Minkyu Kang - * - * based on cpu/arm_cortexa8/omap3/cache.S - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include - -.align 5 -.global invalidate_dcache -.global l2_cache_enable -.global l2_cache_disable - -/* - * invalidate_dcache() - * Invalidate the whole D-cache. - * - * Corrupted registers: r0-r5, r7, r9-r11 - */ -invalidate_dcache: - stmfd r13!, {r0 - r5, r7, r9 - r12, r14} - - cmp r0, #0xC100 @ check if the cpu is s5pc100 - - beq finished_inval @ s5pc100 doesn't need this - @ routine - mrc p15, 1, r0, c0, c0, 1 @ read clidr - ands r3, r0, #0x7000000 @ extract loc from clidr - mov r3, r3, lsr #23 @ left align loc bit field - beq finished_inval @ if loc is 0, then no need to - @ clean - mov r10, #0 @ start clean at cache level 0 -inval_loop1: - add r2, r10, r10, lsr #1 @ work out 3x current cache - @ level - mov r1, r0, lsr r2 @ extract cache type bits from - @ clidr - and r1, r1, #7 @ mask of the bits for current - @ cache only - cmp r1, #2 @ see what cache we have at - @ this level - blt skip_inval @ skip if no cache, or just - @ i-cache - mcr p15, 2, r10, c0, c0, 0 @ select current cache level - @ in cssr - mov r2, #0 @ operand for mcr SBZ - mcr p15, 0, r2, c7, c5, 4 @ flush prefetch buffer to - @ sych the new cssr&csidr, - @ with armv7 this is 'isb', - @ but we compile with armv5 - mrc p15, 1, r1, c0, c0, 0 @ read the new csidr - and r2, r1, #7 @ extract the length of the - @ cache lines - add r2, r2, #4 @ add 4 (line length offset) - ldr r4, =0x3ff - ands r4, r4, r1, lsr #3 @ find maximum number on the - @ way size - clz r5, r4 @ find bit position of way - @ size increment - ldr r7, =0x7fff - ands r7, r7, r1, lsr #13 @ extract max number of the - @ index size -inval_loop2: - mov r9, r4 @ create working copy of max - @ way size -inval_loop3: - orr r11, r10, r9, lsl r5 @ factor way and cache number - @ into r11 - orr r11, r11, r7, lsl r2 @ factor index number into r11 - mcr p15, 0, r11, c7, c6, 2 @ invalidate by set/way - subs r9, r9, #1 @ decrement the way - bge inval_loop3 - subs r7, r7, #1 @ decrement the index - bge inval_loop2 -skip_inval: - add r10, r10, #2 @ increment cache number - cmp r3, r10 - bgt inval_loop1 -finished_inval: - mov r10, #0 @ swith back to cache level 0 - mcr p15, 2, r10, c0, c0, 0 @ select current cache level - @ in cssr - mcr p15, 0, r10, c7, c5, 4 @ flush prefetch buffer, - @ with armv7 this is 'isb', - @ but we compile with armv5 - - ldmfd r13!, {r0 - r5, r7, r9 - r12, pc} - -l2_cache_enable: - push {r0, r1, r2, lr} - mrc 15, 0, r3, cr1, cr0, 1 - orr r3, r3, #2 - mcr 15, 0, r3, cr1, cr0, 1 - pop {r1, r2, r3, pc} - -l2_cache_disable: - push {r0, r1, r2, lr} - mrc 15, 0, r3, cr1, cr0, 1 - bic r3, r3, #2 - mcr 15, 0, r3, cr1, cr0, 1 - pop {r1, r2, r3, pc} diff --git a/cpu/arm_cortexa8/s5pc1xx/clock.c b/cpu/arm_cortexa8/s5pc1xx/clock.c deleted file mode 100644 index 19619f92cd..0000000000 --- a/cpu/arm_cortexa8/s5pc1xx/clock.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Copyright (C) 2009 Samsung Electronics - * Minkyu Kang - * Heungjun Kim - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include - -#define CLK_M 0 -#define CLK_D 1 -#define CLK_P 2 - -#ifndef CONFIG_SYS_CLK_FREQ_C100 -#define CONFIG_SYS_CLK_FREQ_C100 12000000 -#endif -#ifndef CONFIG_SYS_CLK_FREQ_C110 -#define CONFIG_SYS_CLK_FREQ_C110 24000000 -#endif - -unsigned long (*get_pclk)(void); -unsigned long (*get_arm_clk)(void); -unsigned long (*get_pll_clk)(int); - -/* s5pc110: return pll clock frequency */ -static unsigned long s5pc100_get_pll_clk(int pllreg) -{ - struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE; - unsigned long r, m, p, s, mask, fout; - unsigned int freq; - - switch (pllreg) { - case APLL: - r = readl(&clk->apll_con); - break; - case MPLL: - r = readl(&clk->mpll_con); - break; - case EPLL: - r = readl(&clk->epll_con); - break; - case HPLL: - r = readl(&clk->hpll_con); - break; - default: - printf("Unsupported PLL (%d)\n", pllreg); - return 0; - } - - /* - * APLL_CON: MIDV [25:16] - * MPLL_CON: MIDV [23:16] - * EPLL_CON: MIDV [23:16] - * HPLL_CON: MIDV [23:16] - */ - if (pllreg == APLL) - mask = 0x3ff; - else - mask = 0x0ff; - - m = (r >> 16) & mask; - - /* PDIV [13:8] */ - p = (r >> 8) & 0x3f; - /* SDIV [2:0] */ - s = r & 0x7; - - /* FOUT = MDIV * FIN / (PDIV * 2^SDIV) */ - freq = CONFIG_SYS_CLK_FREQ_C100; - fout = m * (freq / (p * (1 << s))); - - return fout; -} - -/* s5pc100: return pll clock frequency */ -static unsigned long s5pc110_get_pll_clk(int pllreg) -{ - struct s5pc110_clock *clk = (struct s5pc110_clock *)S5PC1XX_CLOCK_BASE; - unsigned long r, m, p, s, mask, fout; - unsigned int freq; - - switch (pllreg) { - case APLL: - r = readl(&clk->apll_con); - break; - case MPLL: - r = readl(&clk->mpll_con); - break; - case EPLL: - r = readl(&clk->epll_con); - break; - case VPLL: - r = readl(&clk->vpll_con); - break; - default: - printf("Unsupported PLL (%d)\n", pllreg); - return 0; - } - - /* - * APLL_CON: MIDV [25:16] - * MPLL_CON: MIDV [25:16] - * EPLL_CON: MIDV [24:16] - * VPLL_CON: MIDV [24:16] - */ - if (pllreg == APLL || pllreg == MPLL) - mask = 0x3ff; - else - mask = 0x1ff; - - m = (r >> 16) & mask; - - /* PDIV [13:8] */ - p = (r >> 8) & 0x3f; - /* SDIV [2:0] */ - s = r & 0x7; - - freq = CONFIG_SYS_CLK_FREQ_C110; - if (pllreg == APLL) { - if (s < 1) - s = 1; - /* FOUT = MDIV * FIN / (PDIV * 2^(SDIV - 1)) */ - fout = m * (freq / (p * (1 << (s - 1)))); - } else - /* FOUT = MDIV * FIN / (PDIV * 2^SDIV) */ - fout = m * (freq / (p * (1 << s))); - - return fout; -} - -/* s5pc110: return ARM clock frequency */ -static unsigned long s5pc110_get_arm_clk(void) -{ - struct s5pc110_clock *clk = (struct s5pc110_clock *)S5PC1XX_CLOCK_BASE; - unsigned long div; - unsigned long dout_apll, armclk; - unsigned int apll_ratio; - - div = readl(&clk->div0); - - /* APLL_RATIO: [2:0] */ - apll_ratio = div & 0x7; - - dout_apll = get_pll_clk(APLL) / (apll_ratio + 1); - armclk = dout_apll; - - return armclk; -} - -/* s5pc100: return ARM clock frequency */ -static unsigned long s5pc100_get_arm_clk(void) -{ - struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE; - unsigned long div; - unsigned long dout_apll, armclk; - unsigned int apll_ratio, arm_ratio; - - div = readl(&clk->div0); - - /* ARM_RATIO: [6:4] */ - arm_ratio = (div >> 4) & 0x7; - /* APLL_RATIO: [0] */ - apll_ratio = div & 0x1; - - dout_apll = get_pll_clk(APLL) / (apll_ratio + 1); - armclk = dout_apll / (arm_ratio + 1); - - return armclk; -} - -/* s5pc100: return HCLKD0 frequency */ -static unsigned long get_hclk(void) -{ - struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE; - unsigned long hclkd0; - uint div, d0_bus_ratio; - - div = readl(&clk->div0); - /* D0_BUS_RATIO: [10:8] */ - d0_bus_ratio = (div >> 8) & 0x7; - - hclkd0 = get_arm_clk() / (d0_bus_ratio + 1); - - return hclkd0; -} - -/* s5pc100: return PCLKD1 frequency */ -static unsigned long get_pclkd1(void) -{ - struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE; - unsigned long d1_bus, pclkd1; - uint div, d1_bus_ratio, pclkd1_ratio; - - div = readl(&clk->div0); - /* D1_BUS_RATIO: [14:12] */ - d1_bus_ratio = (div >> 12) & 0x7; - /* PCLKD1_RATIO: [18:16] */ - pclkd1_ratio = (div >> 16) & 0x7; - - /* ASYNC Mode */ - d1_bus = get_pll_clk(MPLL) / (d1_bus_ratio + 1); - pclkd1 = d1_bus / (pclkd1_ratio + 1); - - return pclkd1; -} - -/* s5pc110: return HCLKs frequency */ -static unsigned long get_hclk_sys(int dom) -{ - struct s5pc110_clock *clk = (struct s5pc110_clock *)S5PC1XX_CLOCK_BASE; - unsigned long hclk; - unsigned int div; - unsigned int offset; - unsigned int hclk_sys_ratio; - - if (dom == CLK_M) - return get_hclk(); - - div = readl(&clk->div0); - - /* - * HCLK_MSYS_RATIO: [10:8] - * HCLK_DSYS_RATIO: [19:16] - * HCLK_PSYS_RATIO: [27:24] - */ - offset = 8 + (dom << 0x3); - - hclk_sys_ratio = (div >> offset) & 0xf; - - hclk = get_pll_clk(MPLL) / (hclk_sys_ratio + 1); - - return hclk; -} - -/* s5pc110: return PCLKs frequency */ -static unsigned long get_pclk_sys(int dom) -{ - struct s5pc110_clock *clk = (struct s5pc110_clock *)S5PC1XX_CLOCK_BASE; - unsigned long pclk; - unsigned int div; - unsigned int offset; - unsigned int pclk_sys_ratio; - - div = readl(&clk->div0); - - /* - * PCLK_MSYS_RATIO: [14:12] - * PCLK_DSYS_RATIO: [22:20] - * PCLK_PSYS_RATIO: [30:28] - */ - offset = 12 + (dom << 0x3); - - pclk_sys_ratio = (div >> offset) & 0x7; - - pclk = get_hclk_sys(dom) / (pclk_sys_ratio + 1); - - return pclk; -} - -/* s5pc110: return peripheral clock frequency */ -static unsigned long s5pc110_get_pclk(void) -{ - return get_pclk_sys(CLK_P); -} - -/* s5pc100: return peripheral clock frequency */ -static unsigned long s5pc100_get_pclk(void) -{ - return get_pclkd1(); -} - -void s5pc1xx_clock_init(void) -{ - if (cpu_is_s5pc110()) { - get_pll_clk = s5pc110_get_pll_clk; - get_arm_clk = s5pc110_get_arm_clk; - get_pclk = s5pc110_get_pclk; - } else { - get_pll_clk = s5pc100_get_pll_clk; - get_arm_clk = s5pc100_get_arm_clk; - get_pclk = s5pc100_get_pclk; - } -} diff --git a/cpu/arm_cortexa8/s5pc1xx/cpu_info.c b/cpu/arm_cortexa8/s5pc1xx/cpu_info.c deleted file mode 100644 index f16c0ff130..0000000000 --- a/cpu/arm_cortexa8/s5pc1xx/cpu_info.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2009 Samsung Electronics - * Minkyu Kang - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ -#include -#include -#include - -/* Default is s5pc100 */ -unsigned int s5pc1xx_cpu_id = 0xC100; - -#ifdef CONFIG_ARCH_CPU_INIT -int arch_cpu_init(void) -{ - s5pc1xx_cpu_id = readl(S5PC1XX_PRO_ID); - s5pc1xx_cpu_id = 0xC000 | ((s5pc1xx_cpu_id & 0x00FFF000) >> 12); - - s5pc1xx_clock_init(); - - return 0; -} -#endif - -u32 get_device_type(void) -{ - return s5pc1xx_cpu_id; -} - -#ifdef CONFIG_DISPLAY_CPUINFO -int print_cpuinfo(void) -{ - char buf[32]; - - printf("CPU:\tS5P%X@%sMHz\n", - s5pc1xx_cpu_id, strmhz(buf, get_arm_clk())); - - return 0; -} -#endif diff --git a/cpu/arm_cortexa8/s5pc1xx/gpio.c b/cpu/arm_cortexa8/s5pc1xx/gpio.c deleted file mode 100644 index a97244bf30..0000000000 --- a/cpu/arm_cortexa8/s5pc1xx/gpio.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * (C) Copyright 2009 Samsung Electronics - * Minkyu Kang - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -#define CON_MASK(x) (0xf << ((x) << 2)) -#define CON_SFR(x, v) ((v) << ((x) << 2)) - -#define DAT_MASK(x) (0x1 << (x)) -#define DAT_SET(x) (0x1 << (x)) - -#define PULL_MASK(x) (0x3 << ((x) << 1)) -#define PULL_MODE(x, v) ((v) << ((x) << 1)) - -#define DRV_MASK(x) (0x3 << ((x) << 1)) -#define DRV_SET(x, m) ((m) << ((x) << 1)) -#define RATE_MASK(x) (0x1 << (x + 16)) -#define RATE_SET(x) (0x1 << (x + 16)) - -void gpio_cfg_pin(struct s5pc1xx_gpio_bank *bank, int gpio, int cfg) -{ - unsigned int value; - - value = readl(&bank->con); - value &= ~CON_MASK(gpio); - value |= CON_SFR(gpio, cfg); - writel(value, &bank->con); -} - -void gpio_direction_output(struct s5pc1xx_gpio_bank *bank, int gpio, int en) -{ - unsigned int value; - - gpio_cfg_pin(bank, gpio, GPIO_OUTPUT); - - value = readl(&bank->dat); - value &= ~DAT_MASK(gpio); - if (en) - value |= DAT_SET(gpio); - writel(value, &bank->dat); -} - -void gpio_direction_input(struct s5pc1xx_gpio_bank *bank, int gpio) -{ - gpio_cfg_pin(bank, gpio, GPIO_INPUT); -} - -void gpio_set_value(struct s5pc1xx_gpio_bank *bank, int gpio, int en) -{ - unsigned int value; - - value = readl(&bank->dat); - value &= ~DAT_MASK(gpio); - if (en) - value |= DAT_SET(gpio); - writel(value, &bank->dat); -} - -unsigned int gpio_get_value(struct s5pc1xx_gpio_bank *bank, int gpio) -{ - unsigned int value; - - value = readl(&bank->dat); - return !!(value & DAT_MASK(gpio)); -} - -void gpio_set_pull(struct s5pc1xx_gpio_bank *bank, int gpio, int mode) -{ - unsigned int value; - - value = readl(&bank->pull); - value &= ~PULL_MASK(gpio); - - switch (mode) { - case GPIO_PULL_DOWN: - case GPIO_PULL_UP: - value |= PULL_MODE(gpio, mode); - break; - default: - return; - } - - writel(value, &bank->pull); -} - -void gpio_set_drv(struct s5pc1xx_gpio_bank *bank, int gpio, int mode) -{ - unsigned int value; - - value = readl(&bank->drv); - value &= ~DRV_MASK(gpio); - - switch (mode) { - case GPIO_DRV_1X: - case GPIO_DRV_2X: - case GPIO_DRV_3X: - case GPIO_DRV_4X: - value |= DRV_SET(gpio, mode); - break; - default: - return; - } - - writel(value, &bank->drv); -} - -void gpio_set_rate(struct s5pc1xx_gpio_bank *bank, int gpio, int mode) -{ - unsigned int value; - - value = readl(&bank->drv); - value &= ~RATE_MASK(gpio); - - switch (mode) { - case GPIO_DRV_FAST: - case GPIO_DRV_SLOW: - value |= RATE_SET(gpio); - break; - default: - return; - } - - writel(value, &bank->drv); -} diff --git a/cpu/arm_cortexa8/s5pc1xx/reset.S b/cpu/arm_cortexa8/s5pc1xx/reset.S deleted file mode 100644 index 7f6ff9c35f..0000000000 --- a/cpu/arm_cortexa8/s5pc1xx/reset.S +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2009 Samsung Electronics. - * Minkyu Kang - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include - -#define S5PC100_SWRESET 0xE0200000 -#define S5PC110_SWRESET 0xE0102000 - -.globl reset_cpu -reset_cpu: - ldr r1, =S5PC1XX_PRO_ID - ldr r2, [r1] - ldr r4, =0x00010000 - and r4, r2, r4 - cmp r4, #0 - bne 110f - /* S5PC100 */ - ldr r1, =S5PC100_SWRESET - ldr r2, =0xC100 - b 200f -110: /* S5PC110 */ - ldr r1, =S5PC110_SWRESET - mov r2, #1 -200: - str r2, [r1] -_loop_forever: - b _loop_forever diff --git a/cpu/arm_cortexa8/s5pc1xx/sromc.c b/cpu/arm_cortexa8/s5pc1xx/sromc.c deleted file mode 100644 index 380be81be5..0000000000 --- a/cpu/arm_cortexa8/s5pc1xx/sromc.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2010 Samsung Electronics - * Naveen Krishna Ch - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -/* - * s5pc1xx_config_sromc() - select the proper SROMC Bank and configure the - * band width control and bank control registers - * srom_bank - SROM Bank 0 to 5 - * smc_bw_conf - SMC Band witdh reg configuration value - * smc_bc_conf - SMC Bank Control reg configuration value - */ -void s5pc1xx_config_sromc(u32 srom_bank, u32 smc_bw_conf, u32 smc_bc_conf) -{ - u32 tmp; - struct s5pc1xx_smc *srom; - - if (cpu_is_s5pc100()) - srom = (struct s5pc1xx_smc *)S5PC100_SROMC_BASE; - else - srom = (struct s5pc1xx_smc *)S5PC110_SROMC_BASE; - - /* Configure SMC_BW register to handle proper SROMC bank */ - tmp = srom->bw; - tmp &= ~(0xF << (srom_bank * 4)); - tmp |= smc_bw_conf; - srom->bw = tmp; - - /* Configure SMC_BC register */ - srom->bc[srom_bank] = smc_bc_conf; -} diff --git a/cpu/arm_cortexa8/s5pc1xx/timer.c b/cpu/arm_cortexa8/s5pc1xx/timer.c deleted file mode 100644 index c5df5c5ab5..0000000000 --- a/cpu/arm_cortexa8/s5pc1xx/timer.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (C) 2009 Samsung Electronics - * Heungjun Kim - * Inki Dae - * Minkyu Kang - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include - -#define PRESCALER_1 (16 - 1) /* prescaler of timer 2, 3, 4 */ -#define MUX_DIV_2 1 /* 1/2 period */ -#define MUX_DIV_4 2 /* 1/4 period */ -#define MUX_DIV_8 3 /* 1/8 period */ -#define MUX_DIV_16 4 /* 1/16 period */ -#define MUX4_DIV_SHIFT 16 - -#define TCON_TIMER4_SHIFT 20 - -static unsigned long count_value; - -/* Internal tick units */ -static unsigned long long timestamp; /* Monotonic incrementing timer */ -static unsigned long lastdec; /* Last decremneter snapshot */ - -/* macro to read the 16 bit timer */ -static inline struct s5pc1xx_timer *s5pc1xx_get_base_timer(void) -{ - if (cpu_is_s5pc110()) - return (struct s5pc1xx_timer *)S5PC110_TIMER_BASE; - else - return (struct s5pc1xx_timer *)S5PC100_TIMER_BASE; -} - -int timer_init(void) -{ - struct s5pc1xx_timer *const timer = s5pc1xx_get_base_timer(); - u32 val; - - /* - * @ PWM Timer 4 - * Timer Freq(HZ) = - * PCLK / { (prescaler_value + 1) * (divider_value) } - */ - - /* set prescaler : 16 */ - /* set divider : 2 */ - writel((PRESCALER_1 & 0xff) << 8, &timer->tcfg0); - writel((MUX_DIV_2 & 0xf) << MUX4_DIV_SHIFT, &timer->tcfg1); - - if (count_value == 0) { - /* reset initial value */ - /* count_value = 2085937.5(HZ) (per 1 sec)*/ - count_value = get_pclk() / ((PRESCALER_1 + 1) * - (MUX_DIV_2 + 1)); - - /* count_value / 100 = 20859.375(HZ) (per 10 msec) */ - count_value = count_value / 100; - } - - /* set count value */ - writel(count_value, &timer->tcntb4); - lastdec = count_value; - - val = (readl(&timer->tcon) & ~(0x07 << TCON_TIMER4_SHIFT)) | - S5PC1XX_TCON4_AUTO_RELOAD; - - /* auto reload & manual update */ - writel(val | S5PC1XX_TCON4_UPDATE, &timer->tcon); - - /* start PWM timer 4 */ - writel(val | S5PC1XX_TCON4_START, &timer->tcon); - - timestamp = 0; - - return 0; -} - -/* - * timer without interrupts - */ -void reset_timer(void) -{ - reset_timer_masked(); -} - -unsigned long get_timer(unsigned long base) -{ - return get_timer_masked() - base; -} - -void set_timer(unsigned long t) -{ - timestamp = t; -} - -/* delay x useconds */ -void __udelay(unsigned long usec) -{ - unsigned long tmo, tmp; - - if (usec >= 1000) { - /* - * if "big" number, spread normalization - * to seconds - * 1. start to normalize for usec to ticks per sec - * 2. find number of "ticks" to wait to achieve target - * 3. finish normalize. - */ - tmo = usec / 1000; - tmo *= (CONFIG_SYS_HZ * count_value / 10); - tmo /= 1000; - } else { - /* else small number, don't kill it prior to HZ multiply */ - tmo = usec * CONFIG_SYS_HZ * count_value / 10; - tmo /= (1000 * 1000); - } - - /* get current timestamp */ - tmp = get_timer(0); - - /* if setting this fordward will roll time stamp */ - /* reset "advancing" timestamp to 0, set lastdec value */ - /* else, set advancing stamp wake up time */ - if ((tmo + tmp + 1) < tmp) - reset_timer_masked(); - else - tmo += tmp; - - /* loop till event */ - while (get_timer_masked() < tmo) - ; /* nop */ -} - -void reset_timer_masked(void) -{ - struct s5pc1xx_timer *const timer = s5pc1xx_get_base_timer(); - - /* reset time */ - lastdec = readl(&timer->tcnto4); - timestamp = 0; -} - -unsigned long get_timer_masked(void) -{ - struct s5pc1xx_timer *const timer = s5pc1xx_get_base_timer(); - unsigned long now = readl(&timer->tcnto4); - - if (lastdec >= now) - timestamp += lastdec - now; - else - timestamp += lastdec + count_value - now; - - lastdec = now; - - return timestamp; -} - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return get_timer(0); -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -unsigned long get_tbclk(void) -{ - return CONFIG_SYS_HZ; -} diff --git a/cpu/arm_cortexa8/start.S b/cpu/arm_cortexa8/start.S deleted file mode 100644 index 29dae2f282..0000000000 --- a/cpu/arm_cortexa8/start.S +++ /dev/null @@ -1,416 +0,0 @@ -/* - * armboot - Startup Code for OMAP3530/ARM Cortex CPU-core - * - * Copyright (c) 2004 Texas Instruments - * - * Copyright (c) 2001 Marius Gröger - * Copyright (c) 2002 Alex Züpke - * Copyright (c) 2002 Gary Jennejohn - * Copyright (c) 2003 Richard Woodruff - * Copyright (c) 2003 Kshitij - * Copyright (c) 2006-2008 Syed Mohammed Khasim - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include - -.globl _start -_start: b 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 - -_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 -_pad: .word 0x12345678 /* now 16*4=64 */ -.global _end_vect -_end_vect: - - .balignl 16,0xdeadbeef -/************************************************************************* - * - * Startup Code (reset vector) - * - * do important init only if we don't start from memory! - * setup Memory and board specific bits prior to relocation. - * relocate armboot to ram - * setup stack - * - *************************************************************************/ - -_TEXT_BASE: - .word TEXT_BASE - -.globl _armboot_start -_armboot_start: - .word _start - -/* - * These are defined in the board-specific linker script. - */ -.globl _bss_start -_bss_start: - .word __bss_start - -.globl _bss_end -_bss_end: - .word _end - -#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 - -/* - * the actual reset code - */ - -reset: - /* - * set the cpu to SVC32 mode - */ - mrs r0, cpsr - bic r0, r0, #0x1f - orr r0, r0, #0xd3 - msr cpsr,r0 - -#if (CONFIG_OMAP34XX) - /* Copy vectors to mask ROM indirect addr */ - adr r0, _start @ r0 <- current position of code - add r0, r0, #4 @ skip reset vector - mov r2, #64 @ r2 <- size to copy - add r2, r0, r2 @ r2 <- source end address - mov r1, #SRAM_OFFSET0 @ build vect addr - mov r3, #SRAM_OFFSET1 - add r1, r1, r3 - mov r3, #SRAM_OFFSET2 - add r1, r1, r3 -next: - ldmia r0!, {r3 - r10} @ copy from source address [r0] - stmia r1!, {r3 - r10} @ copy to target address [r1] - cmp r0, r2 @ until source end address [r2] - bne next @ loop until equal */ -#if !defined(CONFIG_SYS_NAND_BOOT) && !defined(CONFIG_SYS_ONENAND_BOOT) - /* No need to copy/exec the clock code - DPLL adjust already done - * in NAND/oneNAND Boot. - */ - bl cpy_clk_code @ put dpll adjust code behind vectors -#endif /* NAND Boot */ -#endif - /* the mask ROM code should have PLL and others stable */ -#ifndef CONFIG_SKIP_LOWLEVEL_INIT - bl cpu_init_crit -#endif - -#ifndef CONFIG_SKIP_RELOCATE_UBOOT -relocate: @ relocate U-Boot to RAM - adr r0, _start @ r0 <- current position of code - ldr r1, _TEXT_BASE @ test if we run from flash or RAM - cmp r0, r1 @ don't reloc during debug - beq stack_setup - - ldr r2, _armboot_start - ldr r3, _bss_start - sub r2, r3, r2 @ r2 <- size of armboot - add r2, r0, r2 @ r2 <- source end address - -copy_loop: @ copy 32 bytes at a time - ldmia r0!, {r3 - r10} @ copy from source address [r0] - stmia r1!, {r3 - r10} @ copy to target address [r1] - cmp r0, r2 @ until source end addreee [r2] - ble copy_loop -#endif /* CONFIG_SKIP_RELOCATE_UBOOT */ - - /* Set up the stack */ -stack_setup: - ldr r0, _TEXT_BASE @ upper 128 KiB: relocated uboot - sub r0, r0, #CONFIG_SYS_MALLOC_LEN @ malloc area - sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE @ bdinfo -#ifdef CONFIG_USE_IRQ - sub r0, r0, #(CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ) -#endif - sub sp, r0, #12 @ leave 3 words for abort-stack - and sp, sp, #~7 @ 8 byte alinged for (ldr/str)d - - /* Clear BSS (if any). Is below tx (watch load addr - need space) */ -clear_bss: - ldr r0, _bss_start @ find start of bss segment - ldr r1, _bss_end @ stop here - mov r2, #0x00000000 @ clear value -clbss_l: - str r2, [r0] @ clear BSS location - cmp r0, r1 @ are we at the end yet - add r0, r0, #4 @ increment clear index pointer - bne clbss_l @ keep clearing till at end - - ldr pc, _start_armboot @ jump to C code - -_start_armboot: .word start_armboot - - -/************************************************************************* - * - * CPU_init_critical registers - * - * setup important registers - * setup memory timing - * - *************************************************************************/ -cpu_init_crit: - /* - * Invalidate L1 I/D - */ - mov r0, #0 @ set up for MCR - mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs - mcr p15, 0, r0, c7, c5, 0 @ invalidate icache - - /* - * disable MMU stuff and caches - */ - mrc p15, 0, r0, c1, c0, 0 - bic r0, r0, #0x00002000 @ clear bits 13 (--V-) - bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM) - orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align - orr r0, r0, #0x00000800 @ set bit 12 (Z---) BTB - mcr p15, 0, r0, c1, c0, 0 - - /* - * Jump to board specific initialization... - * The Mask ROM will have already initialized - * basic memory. Go here to bump up clock rate and handle - * wake up conditions. - */ - mov ip, lr @ persevere link reg across call - bl lowlevel_init @ go setup pll,mux,memory - mov lr, ip @ restore link - mov pc, lr @ back to my caller -/* - ************************************************************************* - * - * 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 -#define I_BIT 0x80 - -/* - * use bad_save_user_regs for abort/prefetch/undef/swi ... - * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling - */ - - .macro bad_save_user_regs - sub sp, sp, #S_FRAME_SIZE @ carve out a frame on current - @ user stack - stmia sp, {r0 - r12} @ Save user registers (now in - @ svc mode) r0-r12 - - ldr r2, _armboot_start - sub r2, r2, #(CONFIG_SYS_MALLOC_LEN) - sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE + 8) @ set base 2 words into abort - @ stack - ldmia r2, {r2 - r3} @ get values for "aborted" pc - @ and cpsr (into parm regs) - add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack - - add r5, sp, #S_SP - mov r1, lr - stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr - mov r0, sp @ save current stack into r0 - @ (param register) - .endm - - .macro irq_save_user_regs - sub sp, sp, #S_FRAME_SIZE - stmia sp, {r0 - r12} @ Calling r0-r12 - add r8, sp, #S_PC @ !! R8 NEEDS to be saved !! - @ a reserved stack spot would - @ be good. - 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, _armboot_start @ setup our mode stack (enter - @ in banked mode) - sub r13, r13, #(CONFIG_SYS_MALLOC_LEN) @ move past malloc pool - sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE + 8) @ move to reserved a couple - @ spots for abort stack - - str lr, [r13] @ save caller lr in position 0 - @ of saved stack - mrs lr, spsr @ get the spsr - str lr, [r13, #4] @ save spsr in position 1 of - @ saved stack - - mov r13, #MODE_SVC @ prepare SVC-Mode - @ msr spsr_c, r13 - msr spsr, r13 @ switch modes, make sure - @ moves will execute - mov lr, pc @ capture return pc - movs pc, lr @ jump to next instruction & - @ switch modes. - .endm - - .macro get_bad_stack_swi - sub r13, r13, #4 @ space on current stack for - @ scratch reg. - str r0, [r13] @ save R0's value. - ldr r0, _armboot_start @ get data regions start - sub r0, r0, #(CONFIG_SYS_MALLOC_LEN) @ move past malloc pool - sub r0, r0, #(CONFIG_SYS_GBL_DATA_SIZE + 8) @ move past gbl and a couple - @ spots for abort stack - str lr, [r0] @ save caller lr in position 0 - @ of saved stack - mrs r0, spsr @ get the spsr - str lr, [r0, #4] @ save spsr in position 1 of - @ saved stack - ldr r0, [r13] @ restore r0 - add r13, r13, #4 @ pop stack entry - .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_swi - 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 - /* someone ought to write a more effective fiq_save_user_regs */ - irq_save_user_regs - bl do_fiq - 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 diff --git a/cpu/arm_cortexa8/u-boot.lds b/cpu/arm_cortexa8/u-boot.lds deleted file mode 100644 index 4f1711cca0..0000000000 --- a/cpu/arm_cortexa8/u-boot.lds +++ /dev/null @@ -1,58 +0,0 @@ -/* - * January 2004 - Changed to support H4 device - * Copyright (c) 2004-2008 Texas Instruments - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -ENTRY(_start) -SECTIONS -{ - . = 0x00000000; - - . = ALIGN(4); - .text : - { - cpu/arm_cortexa8/start.o (.text) - *(.text) - } - - . = ALIGN(4); - .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } - - . = ALIGN(4); - .data : { *(.data) } - - . = ALIGN(4); - .got : { *(.got) } - - __u_boot_cmd_start = .; - .u_boot_cmd : { *(.u_boot_cmd) } - __u_boot_cmd_end = .; - - . = ALIGN(4); - __bss_start = .; - .bss : { *(.bss) } - _end = .; -} diff --git a/cpu/arm_intcm/Makefile b/cpu/arm_intcm/Makefile deleted file mode 100644 index 7701b03bbe..0000000000 --- a/cpu/arm_intcm/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(CPU).a - -START = start.o -COBJS = cpu.o - -SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) -START := $(addprefix $(obj),$(START)) - -all: $(obj).depend $(START) $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/arm_intcm/config.mk b/cpu/arm_intcm/config.mk deleted file mode 100644 index e783f697a1..0000000000 --- a/cpu/arm_intcm/config.mk +++ /dev/null @@ -1,32 +0,0 @@ -# -# (C) Copyright 2002 -# Gary Jennejohn, DENX Software Engineering, -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float - -PLATFORM_CPPFLAGS += -march=armv4 -# ========================================================================= -# -# Supply options according to compiler version -# -# ========================================================================= -PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/arm_intcm/cpu.c b/cpu/arm_intcm/cpu.c deleted file mode 100644 index c0748e872e..0000000000 --- a/cpu/arm_intcm/cpu.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * CPU specific code for an unknown cpu - * - hence fairly empty...... - */ - -#include -#include - -int cleanup_before_linux (void) -{ - /* - * this function is called just before we call linux - * it prepares the processor for linux - * - * we turn off caches etc ... - */ - - disable_interrupts (); - - /* Since the CM has unknown processor we do not support - * cache operations - */ - - return (0); -} diff --git a/cpu/arm_intcm/start.S b/cpu/arm_intcm/start.S deleted file mode 100644 index bb1f003592..0000000000 --- a/cpu/arm_intcm/start.S +++ /dev/null @@ -1,372 +0,0 @@ -/* - * armboot - Startup Code for ARM926EJS CPU-core - * - * Copyright (c) 2003 Texas Instruments - * - * ----- Adapted for OMAP1610 OMAP730 from ARM925t code ------ - * - * Copyright (c) 2001 Marius Gröger - * Copyright (c) 2002 Alex Züpke - * Copyright (c) 2002 Gary Jennejohn - * Copyright (c) 2003 Richard Woodruff - * Copyright (c) 2003 Kshitij - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - - -#include -#include - -/* - ************************************************************************* - * - * Jump vector table - * - ************************************************************************* - */ - -.globl _start -_start: - b 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 - -_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! - * setup memory and board specific bits prior to relocation. - * relocate armboot to ram - * setup stack - * - ************************************************************************* - */ - -_TEXT_BASE: - .word TEXT_BASE /* address of _start in the linked image */ - -.globl _armboot_start -_armboot_start: - .word _start - -/* - * These are defined in the board-specific linker script. - */ -.globl _bss_start -_bss_start: - .word __bss_start - -.globl _bss_end -_bss_end: - .word _end - -#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 - - -/* - * the actual reset code - */ -.globl reset -reset: - /* - * set the cpu to SVC32 mode - */ - mrs r0,cpsr - bic r0,r0,#0x1f - orr r0,r0,#0xd3 - msr cpsr,r0 - - /* - * we do sys-critical inits only at reboot, - * not when booting from ram! - */ -#ifndef CONFIG_SKIP_LOWLEVEL_INIT - bl cpu_init_crit -#endif - -relocate: /* relocate U-Boot to RAM */ - adr r0, _start /* pc relative address of label */ - ldr r1, _TEXT_BASE /* linked image address of label */ - cmp r0, r1 /* test if we run from flash or RAM */ - beq stack_setup /* ifeq we are in the RAM copy */ - - ldr r2, _armboot_start - ldr r3, _bss_start - sub r2, r3, r2 /* r2 <- size of armboot */ - add r2, r0, r2 /* r2 <- source end address */ - -copy_loop: - ldmia r0!, {r3-r10} /* copy from source address [r0] */ - stmia r1!, {r3-r10} /* copy to target address [r1] */ - cmp r0, r2 /* until source end addreee [r2] */ - ble copy_loop - - /* Set up the stack */ -stack_setup: - ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ - sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */ - sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ -#ifdef CONFIG_USE_IRQ - sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) -#endif - sub sp, r0, #12 /* leave 3 words for abort-stack */ - -clear_bss: - ldr r0, _bss_start /* find start of bss segment */ - ldr r1, _bss_end /* stop here */ - mov r2, #0x00000000 /* clear */ - -clbss_l:str r2, [r0] /* clear loop... */ - add r0, r0, #4 - cmp r0, r1 - ble clbss_l - - ldr pc, _start_armboot - -_start_armboot: - .word start_armboot - -/* - ************************************************************************* - * - * CPU_init_critical registers - * - * setup important registers - * setup memory timing - * - ************************************************************************* - */ - -#ifndef CONFIG_SKIP_LOWLEVEL_INIT -cpu_init_crit: - /* arm_int_generic assumes the ARM boot monitor, or user software, - * has initialized the platform - */ - mov pc, lr /* back to my caller */ -#endif -/* - ************************************************************************* - * - * 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 -#define I_BIT 0x80 - -/* - * use bad_save_user_regs for abort/prefetch/undef/swi ... - * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling - */ - - .macro bad_save_user_regs - @ carve out a frame on current user stack - sub sp, sp, #S_FRAME_SIZE - stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12 - - ldr r2, _armboot_start - sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) - sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack - @ get values for "aborted" pc and cpsr (into parm regs) - ldmia r2, {r2 - r3} - add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack - add r5, sp, #S_SP - mov r1, lr - stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr - mov r0, sp @ save current stack into r0 (param register) - .endm - - .macro irq_save_user_regs - sub sp, sp, #S_FRAME_SIZE - stmia sp, {r0 - r12} @ Calling r0-r12 - @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good. - 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, _armboot_start @ setup our mode stack - sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) - sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack - - str lr, [r13] @ save caller lr in position 0 of saved stack - mrs lr, spsr @ get the spsr - str lr, [r13, #4] @ save spsr in position 1 of saved stack - mov r13, #MODE_SVC @ prepare SVC-Mode - @ msr spsr_c, r13 - msr spsr, r13 @ switch modes, make sure moves will execute - mov lr, pc @ capture return pc - movs pc, lr @ jump to next instruction & switch modes. - .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 -.globl undefined_instruction -undefined_instruction: - get_bad_stack - bad_save_user_regs - bl do_undefined_instruction - - .align 5 -.globl software_interrupt -software_interrupt: - get_bad_stack - bad_save_user_regs - bl do_software_interrupt - - .align 5 -.globl prefetch_abort -prefetch_abort: - get_bad_stack - bad_save_user_regs - bl do_prefetch_abort - - .align 5 -.globl data_abort -data_abort: - get_bad_stack - bad_save_user_regs - bl do_data_abort - - .align 5 -.globl not_used -not_used: - get_bad_stack - bad_save_user_regs - bl do_not_used - -#ifdef CONFIG_USE_IRQ - .align 5 -.globl irq -irq: - get_irq_stack - irq_save_user_regs - bl do_irq - irq_restore_user_regs - - .align 5 -.globl fiq -fiq: - get_fiq_stack - /* someone ought to write a more effiction fiq_save_user_regs */ - irq_save_user_regs - bl do_fiq - irq_restore_user_regs - -#else - - .align 5 -.globl irq -irq: - get_bad_stack - bad_save_user_regs - bl do_irq - - .align 5 -.globl fiq -fiq: - get_bad_stack - bad_save_user_regs - bl do_fiq - -#endif diff --git a/cpu/arm_intcm/u-boot.lds b/cpu/arm_intcm/u-boot.lds deleted file mode 100644 index 5eb87fbee7..0000000000 --- a/cpu/arm_intcm/u-boot.lds +++ /dev/null @@ -1,56 +0,0 @@ -/* - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -ENTRY(_start) -SECTIONS -{ - . = 0x00000000; - - . = ALIGN(4); - .text : - { - cpu/arm_intcm/start.o (.text) - *(.text) - } - - . = ALIGN(4); - .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } - - . = ALIGN(4); - .data : { *(.data) } - - . = ALIGN(4); - .got : { *(.got) } - - . = .; - __u_boot_cmd_start = .; - .u_boot_cmd : { *(.u_boot_cmd) } - __u_boot_cmd_end = .; - - . = ALIGN(4); - __bss_start = .; - .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } - _end = .; -} diff --git a/cpu/ixp/Makefile b/cpu/ixp/Makefile deleted file mode 100644 index 1403c4f390..0000000000 --- a/cpu/ixp/Makefile +++ /dev/null @@ -1,50 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(CPU).a - -START = start.o - -COBJS-y += cpu.o -COBJS-$(CONFIG_USE_IRQ) += interrupts.o -COBJS-y += timer.o - -SRCS := $(START:.o=.S) $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) -START := $(addprefix $(obj),$(START)) - -all: $(obj).depend $(START) $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/ixp/config.mk b/cpu/ixp/config.mk deleted file mode 100644 index deca3f4d55..0000000000 --- a/cpu/ixp/config.mk +++ /dev/null @@ -1,35 +0,0 @@ -# -# (C) Copyright 2002 -# Sysgo Real-Time Solutions, GmbH -# Marius Groeger -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -BIG_ENDIAN = y - -PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float -mbig-endian - -PLATFORM_CPPFLAGS += -mbig-endian -march=armv5te -mtune=strongarm1100 -# ========================================================================= -# -# Supply options according to compiler version -# -# ========================================================================= -PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/ixp/cpu.c b/cpu/ixp/cpu.c deleted file mode 100644 index ce275e5f3c..0000000000 --- a/cpu/ixp/cpu.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * CPU specific code - */ - -#include -#include -#include -#include -#include - -ulong loops_per_jiffy; - -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: - loops_per_jiffy = 887467; - speed = 533; - break; - - case 0x1d: - loops_per_jiffy = 666016; - speed = 400; - break; - - case 0x1f: - loops_per_jiffy = 442901; - 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; -} -*/ - -#ifdef CONFIG_BOOTCOUNT_LIMIT - -void bootcount_store (ulong a) -{ - volatile ulong *save_addr = (volatile ulong *)(CONFIG_SYS_BOOTCOUNT_ADDR); - - save_addr[0] = a; - save_addr[1] = BOOTCOUNT_MAGIC; -} - -ulong bootcount_load (void) -{ - volatile ulong *save_addr = (volatile ulong *)(CONFIG_SYS_BOOTCOUNT_ADDR); - - if (save_addr[1] != BOOTCOUNT_MAGIC) - return 0; - else - return save_addr[0]; -} - -#endif /* CONFIG_BOOTCOUNT_LIMIT */ - -int cpu_eth_init(bd_t *bis) -{ -#ifdef CONFIG_IXP4XX_NPE - npe_initialize(bis); -#endif - return 0; -} diff --git a/cpu/ixp/interrupts.c b/cpu/ixp/interrupts.c deleted file mode 100644 index 06a826af63..0000000000 --- a/cpu/ixp/interrupts.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * (C) Copyright 2006 - * Stefan Roese, DENX Software Engineering, sr@denx.de. - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -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); -} diff --git a/cpu/ixp/npe/IxEthAcc.c b/cpu/ixp/npe/IxEthAcc.c deleted file mode 100644 index 061b24bb50..0000000000 --- a/cpu/ixp/npe/IxEthAcc.c +++ /dev/null @@ -1,261 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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_ACC_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); -} - - diff --git a/cpu/ixp/npe/IxEthAccCommon.c b/cpu/ixp/npe/IxEthAccCommon.c deleted file mode 100644 index 211203dffd..0000000000 --- a/cpu/ixp/npe/IxEthAccCommon.c +++ /dev/null @@ -1,1049 +0,0 @@ -/** - * @file IxEthAccCommon.c - * - * @author Intel Corporation - * @date 12-Feb-2002 - * - * @brief This file contains the implementation common support routines for the component - * - * Design Notes: - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -/* - * Component header files - */ - -#include "IxOsal.h" -#include "IxEthAcc.h" -#include "IxEthDB.h" -#include "IxNpeMh.h" -#include "IxEthDBPortDefs.h" -#include "IxFeatureCtrl.h" -#include "IxEthAcc_p.h" -#include "IxEthAccQueueAssign_p.h" - -#include "IxEthAccDataPlane_p.h" -#include "IxEthAccMii_p.h" - -/** - * @addtogroup IxEthAccPri - *@{ - */ - -extern IxEthAccInfo ixEthAccDataInfo; - -/** - * - * @brief Maximum number of RX queues set to be the maximum number - * of traffic calsses. - * - */ -#define IX_ETHACC_MAX_RX_QUEUES \ - (IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY \ - - IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY \ - + 1) - -/** - * - * @brief Maximum number of 128 entry RX queues - * - */ -#define IX_ETHACC_MAX_LARGE_RX_QUEUES 4 - -/** - * - * @brief Data structure template for Default RX Queues - * - */ -IX_ETH_ACC_PRIVATE -IxEthAccQregInfo ixEthAccQmgrRxDefaultTemplate = - { - IX_ETH_ACC_RX_FRAME_ETH_Q, /**< Queue ID */ - "Eth Rx Q", - ixEthRxFrameQMCallback, /**< Functional callback */ - (IxQMgrCallbackId) 0, /**< Callback tag */ - IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */ - IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */ - TRUE, /**< Enable Q notification at startup */ - IX_ETH_ACC_RX_FRAME_ETH_Q_SOURCE,/**< Q Condition to drive callback */ - IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */ - IX_QMGR_Q_WM_LEVEL1, /**< Q High water mark - needed by NPE */ - }; - -/** - * - * @brief Data structure template for Small RX Queues - * - */ -IX_ETH_ACC_PRIVATE -IxEthAccQregInfo ixEthAccQmgrRxSmallTemplate = - { - IX_ETH_ACC_RX_FRAME_ETH_Q, /**< Queue ID */ - "Eth Rx Q", - ixEthRxFrameQMCallback, /**< Functional callback */ - (IxQMgrCallbackId) 0, /**< Callback tag */ - IX_QMGR_Q_SIZE64, /**< Allocate Smaller Q */ - IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */ - TRUE, /**< Enable Q notification at startup */ - IX_ETH_ACC_RX_FRAME_ETH_Q_SOURCE,/**< Q Condition to drive callback */ - IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */ - IX_QMGR_Q_WM_LEVEL1, /**< Q High water mark - needed by NPE */ - }; - - -/** - * - * @brief Data structure used to register & initialize the Queues - * - */ -IX_ETH_ACC_PRIVATE -IxEthAccQregInfo ixEthAccQmgrStaticInfo[]= -{ - { - IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q, - "Eth Rx Fr Q 1", - ixEthRxFreeQMCallback, - (IxQMgrCallbackId) IX_ETH_PORT_1, - IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */ - IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */ - FALSE, /**< Disable Q notification at startup */ - IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q_SOURCE, /**< Q Condition to drive callback */ - IX_QMGR_Q_WM_LEVEL0, /***< Q Low water mark */ - IX_QMGR_Q_WM_LEVEL64, /**< Q High water mark */ - }, - - { - IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q, - "Eth Rx Fr Q 2", - ixEthRxFreeQMCallback, - (IxQMgrCallbackId) IX_ETH_PORT_2, - IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */ - IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */ - FALSE, /**< Disable Q notification at startup */ - IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q_SOURCE, /**< Q Condition to drive callback */ - IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */ - IX_QMGR_Q_WM_LEVEL64, /**< Q High water mark */ - }, -#ifdef __ixp46X - { - IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q, - "Eth Rx Fr Q 3", - ixEthRxFreeQMCallback, - (IxQMgrCallbackId) IX_ETH_PORT_3, - IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */ - IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */ - FALSE, /**< Disable Q notification at startup */ - IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q_SOURCE, /**< Q Condition to drive callback */ - IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */ - IX_QMGR_Q_WM_LEVEL64, /**< Q High water mark */ - }, -#endif - { - IX_ETH_ACC_TX_FRAME_ENET0_Q, - "Eth Tx Q 1", - ixEthTxFrameQMCallback, - (IxQMgrCallbackId) IX_ETH_PORT_1, - IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */ - IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */ - FALSE, /**< Disable Q notification at startup */ - IX_ETH_ACC_TX_FRAME_ENET0_Q_SOURCE, /**< Q Condition to drive callback */ - IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */ - IX_QMGR_Q_WM_LEVEL64, /**< Q High water mark */ - }, - - { - IX_ETH_ACC_TX_FRAME_ENET1_Q, - "Eth Tx Q 2", - ixEthTxFrameQMCallback, - (IxQMgrCallbackId) IX_ETH_PORT_2, - IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */ - IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */ - FALSE, /**< Disable Q notification at startup */ - IX_ETH_ACC_TX_FRAME_ENET1_Q_SOURCE, /**< Q Condition to drive callback */ - IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */ - IX_QMGR_Q_WM_LEVEL64, /**< Q High water mark */ - }, -#ifdef __ixp46X - { - IX_ETH_ACC_TX_FRAME_ENET2_Q, - "Eth Tx Q 3", - ixEthTxFrameQMCallback, - (IxQMgrCallbackId) IX_ETH_PORT_3, - IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */ - IX_QMGR_Q_ENTRY_SIZE1, /** Queue Entry Sizes - all Q entries are single ord entries */ - FALSE, /** Disable Q notification at startup */ - IX_ETH_ACC_TX_FRAME_ENET2_Q_SOURCE, /** Q Condition to drive callback */ - IX_QMGR_Q_WM_LEVEL0, /* No queues use almost empty */ - IX_QMGR_Q_WM_LEVEL64, /** Q High water mark - needed used */ - }, -#endif - { - IX_ETH_ACC_TX_FRAME_DONE_ETH_Q, - "Eth Tx Done Q", - ixEthTxFrameDoneQMCallback, - (IxQMgrCallbackId) 0, - IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */ - IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */ - TRUE, /**< Enable Q notification at startup */ - IX_ETH_ACC_TX_FRAME_DONE_ETH_Q_SOURCE, /**< Q Condition to drive callback */ - IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */ - IX_QMGR_Q_WM_LEVEL2, /**< Q High water mark - needed by NPE */ - }, - - { /* Null Termination entry - */ - (IxQMgrQId)0, - (char *) NULL, - (IxQMgrCallback) NULL, - (IxQMgrCallbackId) 0, - 0, - 0, - 0, - 0, - 0, - 0 - } - -}; - -/** - * - * @brief Data structure used to register & initialize the Queues - * - * The structure will be filled at run time depending on the NPE - * image already loaded and the QoS configured in ethDB. - * - */ -IX_ETH_ACC_PRIVATE -IxEthAccQregInfo ixEthAccQmgrRxQueuesInfo[IX_ETHACC_MAX_RX_QUEUES+1]= -{ - { /* PlaceHolder for rx queues - * depending on the QoS configured - */ - (IxQMgrQId)0, - (char *) NULL, - (IxQMgrCallback) NULL, - (IxQMgrCallbackId) 0, - 0, - 0, - 0, - 0, - 0, - 0 - }, - - { /* PlaceHolder for rx queues - * depending on the QoS configured - */ - (IxQMgrQId)0, - (char *) NULL, - (IxQMgrCallback) NULL, - (IxQMgrCallbackId) 0, - 0, - 0, - 0, - 0, - 0, - 0 - }, - - { /* PlaceHolder for rx queues - * depending on the QoS configured - */ - (IxQMgrQId)0, - (char *) NULL, - (IxQMgrCallback) NULL, - (IxQMgrCallbackId) 0, - 0, - 0, - 0, - 0, - 0, - 0 - }, - - { /* PlaceHolder for rx queues - * depending on the QoS configured - */ - (IxQMgrQId)0, - (char *) NULL, - (IxQMgrCallback) NULL, - (IxQMgrCallbackId) 0, - 0, - 0, - 0, - 0, - 0, - 0 - }, - - { /* PlaceHolder for rx queues - * depending on the QoS configured - */ - (IxQMgrQId)0, - (char *) NULL, - (IxQMgrCallback) NULL, - (IxQMgrCallbackId) 0, - 0, - 0, - 0, - 0, - 0, - 0 - }, - - { /* PlaceHolder for rx queues - * depending on the QoS configured - */ - (IxQMgrQId)0, - (char *) NULL, - (IxQMgrCallback) NULL, - (IxQMgrCallbackId) 0, - 0, - 0, - 0, - 0, - 0, - 0 - }, - - { /* PlaceHolder for rx queues - * depending on the QoS configured - */ - (IxQMgrQId)0, - (char *) NULL, - (IxQMgrCallback) NULL, - (IxQMgrCallbackId) 0, - 0, - 0, - 0, - 0, - 0, - 0 - }, - - { /* PlaceHolder for rx queues - * depending on the QoS configured - */ - (IxQMgrQId)0, - (char *) NULL, - (IxQMgrCallback) NULL, - (IxQMgrCallbackId) 0, - 0, - 0, - 0, - 0, - 0, - 0 - }, - - { /* Null Termination entry - */ - (IxQMgrQId)0, - (char *) NULL, - (IxQMgrCallback) NULL, - (IxQMgrCallbackId) 0, - 0, - 0, - 0, - 0, - 0, - 0 - } - -}; - -/* forward declarations */ -IX_ETH_ACC_PRIVATE IxEthAccStatus -ixEthAccQMgrQueueSetup(IxEthAccQregInfo *qInfoDes); - -/** - * @fn ixEthAccQMgrQueueSetup(void) - * - * @brief Setup one queue and its event, and register the callback required - * by this component to the QMgr - * - * @internal - */ -IX_ETH_ACC_PRIVATE IxEthAccStatus -ixEthAccQMgrQueueSetup(IxEthAccQregInfo *qInfoDes) -{ - /* - * Configure each Q. - */ - if ( ixQMgrQConfig( qInfoDes->qName, - qInfoDes->qId, - qInfoDes->qSize, - qInfoDes->qWords) != IX_SUCCESS) - { - return IX_ETH_ACC_FAIL; - } - - if ( ixQMgrWatermarkSet( qInfoDes->qId, - qInfoDes->AlmostEmptyThreshold, - qInfoDes->AlmostFullThreshold - ) != IX_SUCCESS) - { - return IX_ETH_ACC_FAIL; - } - - /* - * Set dispatcher priority. - */ - if ( ixQMgrDispatcherPrioritySet( qInfoDes->qId, - IX_ETH_ACC_QM_QUEUE_DISPATCH_PRIORITY) - != IX_SUCCESS) - { - return IX_ETH_ACC_FAIL; - } - - /* - * Register callbacks for each Q. - */ - if ( ixQMgrNotificationCallbackSet(qInfoDes->qId, - qInfoDes->qCallback, - qInfoDes->callbackTag) - != IX_SUCCESS ) - { - return IX_ETH_ACC_FAIL; - } - - /* - * Set notification condition for Q - */ - if ( qInfoDes->qNotificationEnableAtStartup == TRUE ) - { - if ( ixQMgrNotificationEnable(qInfoDes->qId, - qInfoDes->qConditionSource) - != IX_SUCCESS ) - { - return IX_ETH_ACC_FAIL; - } - } - - return(IX_ETH_ACC_SUCCESS); -} - -/** - * @fn ixEthAccQMgrQueuesConfig(void) - * - * @brief Setup all the queues and register all callbacks required - * by this component to the QMgr - * - * The RxFree queues, tx queues, rx queues are configured statically - * - * Rx queues configuration is driven by QoS setup. - * Many Rx queues may be required when QoS is enabled (this depends - * on IxEthDB setup and the images being downloaded). The configuration - * of the rxQueues is done in many steps as follows: - * - * @li select all Rx queues as configured by ethDB for all ports - * @li sort the queues by traffic class - * @li build the priority dependency for all queues - * @li fill the configuration for all rx queues - * @li configure all statically configured queues - * @li configure all dynamically configured queues - * - * @param none - * - * @return IxEthAccStatus - * - * @internal - */ -IX_ETH_ACC_PUBLIC -IxEthAccStatus ixEthAccQMgrQueuesConfig(void) -{ - struct - { - int npeCount; - UINT32 npeId; - IxQMgrQId qId; - IxEthDBProperty trafficClass; - } rxQueues[IX_ETHACC_MAX_RX_QUEUES]; - - UINT32 rxQueue = 0; - UINT32 rxQueueCount = 0; - IxQMgrQId ixQId =IX_QMGR_MAX_NUM_QUEUES; - IxEthDBStatus ixEthDBStatus = IX_ETH_DB_SUCCESS; - IxEthDBPortId ixEthDbPortId = 0; - IxEthAccPortId ixEthAccPortId = 0; - UINT32 ixNpeId = 0; - UINT32 ixHighestNpeId = 0; - UINT32 sortIterations = 0; - IxEthAccStatus ret = IX_ETH_ACC_SUCCESS; - IxEthAccQregInfo *qInfoDes = NULL; - IxEthDBProperty ixEthDBTrafficClass = IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY; - IxEthDBPropertyType ixEthDBPropertyType = IX_ETH_DB_INTEGER_PROPERTY; - UINT32 ixEthDBParameter = 0; - BOOL completelySorted = FALSE; - - /* Fill the corspondance between ports and queues - * This defines the mapping from port to queue Ids. - */ - - ixEthAccPortData[IX_ETH_PORT_1].ixEthAccRxData.rxFreeQueue - = IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q; - ixEthAccPortData[IX_ETH_PORT_2].ixEthAccRxData.rxFreeQueue - = IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q; -#ifdef __ixp46X - ixEthAccPortData[IX_ETH_PORT_3].ixEthAccRxData.rxFreeQueue - = IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q; -#endif - ixEthAccPortData[IX_ETH_PORT_1].ixEthAccTxData.txQueue - = IX_ETH_ACC_TX_FRAME_ENET0_Q; - ixEthAccPortData[IX_ETH_PORT_2].ixEthAccTxData.txQueue - = IX_ETH_ACC_TX_FRAME_ENET1_Q; -#ifdef __ixp46X - ixEthAccPortData[IX_ETH_PORT_3].ixEthAccTxData.txQueue - = IX_ETH_ACC_TX_FRAME_ENET2_Q; -#endif - /* Fill the corspondance between ports and NPEs - * This defines the mapping from port to npeIds. - */ - - ixEthAccPortData[IX_ETH_PORT_1].npeId = IX_NPEMH_NPEID_NPEB; - ixEthAccPortData[IX_ETH_PORT_2].npeId = IX_NPEMH_NPEID_NPEC; -#ifdef __ixp46X - ixEthAccPortData[IX_ETH_PORT_3].npeId = IX_NPEMH_NPEID_NPEA; -#endif - /* set the default rx scheduling discipline */ - ixEthAccDataInfo.schDiscipline = FIFO_NO_PRIORITY; - - /* - * Queue Selection step: - * - * The following code selects all the queues and build - * a temporary array which contains for each queue - * - the queue Id, - * - the highest traffic class (in case of many - * priorities configured for the same queue on different - * ports) - * - the number of different Npes which are - * configured to write to this queue. - * - * The output of this loop is a temporary array of RX queues - * in any order. - * - */ -#ifdef CONFIG_IXP425_COMPONENT_ETHDB - for (ixEthAccPortId = 0; - (ixEthAccPortId < IX_ETH_ACC_NUMBER_OF_PORTS) - && (ret == IX_ETH_ACC_SUCCESS); - ixEthAccPortId++) - { - /* map between ethDb and ethAcc port Ids */ - ixEthDbPortId = (IxEthDBPortId)ixEthAccPortId; - - /* map between npeId and ethAcc port Ids */ - ixNpeId = IX_ETH_ACC_PORT_TO_NPE_ID(ixEthAccPortId); - - /* Iterate thru the different priorities */ - for (ixEthDBTrafficClass = IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY; - ixEthDBTrafficClass <= IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY; - ixEthDBTrafficClass++) - { - ixEthDBStatus = ixEthDBFeaturePropertyGet( - ixEthDbPortId, - IX_ETH_DB_VLAN_QOS, - ixEthDBTrafficClass, - &ixEthDBPropertyType, - (void *)&ixEthDBParameter); - - if (ixEthDBStatus == IX_ETH_DB_SUCCESS) - { - /* This port and QoS class are mapped to - * a RX queue. - */ - if (ixEthDBPropertyType == IX_ETH_DB_INTEGER_PROPERTY) - { - /* remember the highest npe Id supporting ethernet */ - if (ixNpeId > ixHighestNpeId) - { - ixHighestNpeId = ixNpeId; - } - - /* search the queue in the list of queues - * already used by an other port or QoS - */ - for (rxQueue = 0; - rxQueue < rxQueueCount; - rxQueue++) - { - if (rxQueues[rxQueue].qId == (IxQMgrQId)ixEthDBParameter) - { - /* found an existing setup, update the number of ports - * for this queue if the port maps to - * a different NPE. - */ - if (rxQueues[rxQueue].npeId != ixNpeId) - { - rxQueues[rxQueue].npeCount++; - rxQueues[rxQueue].npeId = ixNpeId; - } - /* get the highest traffic class for this queue */ - if (rxQueues[rxQueue].trafficClass > ixEthDBTrafficClass) - { - rxQueues[rxQueue].trafficClass = ixEthDBTrafficClass; - } - break; - } - } - if (rxQueue == rxQueueCount) - { - /* new queue not found in the current list, - * add a new entry. - */ - IX_OSAL_ASSERT(rxQueueCount < IX_ETHACC_MAX_RX_QUEUES); - rxQueues[rxQueueCount].qId = ixEthDBParameter; - rxQueues[rxQueueCount].npeCount = 1; - rxQueues[rxQueueCount].npeId = ixNpeId; - rxQueues[rxQueueCount].trafficClass = ixEthDBTrafficClass; - rxQueueCount++; - } - } - else - { - /* unexpected property type (not Integer) */ - ret = IX_ETH_ACC_FAIL; - - IX_ETH_ACC_WARNING_LOG("ixEthAccQMgrQueuesConfig: unexpected property type returned by EthDB\n", 0, 0, 0, 0, 0, 0); - - /* no point to continue to iterate */ - break; - } - } - else - { - /* No Rx queue configured for this port - * and this traffic class. Do nothing. - */ - } - } - - /* notify EthDB that queue initialization is complete and traffic class allocation is frozen */ - ixEthDBFeaturePropertySet(ixEthDbPortId, - IX_ETH_DB_VLAN_QOS, - IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE, - NULL /* ignored */); - } - -#else - - ixNpeId = IX_ETH_ACC_PORT_TO_NPE_ID(ixEthAccPortId); - rxQueues[0].qId = 4; - rxQueues[0].npeCount = 1; - rxQueues[0].npeId = ixNpeId; - rxQueues[0].trafficClass = IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY; - rxQueueCount++; - -#endif - - /* check there is at least 1 rx queue : there is no point - * to continue if there is no rx queue configured - */ - if ((rxQueueCount == 0) || (ret == IX_ETH_ACC_FAIL)) - { - IX_ETH_ACC_WARNING_LOG("ixEthAccQMgrQueuesConfig: no queues configured, bailing out\n", 0, 0, 0, 0, 0, 0); - return (IX_ETH_ACC_FAIL); - } - - /* Queue sort step: - * - * Re-order the array of queues by decreasing traffic class - * using a bubble sort. (trafficClass 0 is the lowest - * priority traffic, trafficClass 7 is the highest priority traffic) - * - * Primary sort order is traffic class - * Secondary sort order is npeId - * - * Note that a bubble sort algorithm is not very efficient when - * the number of queues grows . However, this is not a very bad choice - * considering the very small number of entries to sort. Also, bubble - * sort is extremely fast when the list is already sorted. - * - * The output of this loop is a sorted array of queues. - * - */ - sortIterations = 0; - do - { - sortIterations++; - completelySorted = TRUE; - for (rxQueue = 0; - rxQueue < rxQueueCount - sortIterations; - rxQueue++) - { - /* compare adjacent elements */ - if ((rxQueues[rxQueue].trafficClass < - rxQueues[rxQueue+1].trafficClass) - || ((rxQueues[rxQueue].trafficClass == - rxQueues[rxQueue+1].trafficClass) - &&(rxQueues[rxQueue].npeId < - rxQueues[rxQueue+1].npeId))) - { - /* swap adjacent elements */ - int npeCount = rxQueues[rxQueue].npeCount; - UINT32 npeId = rxQueues[rxQueue].npeId; - IxQMgrQId qId = rxQueues[rxQueue].qId; - IxEthDBProperty trafficClass = rxQueues[rxQueue].trafficClass; - rxQueues[rxQueue].npeCount = rxQueues[rxQueue+1].npeCount; - rxQueues[rxQueue].npeId = rxQueues[rxQueue+1].npeId; - rxQueues[rxQueue].qId = rxQueues[rxQueue+1].qId; - rxQueues[rxQueue].trafficClass = rxQueues[rxQueue+1].trafficClass; - rxQueues[rxQueue+1].npeCount = npeCount; - rxQueues[rxQueue+1].npeId = npeId; - rxQueues[rxQueue+1].qId = qId; - rxQueues[rxQueue+1].trafficClass = trafficClass; - completelySorted = FALSE; - } - } - } - while (!completelySorted); - - /* Queue traffic class list: - * - * Fill an array of rx queues linked by ascending traffic classes. - * - * If the queues are configured as follows - * qId 6 -> traffic class 0 (lowest) - * qId 7 -> traffic class 0 - * qId 8 -> traffic class 6 - * qId 12 -> traffic class 7 (highest) - * - * Then the output of this loop will be - * - * higherPriorityQueue[6] = 8 - * higherPriorityQueue[7] = 8 - * higherPriorityQueue[8] = 12 - * higherPriorityQueue[12] = Invalid queueId - * higherPriorityQueue[...] = Invalid queueId - * - * Note that this queue ordering does not handle all possibilities - * that could result from different rules associated with different - * ports, and inconsistencies in the rules. In all cases, the - * output of this algorithm is a simple linked list of queues, - * without closed circuit. - - * This list is implemented as an array with invalid values initialized - * with an "invalid" queue id which is the maximum number of queues. - * - */ - - /* - * Initialise the rx queue list. - */ - for (rxQueue = 0; rxQueue < IX_QMGR_MAX_NUM_QUEUES; rxQueue++) - { - ixEthAccDataInfo.higherPriorityQueue[rxQueue] = IX_QMGR_MAX_NUM_QUEUES; - } - - /* build the linked list for this NPE. - */ - for (ixNpeId = 0; - ixNpeId <= ixHighestNpeId; - ixNpeId++) - { - /* iterate thru the sorted list of queues - */ - ixQId = IX_QMGR_MAX_NUM_QUEUES; - for (rxQueue = 0; - rxQueue < rxQueueCount; - rxQueue++) - { - if (rxQueues[rxQueue].npeId == ixNpeId) - { - ixEthAccDataInfo.higherPriorityQueue[rxQueues[rxQueue].qId] = ixQId; - /* iterate thru queues with the same traffic class - * than the current queue. (queues are ordered by descending - * traffic classes and npeIds). - */ - while ((rxQueue < rxQueueCount - 1) - && (rxQueues[rxQueue].trafficClass - == rxQueues[rxQueue+1].trafficClass) - && (ixNpeId == rxQueues[rxQueue].npeId)) - { - rxQueue++; - ixEthAccDataInfo.higherPriorityQueue[rxQueues[rxQueue].qId] = ixQId; - } - ixQId = rxQueues[rxQueue].qId; - } - } - } - - /* point on the first dynamic queue description */ - qInfoDes = ixEthAccQmgrRxQueuesInfo; - - /* update the list of queues with the rx queues */ - for (rxQueue = 0; - (rxQueue < rxQueueCount) && (ret == IX_ETH_ACC_SUCCESS); - rxQueue++) - { - /* Don't utilize more than IX_ETHACC_MAX_LARGE_RX_QUEUES queues - * with the full 128 entries. For the lower priority queues, use - * a smaller number of entries. This ensures queue resources - * remain available for other components. - */ - if( (rxQueueCount > IX_ETHACC_MAX_LARGE_RX_QUEUES) && - (rxQueue < rxQueueCount - IX_ETHACC_MAX_LARGE_RX_QUEUES) ) - { - /* add the small RX Queue setup template to the list of queues */ - memcpy(qInfoDes, &ixEthAccQmgrRxSmallTemplate, sizeof(*qInfoDes)); - } else { - /* add the default RX Queue setup template to the list of queues */ - memcpy(qInfoDes, &ixEthAccQmgrRxDefaultTemplate, sizeof(*qInfoDes)); - } - - /* setup the RxQueue ID */ - qInfoDes->qId = rxQueues[rxQueue].qId; - - /* setup the RxQueue watermark level - * - * Each queue can be filled by many NPEs. To avoid the - * NPEs to write to a full queue, need to set the - * high watermark level for nearly full condition. - * (the high watermark level are a power of 2 - * starting from the top of the queue) - * - * Number of watermark - * ports level - * 1 0 - * 2 1 - * 3 2 - * 4 4 - * 5 4 - * 6 8 - * n approx. 2**ceil(log2(n)) - */ - if (rxQueues[rxQueue].npeCount == 1) - { - qInfoDes->AlmostFullThreshold = IX_QMGR_Q_WM_LEVEL0; - } - else if (rxQueues[rxQueue].npeCount == 2) - { - qInfoDes->AlmostFullThreshold = IX_QMGR_Q_WM_LEVEL1; - } - else if (rxQueues[rxQueue].npeCount == 3) - { - qInfoDes->AlmostFullThreshold = IX_QMGR_Q_WM_LEVEL2; - } - else - { - /* reach the maximum number for CSR 2.0 */ - IX_ETH_ACC_WARNING_LOG("ixEthAccQMgrQueuesConfig: maximum number of NPEs per queue reached, bailing out\n", 0, 0, 0, 0, 0, 0); - ret = IX_ETH_ACC_FAIL; - break; - } - - /* move to next queue entry */ - ++qInfoDes; - } - - /* configure the static list (RxFree, Tx and TxDone queues) */ - for (qInfoDes = ixEthAccQmgrStaticInfo; - (qInfoDes->qCallback != (IxQMgrCallback) NULL ) - && (ret == IX_ETH_ACC_SUCCESS); - ++qInfoDes) - { - ret = ixEthAccQMgrQueueSetup(qInfoDes); - } - - /* configure the dynamic list (Rx queues) */ - for (qInfoDes = ixEthAccQmgrRxQueuesInfo; - (qInfoDes->qCallback != (IxQMgrCallback) NULL ) - && (ret == IX_ETH_ACC_SUCCESS); - ++qInfoDes) - { - ret = ixEthAccQMgrQueueSetup(qInfoDes); - } - - return(ret); -} - -/** - * @fn ixEthAccQMgrRxQEntryGet(UINT32 *rxQueueEntries) - * - * @brief Add and return the total number of entries in all Rx queues - * - * @param UINT32 rxQueueEntries[in] number of entries in all queues - * - * @return void - * - * @note Rx queues configuration is driven by Qos Setup. There is a - * variable number of rx queues which are set at initialisation. - * - * @internal - */ -IX_ETH_ACC_PUBLIC -void ixEthAccQMgrRxQEntryGet(UINT32 *numRxQueueEntries) -{ - UINT32 rxQueueLevel; - IxEthAccQregInfo *qInfoDes;; - - *numRxQueueEntries = 0; - - /* iterate thru rx queues */ - for (qInfoDes = ixEthAccQmgrRxQueuesInfo; - qInfoDes->qCallback != (IxQMgrCallback)NULL; - ++qInfoDes) - { - /* retrieve the rx queue level */ - rxQueueLevel = 0; - ixQMgrQNumEntriesGet(qInfoDes->qId, &rxQueueLevel); - (*numRxQueueEntries) += rxQueueLevel; - } -} - -/** - * @fn ixEthAccQMgrRxCallbacksRegister(IxQMgrCallback ixQMgrCallback) - * - * @brief Change the callback registered to all rx queues. - * - * @param IxQMgrCallback ixQMgrCallback[in] QMgr callback to register - * - * @return IxEthAccStatus - * - * @note The user may decide to use different Rx mechanisms - * (e.g. receive many frames at the same time , or receive - * one frame at a time, depending on the overall application - * performances). A different QMgr callback is registered. This - * way, there is no excessive pointer checks in the datapath. - * - * @internal - */ -IX_ETH_ACC_PUBLIC -IxEthAccStatus ixEthAccQMgrRxCallbacksRegister(IxQMgrCallback ixQMgrCallback) -{ - IxEthAccQregInfo *qInfoDes; - IxEthAccStatus ret = IX_ETH_ACC_SUCCESS; - - /* parameter check */ - if (NULL == ixQMgrCallback) - { - ret = IX_ETH_ACC_FAIL; - } - - /* iterate thru rx queues */ - for (qInfoDes = ixEthAccQmgrRxQueuesInfo; - (qInfoDes->qCallback != (IxQMgrCallback) NULL ) - && (ret == IX_ETH_ACC_SUCCESS); - ++qInfoDes) - { - /* register the rx callback for all queues */ - if (ixQMgrNotificationCallbackSet(qInfoDes->qId, - ixQMgrCallback, - qInfoDes->callbackTag - ) != IX_SUCCESS) - { - ret = IX_ETH_ACC_FAIL; - } - } - return(ret); -} - -/** - * @fn ixEthAccSingleEthNpeCheck(IxEthAccPortId portId) - * - * @brief Check the npe exists for this port - * - * @param IxEthAccPortId portId[in] port - * - * @return IxEthAccStatus - * - * @internal - */ -IX_ETH_ACC_PUBLIC -IxEthAccStatus ixEthAccSingleEthNpeCheck(IxEthAccPortId 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 ((IX_ETH_PORT_1 == portId) && - (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) == - IX_FEATURE_CTRL_COMPONENT_ENABLED)) - { - return IX_ETH_ACC_SUCCESS; - } - - if ((IX_ETH_PORT_2 == portId) && - (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) == - IX_FEATURE_CTRL_COMPONENT_ENABLED)) - { - return IX_ETH_ACC_SUCCESS; - } - - if ((IX_ETH_PORT_3 == portId) && - (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA_ETH) == - IX_FEATURE_CTRL_COMPONENT_ENABLED)) - { - return IX_ETH_ACC_SUCCESS; - } - - return IX_ETH_ACC_FAIL; - } - - return IX_ETH_ACC_SUCCESS; -} - -/** - * @fn ixEthAccStatsShow(void) - * - * @brief Displays all EthAcc stats - * - * @return void - * - */ -void ixEthAccStatsShow(IxEthAccPortId portId) -{ - ixEthAccMdioShow(); - - printf("\nPort %u\nUnicast MAC : ", portId); - ixEthAccPortUnicastAddressShow(portId); - ixEthAccPortMulticastAddressShow(portId); - printf("\n"); - - ixEthAccDataPlaneShow(); -} - - - diff --git a/cpu/ixp/npe/IxEthAccControlInterface.c b/cpu/ixp/npe/IxEthAccControlInterface.c deleted file mode 100644 index 44328473e6..0000000000 --- a/cpu/ixp/npe/IxEthAccControlInterface.c +++ /dev/null @@ -1,533 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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; -} diff --git a/cpu/ixp/npe/IxEthAccDataPlane.c b/cpu/ixp/npe/IxEthAccDataPlane.c deleted file mode 100644 index b62f0d016e..0000000000 --- a/cpu/ixp/npe/IxEthAccDataPlane.c +++ /dev/null @@ -1,2483 +0,0 @@ -/** - * @file IxEthDataPlane.c - * - * @author Intel Corporation - * @date 12-Feb-2002 - * - * @brief This file contains the implementation of the IXPxxx - * Ethernet Access Data plane component - * - * Design Notes: - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#include "IxNpeMh.h" -#include "IxEthAcc.h" -#include "IxEthDB.h" -#include "IxOsal.h" -#include "IxEthDBPortDefs.h" -#include "IxFeatureCtrl.h" -#include "IxEthAcc_p.h" -#include "IxEthAccQueueAssign_p.h" - -extern PUBLIC IxEthAccMacState ixEthAccMacState[]; -extern PUBLIC UINT32 ixEthAccNewSrcMask; - -/** - * private functions prototype - */ -PRIVATE IX_OSAL_MBUF * -ixEthAccEntryFromQConvert(UINT32 qEntry, UINT32 mask); - -PRIVATE UINT32 -ixEthAccMbufRxQPrepare(IX_OSAL_MBUF *mbuf); - -PRIVATE UINT32 -ixEthAccMbufTxQPrepare(IX_OSAL_MBUF *mbuf); - -PRIVATE IxEthAccStatus -ixEthAccTxSwQHighestPriorityGet(IxEthAccPortId portId, - IxEthAccTxPriority *priorityPtr); - -PRIVATE IxEthAccStatus -ixEthAccTxFromSwQ(IxEthAccPortId portId, - IxEthAccTxPriority priority); - -PRIVATE IxEthAccStatus -ixEthAccRxFreeFromSwQ(IxEthAccPortId portId); - -PRIVATE void -ixEthAccMbufFromTxQ(IX_OSAL_MBUF *mbuf); - -PRIVATE void -ixEthAccMbufFromRxQ(IX_OSAL_MBUF *mbuf); - -PRIVATE IX_STATUS -ixEthAccQmgrLockTxWrite(IxEthAccPortId portId, - UINT32 qBuffer); - -PRIVATE IX_STATUS -ixEthAccQmgrLockRxWrite(IxEthAccPortId portId, - UINT32 qBuffer); - -PRIVATE IX_STATUS -ixEthAccQmgrTxWrite(IxEthAccPortId portId, - UINT32 qBuffer, - UINT32 priority); - -/** - * @addtogroup IxEthAccPri - *@{ - */ - -/* increment a counter only when stats are enabled */ -#define TX_STATS_INC(port,field) \ - IX_ETH_ACC_STATS_INC(ixEthAccPortData[port].ixEthAccTxData.stats.field) -#define RX_STATS_INC(port,field) \ - IX_ETH_ACC_STATS_INC(ixEthAccPortData[port].ixEthAccRxData.stats.field) - -/* always increment the counter (mainly used for unexpected errors) */ -#define TX_INC(port,field) \ - ixEthAccPortData[port].ixEthAccTxData.stats.field++ -#define RX_INC(port,field) \ - ixEthAccPortData[port].ixEthAccRxData.stats.field++ - -PRIVATE IxEthAccDataPlaneStats ixEthAccDataStats; - -extern IxEthAccPortDataInfo ixEthAccPortData[]; -extern IxEthAccInfo ixEthAccDataInfo; - -PRIVATE IxOsalFastMutex txWriteMutex[IX_ETH_ACC_NUMBER_OF_PORTS]; -PRIVATE IxOsalFastMutex rxWriteMutex[IX_ETH_ACC_NUMBER_OF_PORTS]; - -/** - * - * @brief Mbuf header conversion macros : they implement the - * different conversions using a temporary value. They also double-check - * that the parameters can be converted to/from NPE format. - * - */ -#if defined(__wince) && !defined(IN_KERNEL) -#define PTR_VIRT2NPE(ptrSrc,dst) \ - do { UINT32 temp; \ - IX_OSAL_ENSURE(sizeof(ptrSrc) == sizeof(UINT32), "Wrong parameter type"); \ - IX_OSAL_ENSURE(sizeof(dst) == sizeof(UINT32), "Wrong parameter type"); \ - temp = (UINT32)IX_OSAL_MBUF_MBUF_VIRTUAL_TO_PHYSICAL_TRANSLATION((IX_OSAL_MBUF*)ptrSrc); \ - (dst) = IX_OSAL_SWAP_BE_SHARED_LONG(temp); } \ - while(0) - -#define PTR_NPE2VIRT(type,src,ptrDst) \ - do { void *temp; \ - IX_OSAL_ENSURE(sizeof(type) == sizeof(UINT32), "Wrong parameter type"); \ - IX_OSAL_ENSURE(sizeof(src) == sizeof(UINT32), "Wrong parameter type"); \ - IX_OSAL_ENSURE(sizeof(ptrDst) == sizeof(UINT32), "Wrong parameter type"); \ - temp = (void *)IX_OSAL_SWAP_BE_SHARED_LONG(src); \ - (ptrDst) = (type)IX_OSAL_MBUF_MBUF_PHYSICAL_TO_VIRTUAL_TRANSLATION(temp); } \ - while(0) -#else -#define PTR_VIRT2NPE(ptrSrc,dst) \ - do { UINT32 temp; \ - IX_OSAL_ENSURE(sizeof(ptrSrc) == sizeof(UINT32), "Wrong parameter type"); \ - IX_OSAL_ENSURE(sizeof(dst) == sizeof(UINT32), "Wrong parameter type"); \ - temp = (UINT32)IX_OSAL_MMU_VIRT_TO_PHYS(ptrSrc); \ - (dst) = IX_OSAL_SWAP_BE_SHARED_LONG(temp); } \ - while(0) - -#define PTR_NPE2VIRT(type,src,ptrDst) \ - do { void *temp; \ - IX_OSAL_ENSURE(sizeof(type) == sizeof(UINT32), "Wrong parameter type"); \ - IX_OSAL_ENSURE(sizeof(src) == sizeof(UINT32), "Wrong parameter type"); \ - IX_OSAL_ENSURE(sizeof(ptrDst) == sizeof(UINT32), "Wrong parameter type"); \ - temp = (void *)IX_OSAL_SWAP_BE_SHARED_LONG(src); \ - (ptrDst) = (type)IX_OSAL_MMU_PHYS_TO_VIRT(temp); } \ - while(0) -#endif - -/** - * - * @brief Mbuf payload pointer conversion macros : Wince has its own - * method to convert the buffer pointers - */ -#if defined(__wince) && !defined(IN_KERNEL) -#define DATAPTR_VIRT2NPE(ptrSrc,dst) \ - do { UINT32 temp; \ - temp = (UINT32)IX_OSAL_MBUF_DATA_VIRTUAL_TO_PHYSICAL_TRANSLATION(ptrSrc); \ - (dst) = IX_OSAL_SWAP_BE_SHARED_LONG(temp); } \ - while(0) - -#else -#define DATAPTR_VIRT2NPE(ptrSrc,dst) PTR_VIRT2NPE(IX_OSAL_MBUF_MDATA(ptrSrc),dst) -#endif - - -/* Flush the shared part of the mbuf header */ -#define IX_ETHACC_NE_CACHE_FLUSH(mbufPtr) \ - do { \ - IX_OSAL_CACHE_FLUSH(IX_ETHACC_NE_SHARED(mbufPtr), \ - sizeof(IxEthAccNe)); \ - } \ - while(0) - -/* Invalidate the shared part of the mbuf header */ -#define IX_ETHACC_NE_CACHE_INVALIDATE(mbufPtr) \ - do { \ - IX_OSAL_CACHE_INVALIDATE(IX_ETHACC_NE_SHARED(mbufPtr), \ - sizeof(IxEthAccNe)); \ - } \ - while(0) - -/* Preload one cache line (shared mbuf headers are aligned - * and their size is 1 cache line) - * - * IX_OSAL_CACHED is defined when the mbuf headers are - * allocated from cached memory. - * - * Other processor on emulation environment may not implement - * preload function - */ -#ifdef IX_OSAL_CACHED - #if (CPU!=SIMSPARCSOLARIS) && !defined (__wince) - #define IX_ACC_DATA_CACHE_PRELOAD(ptr) \ - do { /* preload a cache line (Xscale Processor) */ \ - __asm__ (" pld [%0]\n": : "r" (ptr)); \ - } \ - while(0) - #else - /* preload not implemented on different processor */ - #define IX_ACC_DATA_CACHE_PRELOAD(mbufPtr) \ - do { /* nothing */ } while (0) - #endif -#else - /* preload not needed if cache is not enabled */ - #define IX_ACC_DATA_CACHE_PRELOAD(mbufPtr) \ - do { /* nothing */ } while (0) -#endif - -/** - * - * @brief function to retrieve the correct pointer from - * a queue entry posted by the NPE - * - * @param qEntry : entry from qmgr queue - * mask : applicable mask for this queue - * (4 most significant bits are used for additional informations) - * - * @return IX_OSAL_MBUF * pointer to mbuf header - * - * @internal - */ -PRIVATE IX_OSAL_MBUF * -ixEthAccEntryFromQConvert(UINT32 qEntry, UINT32 mask) -{ - IX_OSAL_MBUF *mbufPtr; - - if (qEntry != 0) - { - /* mask NPE bits (e.g. priority, port ...) */ - qEntry &= mask; - -#if IX_ACC_DRAM_PHYS_OFFSET != 0 - /* restore the original address pointer (if PHYS_OFFSET is not 0) */ - qEntry |= (IX_ACC_DRAM_PHYS_OFFSET & ~IX_ETHNPE_QM_Q_RXENET_ADDR_MASK); -#endif - /* get the mbuf pointer address from the npe-shared address */ - qEntry -= offsetof(IX_OSAL_MBUF,ix_ne); - - /* phys2virt mbuf */ - mbufPtr = (IX_OSAL_MBUF *)IX_OSAL_MMU_PHYS_TO_VIRT(qEntry); - - /* preload the cacheline shared with NPE */ - IX_ACC_DATA_CACHE_PRELOAD(IX_ETHACC_NE_SHARED(mbufPtr)); - - /* preload the cacheline used by xscale */ - IX_ACC_DATA_CACHE_PRELOAD(mbufPtr); - } - else - { - mbufPtr = NULL; - } - - return mbufPtr; -} - -/* Convert the mbuf header for NPE transmission */ -PRIVATE UINT32 -ixEthAccMbufTxQPrepare(IX_OSAL_MBUF *mbuf) -{ - UINT32 qbuf; - UINT32 len; - - /* endianess swap for tci and flags - note: this is done only once, even for chained buffers */ - IX_ETHACC_NE_FLAGS(mbuf) = IX_OSAL_SWAP_BE_SHARED_SHORT(IX_ETHACC_NE_FLAGS(mbuf)); - IX_ETHACC_NE_VLANTCI(mbuf) = IX_OSAL_SWAP_BE_SHARED_SHORT(IX_ETHACC_NE_VLANTCI(mbuf)); - - /* test for unchained mbufs */ - if (IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbuf) == NULL) - { - /* "best case" scenario : unchained mbufs */ - IX_ETH_ACC_STATS_INC(ixEthAccDataStats.unchainedTxMBufs); - - /* payload pointer conversion */ - DATAPTR_VIRT2NPE(mbuf, IX_ETHACC_NE_DATA(mbuf)); - - /* unchained mbufs : the frame length is the mbuf length - * and the 2 identical lengths are stored in the same - * word. - */ - len = IX_OSAL_MBUF_MLEN(mbuf); - - /* set the length in both length and pktLen 16-bits fields */ - len |= (len << IX_ETHNPE_ACC_LENGTH_OFFSET); - IX_ETHACC_NE_LEN(mbuf) = IX_OSAL_SWAP_BE_SHARED_LONG(len); - - /* unchained mbufs : next contains 0 */ - IX_ETHACC_NE_NEXT(mbuf) = 0; - - /* flush shared header after all address conversions */ - IX_ETHACC_NE_CACHE_FLUSH(mbuf); - } - else - { - /* chained mbufs */ - IX_OSAL_MBUF *ptr = mbuf; - IX_OSAL_MBUF *nextPtr; - UINT32 frmLen; - - /* get the frame length from the header of the first buffer */ - frmLen = IX_OSAL_MBUF_PKT_LEN(mbuf); - - do - { - IX_ETH_ACC_STATS_INC(ixEthAccDataStats.chainedTxMBufs); - - /* payload pointer */ - DATAPTR_VIRT2NPE(ptr,IX_ETHACC_NE_DATA(ptr)); - /* Buffer length and frame length are stored in the same word */ - len = IX_OSAL_MBUF_MLEN(ptr); - len = frmLen | (len << IX_ETHNPE_ACC_LENGTH_OFFSET); - IX_ETHACC_NE_LEN(ptr) = IX_OSAL_SWAP_BE_SHARED_LONG(len); - - /* get the virtual next chain pointer */ - nextPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(ptr); - if (nextPtr != NULL) - { - /* shared pointer of the next buffer is chained */ - PTR_VIRT2NPE(IX_ETHACC_NE_SHARED(nextPtr), - IX_ETHACC_NE_NEXT(ptr)); - } - else - { - IX_ETHACC_NE_NEXT(ptr) = 0; - } - - /* flush shared header after all address conversions */ - IX_ETHACC_NE_CACHE_FLUSH(ptr); - - /* move to next buffer */ - ptr = nextPtr; - - /* the frame length field is set only in the first buffer - * and is zeroed in the next buffers - */ - frmLen = 0; - } - while(ptr != NULL); - - } - - /* virt2phys mbuf itself */ - qbuf = (UINT32)IX_OSAL_MMU_VIRT_TO_PHYS( - IX_ETHACC_NE_SHARED(mbuf)); - - /* Ensure the bits which are reserved to exchange information with - * the NPE are cleared - * - * If the mbuf address is not correctly aligned, or from an - * incompatible memory range, there is no point to continue - */ - IX_OSAL_ENSURE(((qbuf & ~IX_ETHNPE_QM_Q_TXENET_ADDR_MASK) == 0), - "Invalid address range"); - - return qbuf; -} - -/* Convert the mbuf header for NPE reception */ -PRIVATE UINT32 -ixEthAccMbufRxQPrepare(IX_OSAL_MBUF *mbuf) -{ - UINT32 len; - UINT32 qbuf; - - if (IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbuf) == NULL) - { - /* "best case" scenario : unchained mbufs */ - IX_ETH_ACC_STATS_INC(ixEthAccDataStats.unchainedRxFreeMBufs); - - /* unchained mbufs : payload pointer */ - DATAPTR_VIRT2NPE(mbuf, IX_ETHACC_NE_DATA(mbuf)); - - /* unchained mbufs : set the buffer length - * and the frame length field is zeroed - */ - len = (IX_OSAL_MBUF_MLEN(mbuf) << IX_ETHNPE_ACC_LENGTH_OFFSET); - IX_ETHACC_NE_LEN(mbuf) = IX_OSAL_SWAP_BE_SHARED_LONG(len); - - /* unchained mbufs : next pointer is null */ - IX_ETHACC_NE_NEXT(mbuf) = 0; - - /* flush shared header after all address conversions */ - IX_ETHACC_NE_CACHE_FLUSH(mbuf); - - /* remove shared header cache line */ - IX_ETHACC_NE_CACHE_INVALIDATE(mbuf); - } - else - { - /* chained mbufs */ - IX_OSAL_MBUF *ptr = mbuf; - IX_OSAL_MBUF *nextPtr; - - do - { - /* chained mbufs */ - IX_ETH_ACC_STATS_INC(ixEthAccDataStats.chainedRxFreeMBufs); - - /* we must save virtual next chain pointer */ - nextPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(ptr); - - if (nextPtr != NULL) - { - /* chaining pointer for NPE */ - PTR_VIRT2NPE(IX_ETHACC_NE_SHARED(nextPtr), - IX_ETHACC_NE_NEXT(ptr)); - } - else - { - IX_ETHACC_NE_NEXT(ptr) = 0; - } - - /* payload pointer */ - DATAPTR_VIRT2NPE(ptr,IX_ETHACC_NE_DATA(ptr)); - - /* buffer length */ - len = (IX_OSAL_MBUF_MLEN(ptr) << IX_ETHNPE_ACC_LENGTH_OFFSET); - IX_ETHACC_NE_LEN(ptr) = IX_OSAL_SWAP_BE_SHARED_LONG(len); - - /* flush shared header after all address conversions */ - IX_ETHACC_NE_CACHE_FLUSH(ptr); - - /* remove shared header cache line */ - IX_ETHACC_NE_CACHE_INVALIDATE(ptr); - - /* next mbuf in the chain */ - ptr = nextPtr; - } - while(ptr != NULL); - } - - /* virt2phys mbuf itself */ - qbuf = (UINT32)IX_OSAL_MMU_VIRT_TO_PHYS( - IX_ETHACC_NE_SHARED(mbuf)); - - /* Ensure the bits which are reserved to exchange information with - * the NPE are cleared - * - * If the mbuf address is not correctly aligned, or from an - * incompatible memory range, there is no point to continue - */ - IX_OSAL_ENSURE(((qbuf & ~IX_ETHNPE_QM_Q_RXENET_ADDR_MASK) == 0), - "Invalid address range"); - - return qbuf; -} - -/* Convert the mbuf header after NPE transmission - * Since there is nothing changed by the NPE, there is no need - * to process anything but the update of internal stats - * when they are enabled -*/ -PRIVATE void -ixEthAccMbufFromTxQ(IX_OSAL_MBUF *mbuf) -{ -#ifndef NDEBUG - /* test for unchained mbufs */ - if (IX_ETHACC_NE_NEXT(mbuf) == 0) - { - /* unchained mbufs : update the stats */ - IX_ETH_ACC_STATS_INC(ixEthAccDataStats.unchainedTxDoneMBufs); - } - else - { - /* chained mbufs : walk the chain and update the stats */ - IX_OSAL_MBUF *ptr = mbuf; - - do - { - IX_ETH_ACC_STATS_INC(ixEthAccDataStats.chainedTxDoneMBufs); - ptr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(ptr); - } - while (ptr != NULL); - } -#endif -} - -/* Convert the mbuf header after NPE reception */ -PRIVATE void -ixEthAccMbufFromRxQ(IX_OSAL_MBUF *mbuf) -{ - UINT32 len; - - /* endianess swap for tci and flags - note: this is done only once, even for chained buffers */ - IX_ETHACC_NE_FLAGS(mbuf) = IX_OSAL_SWAP_BE_SHARED_SHORT(IX_ETHACC_NE_FLAGS(mbuf)); - IX_ETHACC_NE_VLANTCI(mbuf) = IX_OSAL_SWAP_BE_SHARED_SHORT(IX_ETHACC_NE_VLANTCI(mbuf)); - - /* test for unchained mbufs */ - if (IX_ETHACC_NE_NEXT(mbuf) == 0) - { - /* unchained mbufs */ - IX_ETH_ACC_STATS_INC(ixEthAccDataStats.unchainedRxMBufs); - - /* get the frame length. it is the same than the buffer length */ - len = IX_OSAL_SWAP_BE_SHARED_LONG(IX_ETHACC_NE_LEN(mbuf)); - len &= IX_ETHNPE_ACC_PKTLENGTH_MASK; - IX_OSAL_MBUF_PKT_LEN(mbuf) = IX_OSAL_MBUF_MLEN(mbuf) = len; - - /* clears the next packet field */ - IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbuf) = NULL; - } - else - { - IX_OSAL_MBUF *ptr = mbuf; - IX_OSAL_MBUF *nextPtr; - UINT32 frmLen; - - /* convert the frame length */ - frmLen = IX_OSAL_SWAP_BE_SHARED_LONG(IX_ETHACC_NE_LEN(mbuf)); - IX_OSAL_MBUF_PKT_LEN(mbuf) = (frmLen & IX_ETHNPE_ACC_PKTLENGTH_MASK); - - /* chained mbufs */ - do - { - IX_ETH_ACC_STATS_INC(ixEthAccDataStats.chainedRxMBufs); - - /* convert the length */ - len = IX_OSAL_SWAP_BE_SHARED_LONG(IX_ETHACC_NE_LEN(ptr)); - IX_OSAL_MBUF_MLEN(ptr) = (len >> IX_ETHNPE_ACC_LENGTH_OFFSET); - - /* get the next pointer */ - PTR_NPE2VIRT(IX_OSAL_MBUF *,IX_ETHACC_NE_NEXT(ptr), nextPtr); - if (nextPtr != NULL) - { - nextPtr = (IX_OSAL_MBUF *)((UINT8 *)nextPtr - offsetof(IX_OSAL_MBUF,ix_ne)); - } - /* set the next pointer */ - IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(ptr) = nextPtr; - - /* move to the next buffer */ - ptr = nextPtr; - } - while (ptr != NULL); - } -} - -/* write to qmgr if possible and report an overflow if not possible - * Use a fast lock to protect the queue write. - * This way, the tx feature is reentrant. - */ -PRIVATE IX_STATUS -ixEthAccQmgrLockTxWrite(IxEthAccPortId portId, UINT32 qBuffer) -{ - IX_STATUS qStatus; - if (ixOsalFastMutexTryLock(&txWriteMutex[portId]) == IX_SUCCESS) - { - qStatus = ixQMgrQWrite( - IX_ETH_ACC_PORT_TO_TX_Q_ID(portId), - &qBuffer); -#ifndef NDEBUG - if (qStatus != IX_SUCCESS) - { - TX_STATS_INC(portId, txOverflow); - } -#endif - ixOsalFastMutexUnlock(&txWriteMutex[portId]); - } - else - { - TX_STATS_INC(portId, txLock); - qStatus = IX_QMGR_Q_OVERFLOW; - } - return qStatus; -} - -/* write to qmgr if possible and report an overflow if not possible - * Use a fast lock to protect the queue write. - * This way, the Rx feature is reentrant. - */ -PRIVATE IX_STATUS -ixEthAccQmgrLockRxWrite(IxEthAccPortId portId, UINT32 qBuffer) -{ - IX_STATUS qStatus; - if (ixOsalFastMutexTryLock(&rxWriteMutex[portId]) == IX_SUCCESS) - { - qStatus = ixQMgrQWrite( - IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(portId), - &qBuffer); -#ifndef NDEBUG - if (qStatus != IX_SUCCESS) - { - RX_STATS_INC(portId, rxFreeOverflow); - } -#endif - ixOsalFastMutexUnlock(&rxWriteMutex[portId]); - } - else - { - RX_STATS_INC(portId, rxFreeLock); - qStatus = IX_QMGR_Q_OVERFLOW; - } - return qStatus; -} - -/* - * Set the priority and write to a qmgr queue. - */ -PRIVATE IX_STATUS -ixEthAccQmgrTxWrite(IxEthAccPortId portId, UINT32 qBuffer, UINT32 priority) -{ - /* fill the priority field */ - qBuffer |= (priority << IX_ETHNPE_QM_Q_FIELD_PRIOR_R); - - return ixEthAccQmgrLockTxWrite(portId, qBuffer); -} - -/** - * - * @brief This function will discover the highest priority S/W Tx Q that - * has entries in it - * - * @param portId - (in) the id of the port whose S/W Tx queues are to be searched - * priorityPtr - (out) the priority of the highest priority occupied q will be written - * here - * - * @return IX_ETH_ACC_SUCCESS if an occupied Q is found - * IX_ETH_ACC_FAIL if no Q has entries - * - * @internal - */ -PRIVATE IxEthAccStatus -ixEthAccTxSwQHighestPriorityGet(IxEthAccPortId portId, - IxEthAccTxPriority *priorityPtr) -{ - if (ixEthAccPortData[portId].ixEthAccTxData.schDiscipline - == FIFO_NO_PRIORITY) - { - if(IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(ixEthAccPortData[portId]. - ixEthAccTxData.txQ[IX_ETH_ACC_TX_DEFAULT_PRIORITY])) - { - return IX_ETH_ACC_FAIL; - } - else - { - *priorityPtr = IX_ETH_ACC_TX_DEFAULT_PRIORITY; - TX_STATS_INC(portId,txPriority[*priorityPtr]); - return IX_ETH_ACC_SUCCESS; - } - } - else - { - IxEthAccTxPriority highestPriority = IX_ETH_ACC_TX_PRIORITY_7; - while(1) - { - if(!IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(ixEthAccPortData[portId]. - ixEthAccTxData.txQ[highestPriority])) - { - - *priorityPtr = highestPriority; - TX_STATS_INC(portId,txPriority[highestPriority]); - return IX_ETH_ACC_SUCCESS; - - } - if (highestPriority == IX_ETH_ACC_TX_PRIORITY_0) - { - return IX_ETH_ACC_FAIL; - } - highestPriority--; - } - } -} - -/** - * - * @brief This function will take a buffer from a TX S/W Q and attempt - * to add it to the relevant TX H/W Q - * - * @param portId - the port whose TX queue is to be written to - * priority - identifies the queue from which the entry is to be read - * - * @internal - */ -PRIVATE IxEthAccStatus -ixEthAccTxFromSwQ(IxEthAccPortId portId, - IxEthAccTxPriority priority) -{ - IX_OSAL_MBUF *mbuf; - IX_STATUS qStatus; - - IX_OSAL_ENSURE((UINT32)priority <= (UINT32)7, "Invalid priority"); - - IX_ETH_ACC_DATAPLANE_REMOVE_MBUF_FROM_Q_HEAD( - ixEthAccPortData[portId].ixEthAccTxData.txQ[priority], - mbuf); - - if (mbuf != NULL) - { - /* - * Add the Tx buffer to the H/W Tx Q - * We do not need to flush here as it is already done - * in TxFrameSubmit(). - */ - qStatus = ixEthAccQmgrTxWrite( - portId, - IX_OSAL_MMU_VIRT_TO_PHYS((UINT32)IX_ETHACC_NE_SHARED(mbuf)), - priority); - - if (qStatus == IX_SUCCESS) - { - TX_STATS_INC(portId,txFromSwQOK); - return IX_SUCCESS; - } - else if (qStatus == IX_QMGR_Q_OVERFLOW) - { - /* - * H/W Q overflow, need to save the buffer - * back on the s/w Q. - * we must put it back on the head of the q to avoid - * reordering packet tx - */ - TX_STATS_INC(portId,txFromSwQDelayed); - IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD( - ixEthAccPortData[portId].ixEthAccTxData.txQ[priority], - mbuf); - - /*enable Q notification*/ - qStatus = ixQMgrNotificationEnable( - IX_ETH_ACC_PORT_TO_TX_Q_ID(portId), - IX_ETH_ACC_PORT_TO_TX_Q_SOURCE(portId)); - - if (qStatus != IX_SUCCESS && qStatus != IX_QMGR_WARNING) - { - TX_INC(portId,txUnexpectedError); - IX_ETH_ACC_FATAL_LOG( - "ixEthAccTxFromSwQ:Unexpected Error: %u\n", - qStatus, 0, 0, 0, 0, 0); - } - } - else - { - TX_INC(portId,txUnexpectedError); - - /* recovery attempt */ - IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD( - ixEthAccPortData[portId].ixEthAccTxData.txQ[priority], - mbuf); - - IX_ETH_ACC_FATAL_LOG( - "ixEthAccTxFromSwQ:Error: unexpected QM status 0x%08X\n", - qStatus, 0, 0, 0, 0, 0); - } - } - else - { - /* sw queue is empty */ - } - return IX_ETH_ACC_FAIL; -} - -/** - * - * @brief This function will take a buffer from a RXfree S/W Q and attempt - * to add it to the relevant RxFree H/W Q - * - * @param portId - the port whose RXFree queue is to be written to - * - * @internal - */ -PRIVATE IxEthAccStatus -ixEthAccRxFreeFromSwQ(IxEthAccPortId portId) -{ - IX_OSAL_MBUF *mbuf; - IX_STATUS qStatus = IX_SUCCESS; - - IX_ETH_ACC_DATAPLANE_REMOVE_MBUF_FROM_Q_HEAD( - ixEthAccPortData[portId].ixEthAccRxData.freeBufferList, - mbuf); - if (mbuf != NULL) - { - /* - * Add The Rx Buffer to the H/W Free buffer Q if possible - */ - qStatus = ixEthAccQmgrLockRxWrite(portId, - IX_OSAL_MMU_VIRT_TO_PHYS( - (UINT32)IX_ETHACC_NE_SHARED(mbuf))); - - if (qStatus == IX_SUCCESS) - { - RX_STATS_INC(portId,rxFreeRepFromSwQOK); - /* - * Buffer added to h/w Q. - */ - return IX_SUCCESS; - } - else if (qStatus == IX_QMGR_Q_OVERFLOW) - { - /* - * H/W Q overflow, need to save the buffer back on the s/w Q. - */ - RX_STATS_INC(portId,rxFreeRepFromSwQDelayed); - - IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD( - ixEthAccPortData[portId].ixEthAccRxData.freeBufferList, - mbuf); - } - else - { - /* unexpected qmgr error */ - RX_INC(portId,rxUnexpectedError); - - IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD( - ixEthAccPortData[portId].ixEthAccRxData.freeBufferList, - mbuf); - - IX_ETH_ACC_FATAL_LOG("IxEthAccRxFreeFromSwQ:Error: unexpected QM status 0x%08X\n", - qStatus, 0, 0, 0, 0, 0); - } - } - else - { - /* sw queue is empty */ - } - return IX_ETH_ACC_FAIL; -} - - -IX_ETH_ACC_PUBLIC -IxEthAccStatus ixEthAccInitDataPlane() -{ - UINT32 portId; - - /* - * Initialize the service and register callback to other services. - */ - - IX_ETH_ACC_MEMSET(&ixEthAccDataStats, - 0, - sizeof(ixEthAccDataStats)); - - for(portId=0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) - { - ixOsalFastMutexInit(&txWriteMutex[portId]); - ixOsalFastMutexInit(&rxWriteMutex[portId]); - - IX_ETH_ACC_MEMSET(&ixEthAccPortData[portId], - 0, - sizeof(ixEthAccPortData[portId])); - - ixEthAccPortData[portId].ixEthAccTxData.schDiscipline = FIFO_NO_PRIORITY; - } - - return (IX_ETH_ACC_SUCCESS); -} - - -IX_ETH_ACC_PUBLIC -IxEthAccStatus ixEthAccPortTxDoneCallbackRegister(IxEthAccPortId portId, - IxEthAccPortTxDoneCallback - txCallbackFn, - UINT32 callbackTag) -{ - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - if (!IX_ETH_ACC_IS_PORT_VALID(portId)) - { - return (IX_ETH_ACC_INVALID_PORT); - } - -/* HACK: removing this code to enable NPE-A preliminary testing - * if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - * { - * IX_ETH_ACC_WARNING_LOG("ixEthAccPortTxDoneCallbackRegister: Unavailable Eth %d: Cannot register TxDone Callback.\n",(INT32)portId,0,0,0,0,0); - * return IX_ETH_ACC_SUCCESS ; - * } - */ - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - if (txCallbackFn == 0) - /* Check for null function pointer here. */ - { - return (IX_ETH_ACC_INVALID_ARG); - } - ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn = txCallbackFn; - ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag = callbackTag; - return (IX_ETH_ACC_SUCCESS); -} - - -IX_ETH_ACC_PUBLIC -IxEthAccStatus ixEthAccPortRxCallbackRegister(IxEthAccPortId portId, - IxEthAccPortRxCallback - rxCallbackFn, - UINT32 callbackTag) -{ - IxEthAccPortId port; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - 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("ixEthAccPortRxCallbackRegister: Unavailable Eth %d: Cannot register Rx Callback.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - /* Check for null function pointer here. */ - if (rxCallbackFn == NULL) - { - return (IX_ETH_ACC_INVALID_ARG); - } - - /* Check the user is not changing the callback type - * when the port is enabled. - */ - if (ixEthAccMacState[portId].portDisableState == ACTIVE) - { - for (port = 0; port < IX_ETH_ACC_NUMBER_OF_PORTS; port++) - { - if ((ixEthAccMacState[port].portDisableState == ACTIVE) - && (ixEthAccPortData[port].ixEthAccRxData.rxMultiBufferCallbackInUse == TRUE)) - { - /* one of the active ports has a different rx callback type. - * Changing the callback type when the port is enabled - * is not safe - */ - return (IX_ETH_ACC_INVALID_ARG); - } - } - } - - /* update the callback pointer : this is done before - * registering the new qmgr callback - */ - ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn = rxCallbackFn; - ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag = callbackTag; - - /* update the qmgr callback for rx queues */ - if (ixEthAccQMgrRxCallbacksRegister(ixEthRxFrameQMCallback) - != IX_ETH_ACC_SUCCESS) - { - /* unexpected qmgr error */ - IX_ETH_ACC_FATAL_LOG("ixEthAccPortRxCallbackRegister: unexpected QMgr error, " \ - "could not register Rx single-buffer callback\n", 0, 0, 0, 0, 0, 0); - - RX_INC(portId,rxUnexpectedError); - return (IX_ETH_ACC_INVALID_ARG); - } - - ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackInUse = FALSE; - - return (IX_ETH_ACC_SUCCESS); -} - -IX_ETH_ACC_PUBLIC -IxEthAccStatus ixEthAccPortMultiBufferRxCallbackRegister( - IxEthAccPortId portId, - IxEthAccPortMultiBufferRxCallback - rxCallbackFn, - UINT32 callbackTag) -{ - IxEthAccPortId port; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - 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("ixEthAccPortMultiBufferRxCallbackRegister: Unavailable Eth %d: Cannot register Rx Callback.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - /* Check for null function pointer here. */ - if (rxCallbackFn == NULL) - { - return (IX_ETH_ACC_INVALID_ARG); - } - - /* Check the user is not changing the callback type - * when the port is enabled. - */ - if (ixEthAccMacState[portId].portDisableState == ACTIVE) - { - for (port = 0; port < IX_ETH_ACC_NUMBER_OF_PORTS; port++) - { - if ((ixEthAccMacState[port].portDisableState == ACTIVE) - && (ixEthAccPortData[port].ixEthAccRxData.rxMultiBufferCallbackInUse == FALSE)) - { - /* one of the active ports has a different rx callback type. - * Changing the callback type when the port is enabled - * is not safe - */ - return (IX_ETH_ACC_INVALID_ARG); - } - } - } - - /* update the callback pointer : this is done before - * registering the new qmgr callback - */ - ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn = rxCallbackFn; - ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag = callbackTag; - - /* update the qmgr callback for rx queues */ - if (ixEthAccQMgrRxCallbacksRegister(ixEthRxMultiBufferQMCallback) - != IX_ETH_ACC_SUCCESS) - { - /* unexpected qmgr error */ - RX_INC(portId,rxUnexpectedError); - - IX_ETH_ACC_FATAL_LOG("ixEthAccPortMultiBufferRxCallbackRegister: unexpected QMgr error, " \ - "could not register Rx multi-buffer callback\n", 0, 0, 0, 0, 0, 0); - - return (IX_ETH_ACC_INVALID_ARG); - } - - ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackInUse = TRUE; - - return (IX_ETH_ACC_SUCCESS); -} - -IX_ETH_ACC_PUBLIC -IxEthAccStatus ixEthAccPortTxFrameSubmit(IxEthAccPortId portId, - IX_OSAL_MBUF *buffer, - IxEthAccTxPriority priority) -{ - IX_STATUS qStatus = IX_SUCCESS; - UINT32 qBuffer; - IxEthAccTxPriority highestPriority; - IxQMgrQStatus txQStatus; - -#ifndef NDEBUG - if (buffer == NULL) - { - return (IX_ETH_ACC_FAIL); - } - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - if (!IX_ETH_ACC_IS_PORT_VALID(portId)) - { - return (IX_ETH_ACC_INVALID_PORT); - } - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_FATAL_LOG("ixEthAccPortTxFrameSubmit: Unavailable Eth %d: Cannot submit Tx Frame.\n", - (INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_PORT_UNINITIALIZED ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - if ((UINT32)priority > (UINT32)IX_ETH_ACC_TX_PRIORITY_7) - { - return (IX_ETH_ACC_INVALID_ARG); - } -#endif - - /* - * Need to Flush the MBUF and its contents (data) as it may be - * read from the NPE. Convert virtual addresses to physical addresses also. - */ - qBuffer = ixEthAccMbufTxQPrepare(buffer); - - /* - * If no fifo priority set on Xscale ... - */ - if (ixEthAccPortData[portId].ixEthAccTxData.schDiscipline == - FIFO_NO_PRIORITY) - { - /* - * Add The Tx Buffer to the H/W Tx Q if possible - * (the priority is passed to the NPE, because - * the NPE is able to reorder the frames - * before transmission to the underlying hardware) - */ - qStatus = ixEthAccQmgrTxWrite(portId, - qBuffer, - IX_ETH_ACC_TX_DEFAULT_PRIORITY); - - if (qStatus == IX_SUCCESS) - { - TX_STATS_INC(portId,txQOK); - - /* - * "best case" scenario : Buffer added to h/w Q. - */ - return (IX_SUCCESS); - } - else if (qStatus == IX_QMGR_Q_OVERFLOW) - { - /* - * We were unable to write the buffer to the - * appropriate H/W Q, Save it in the sw Q. - * (use the default priority queue regardless of - * input parameter) - */ - priority = IX_ETH_ACC_TX_DEFAULT_PRIORITY; - } - else - { - /* unexpected qmgr error */ - TX_INC(portId,txUnexpectedError); - IX_ETH_ACC_FATAL_LOG( - "ixEthAccPortTxFrameSubmit:Error: qStatus = %u\n", - (UINT32)qStatus, 0, 0, 0, 0, 0); - return (IX_ETH_ACC_FAIL); - } - } - else if (ixEthAccPortData[portId].ixEthAccTxData.schDiscipline == - FIFO_PRIORITY) - { - - /* - * For priority transmission, put the frame directly on the H/W queue - * if the H/W queue is empty, otherwise, put it in a S/W Q - */ - ixQMgrQStatusGet(IX_ETH_ACC_PORT_TO_TX_Q_ID(portId), &txQStatus); - if((txQStatus & IX_QMGR_Q_STATUS_E_BIT_MASK) != 0) - { - /*The tx queue is empty, check whether there are buffers on the s/w queues*/ - if(ixEthAccTxSwQHighestPriorityGet(portId, &highestPriority) - !=IX_ETH_ACC_FAIL) - { - /*there are buffers on the s/w queues, submit them*/ - ixEthAccTxFromSwQ(portId, highestPriority); - - /* the queue was empty, 1 buffer is already supplied - * but is likely to be immediately transmitted and the - * hw queue is likely to be empty again, so submit - * more from the sw queues - */ - if(ixEthAccTxSwQHighestPriorityGet(portId, &highestPriority) - !=IX_ETH_ACC_FAIL) - { - ixEthAccTxFromSwQ(portId, highestPriority); - /* - * and force the buffer supplied to be placed - * on a priority queue - */ - qStatus = IX_QMGR_Q_OVERFLOW; - } - else - { - /*there are no buffers in the s/w queues, submit directly*/ - qStatus = ixEthAccQmgrTxWrite(portId, qBuffer, priority); - } - } - else - { - /*there are no buffers in the s/w queues, submit directly*/ - qStatus = ixEthAccQmgrTxWrite(portId, qBuffer, priority); - } - } - else - { - qStatus = IX_QMGR_Q_OVERFLOW; - } - } - else - { - TX_INC(portId,txUnexpectedError); - IX_ETH_ACC_FATAL_LOG( - "ixEthAccPortTxFrameSubmit:Error: wrong schedule discipline setup\n", - 0, 0, 0, 0, 0, 0); - return (IX_ETH_ACC_FAIL); - } - - if(qStatus == IX_SUCCESS ) - { - TX_STATS_INC(portId,txQOK); - return IX_ETH_ACC_SUCCESS; - } - else if(qStatus == IX_QMGR_Q_OVERFLOW) - { - TX_STATS_INC(portId,txQDelayed); - /* - * We were unable to write the buffer to the - * appropriate H/W Q, Save it in a s/w Q. - */ - IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_TAIL( - ixEthAccPortData[portId]. - ixEthAccTxData.txQ[priority], - buffer); - - qStatus = ixQMgrNotificationEnable( - IX_ETH_ACC_PORT_TO_TX_Q_ID(portId), - IX_ETH_ACC_PORT_TO_TX_Q_SOURCE(portId)); - - if (qStatus != IX_SUCCESS) - { - if (qStatus == IX_QMGR_WARNING) - { - /* notification is enabled for a queue - * which is already empty (the condition is already met) - * and there will be no more queue event to drain the sw queue - */ - TX_STATS_INC(portId,txLateNotificationEnabled); - - /* pull a buffer from the sw queue */ - if(ixEthAccTxSwQHighestPriorityGet(portId, &highestPriority) - !=IX_ETH_ACC_FAIL) - { - /*there are buffers on the s/w queues, submit from them*/ - ixEthAccTxFromSwQ(portId, highestPriority); - } - } - else - { - TX_INC(portId,txUnexpectedError); - IX_ETH_ACC_FATAL_LOG( - "ixEthAccPortTxFrameSubmit: unexpected Error: %u\n", - qStatus, 0, 0, 0, 0, 0); - } - } - } - else - { - TX_INC(portId,txUnexpectedError); - IX_ETH_ACC_FATAL_LOG( - "ixEthAccPortTxFrameSubmit: unexpected Error: %u\n", - qStatus, 0, 0, 0, 0, 0); - return (IX_ETH_ACC_FAIL); - } - - return (IX_ETH_ACC_SUCCESS); -} - - -/** - * - * @brief replenish: convert a chain of mbufs to the format - * expected by the NPE - * - */ - -IX_ETH_ACC_PUBLIC -IxEthAccStatus ixEthAccPortRxFreeReplenish(IxEthAccPortId portId, - IX_OSAL_MBUF *buffer) -{ - IX_STATUS qStatus = IX_SUCCESS; - UINT32 qBuffer; - - /* - * Check buffer is valid. - */ - -#ifndef NDEBUG - /* check parameter value */ - if (buffer == 0) - { - return (IX_ETH_ACC_FAIL); - } - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - if (!IX_ETH_ACC_IS_PORT_VALID(portId)) - { - return (IX_ETH_ACC_INVALID_PORT); - } - - /* check initialisation is done */ - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_FATAL_LOG(" ixEthAccPortRxFreeReplenish: Unavailable Eth %d: Cannot replenish Rx Free Q.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_PORT_UNINITIALIZED ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - /* check boundaries and constraints */ - if (IX_OSAL_MBUF_MLEN(buffer) < IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN) - { - return (IX_ETH_ACC_FAIL); - } -#endif - - qBuffer = ixEthAccMbufRxQPrepare(buffer); - - /* - * Add The Rx Buffer to the H/W Free buffer Q if possible - */ - qStatus = ixEthAccQmgrLockRxWrite(portId, qBuffer); - - if (qStatus == IX_SUCCESS) - { - RX_STATS_INC(portId,rxFreeRepOK); - /* - * Buffer added to h/w Q. - */ - return (IX_SUCCESS); - } - else if (qStatus == IX_QMGR_Q_OVERFLOW) - { - RX_STATS_INC(portId,rxFreeRepDelayed); - /* - * We were unable to write the buffer to the approprate H/W Q, - * Save it in a s/w Q. - */ - IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_TAIL( - ixEthAccPortData[portId].ixEthAccRxData.freeBufferList, - buffer); - - qStatus = ixQMgrNotificationEnable( - IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(portId), - IX_ETH_ACC_PORT_TO_RX_FREE_Q_SOURCE(portId)); - - if (qStatus != IX_SUCCESS) - { - if (qStatus == IX_QMGR_WARNING) - { - /* notification is enabled for a queue - * which is already empty (the condition is already met) - * and there will be no more queue event to drain the sw queue - * move an entry from the sw queue to the hw queue */ - RX_STATS_INC(portId,rxFreeLateNotificationEnabled); - ixEthAccRxFreeFromSwQ(portId); - } - else - { - RX_INC(portId,rxUnexpectedError); - IX_ETH_ACC_FATAL_LOG( - "ixEthAccRxPortFreeReplenish:Error: %u\n", - qStatus, 0, 0, 0, 0, 0); - } - } - } - else - { - RX_INC(portId,rxUnexpectedError); - IX_ETH_ACC_FATAL_LOG( - "ixEthAccRxPortFreeReplenish:Error: qStatus = %u\n", - (UINT32)qStatus, 0, 0, 0, 0, 0); - return(IX_ETH_ACC_FAIL); - } - return (IX_ETH_ACC_SUCCESS); -} - - -IX_ETH_ACC_PUBLIC -IxEthAccStatus ixEthAccTxSchedulingDisciplineSetPriv(IxEthAccPortId portId, - IxEthAccSchedulerDiscipline - sched) -{ - 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("ixEthAccTxSchedulingDisciplineSet: Unavailable Eth %d: Cannot set Tx Scheduling Discipline.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - if (sched != FIFO_PRIORITY && sched != FIFO_NO_PRIORITY) - { - return (IX_ETH_ACC_INVALID_ARG); - } - - ixEthAccPortData[portId].ixEthAccTxData.schDiscipline = sched; - return (IX_ETH_ACC_SUCCESS); -} - -IX_ETH_ACC_PUBLIC -IxEthAccStatus ixEthAccRxSchedulingDisciplineSetPriv(IxEthAccSchedulerDiscipline - sched) -{ - if (sched != FIFO_PRIORITY && sched != FIFO_NO_PRIORITY) - { - return (IX_ETH_ACC_INVALID_ARG); - } - - ixEthAccDataInfo.schDiscipline = sched; - - return (IX_ETH_ACC_SUCCESS); -} - - -/** - * @fn ixEthRxFrameProcess(IxEthAccPortId portId, IX_OSAL_MBUF *mbufPtr) - * - * @brief process incoming frame : - * - * @param @ref IxQMgrCallback IxQMgrMultiBufferCallback - * - * @return none - * - * @internal - * - */ -IX_ETH_ACC_PRIVATE BOOL -ixEthRxFrameProcess(IxEthAccPortId portId, IX_OSAL_MBUF *mbufPtr) -{ - UINT32 flags; - IxEthDBStatus result; - -#ifndef NDEBUG - /* Prudent to at least check the port is within range */ - if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS) - { - ixEthAccDataStats.unexpectedError++; - IX_ETH_ACC_FATAL_LOG( - "ixEthRxFrameProcess: Illegal port: %u\n", - (UINT32)portId, 0, 0, 0, 0, 0); - return FALSE; - } -#endif - - /* convert fields from mbuf header */ - ixEthAccMbufFromRxQ(mbufPtr); - - /* check about any special processing for this frame */ - flags = IX_ETHACC_NE_FLAGS(mbufPtr); - if ((flags & (IX_ETHACC_NE_FILTERMASK | IX_ETHACC_NE_NEWSRCMASK)) == 0) - { - /* "best case" scenario : nothing special to do for this frame */ - return TRUE; - } - -#ifdef CONFIG_IXP425_COMPONENT_ETHDB - /* if a new source MAC address is detected by the NPE, - * update IxEthDB with the portId and the MAC address. - */ - if ((flags & IX_ETHACC_NE_NEWSRCMASK & ixEthAccNewSrcMask) != 0) - { - result = ixEthDBFilteringDynamicEntryProvision(portId, - (IxEthDBMacAddr *) IX_ETHACC_NE_SOURCEMAC(mbufPtr)); - - if (result != IX_ETH_DB_SUCCESS && result != IX_ETH_DB_FEATURE_UNAVAILABLE) - { - if ((ixEthAccMacState[portId].portDisableState == ACTIVE) && (result != IX_ETH_DB_BUSY)) - { - RX_STATS_INC(portId, rxUnexpectedError); - IX_ETH_ACC_FATAL_LOG("ixEthRxFrameProcess: Failed to add source MAC \ - to the Learning/Filtering database\n", 0, 0, 0, 0, 0, 0); - } - else - { - /* we expect this to fail during PortDisable, as EthDB is disabled for - * that port and will refuse to learn new addresses - */ - } - } - else - { - RX_STATS_INC(portId, rxUnlearnedMacAddress); - } - } -#endif - - /* check if this frame should have been filtered - * by the NPE and take the appropriate action - */ - if (((flags & IX_ETHACC_NE_FILTERMASK) != 0) - && (ixEthAccMacState[portId].portDisableState == ACTIVE)) - { - /* If the mbuf was allocated with a small data size, or the current data pointer is not - * within the allocated data area, then the buffer is non-standard and has to be - * replenished with the minimum size only - */ - if( (IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(mbufPtr) < IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN) - || ((UINT8 *)IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(mbufPtr) > IX_OSAL_MBUF_MDATA(mbufPtr)) - || ((UINT8 *)(IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(mbufPtr) + - IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(mbufPtr)) - < IX_OSAL_MBUF_MDATA(mbufPtr)) ) - { - /* set to minimum length */ - IX_OSAL_MBUF_MLEN(mbufPtr) = IX_OSAL_MBUF_PKT_LEN(mbufPtr) = - IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN; - } - else - { - /* restore original length */ - IX_OSAL_MBUF_MLEN(mbufPtr) = IX_OSAL_MBUF_PKT_LEN(mbufPtr) = - ( IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(mbufPtr) - - (IX_OSAL_MBUF_MDATA(mbufPtr) - (UINT8 *)IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(mbufPtr)) ); - } - - /* replenish from here */ - if (ixEthAccPortRxFreeReplenish(portId, mbufPtr) != IX_ETH_ACC_SUCCESS) - { - IX_ETH_ACC_FATAL_LOG("ixEthRxFrameProcess: Failed to replenish with filtered frame\ - on port %d\n", portId, 0, 0, 0, 0, 0); - } - - RX_STATS_INC(portId, rxFiltered); - - /* indicate that frame should not be subjected to further processing */ - return FALSE; - } - - return TRUE; -} - - -/** - * @fn ixEthRxFrameQMCallback - * - * @brief receive callback for Frame receive Q from NPE - * - * Frames are passed one-at-a-time to the user - * - * @param @ref IxQMgrCallback - * - * @return none - * - * @internal - * - * Design note : while processing the entry X, entry X+1 is preloaded - * into memory to reduce the number of stall cycles - * - */ -void ixEthRxFrameQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId) -{ - IX_OSAL_MBUF *mbufPtr; - IX_OSAL_MBUF *nextMbufPtr; - UINT32 qEntry; - UINT32 nextQEntry; - UINT32 *qEntryPtr; - UINT32 portId; - UINT32 destPortId; - UINT32 npeId; - UINT32 rxQReadStatus; - - /* - * Design note : entries are read in a buffer, This buffer contains - * an extra zeroed entry so the loop will - * always terminate on a null entry, whatever the result of Burst read is. - */ - UINT32 rxQEntry[IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK + 1]; - - /* - * Indication of the number of times the callback is used. - */ - IX_ETH_ACC_STATS_INC(ixEthAccDataStats.rxCallbackCounter); - - do - { - /* - * Indication of the number of times the queue is drained - */ - IX_ETH_ACC_STATS_INC(ixEthAccDataStats.rxCallbackBurstRead); - - /* ensure the last entry of the array contains a zeroed value */ - qEntryPtr = rxQEntry; - qEntryPtr[IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK] = 0; - - rxQReadStatus = ixQMgrQBurstRead(qId, - IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK, - qEntryPtr); - -#ifndef NDEBUG - if ((rxQReadStatus != IX_QMGR_Q_UNDERFLOW) - && (rxQReadStatus != IX_SUCCESS)) - { - ixEthAccDataStats.unexpectedError++; - /*major error*/ - IX_ETH_ACC_FATAL_LOG( - "ixEthRxFrameQMCallback:Error: %u\n", - (UINT32)rxQReadStatus, 0, 0, 0, 0, 0); - return; - } -#endif - - /* convert and preload the next entry - * (the conversion function takes care about null pointers which - * are used to mark the end of the loop) - */ - nextQEntry = *qEntryPtr; - nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry, - IX_ETHNPE_QM_Q_RXENET_ADDR_MASK); - - while(nextQEntry != 0) - { - /* get the next entry */ - qEntry = nextQEntry; - mbufPtr = nextMbufPtr; - -#ifndef NDEBUG - if (mbufPtr == NULL) - { - ixEthAccDataStats.unexpectedError++; - IX_ETH_ACC_FATAL_LOG( - "ixEthRxFrameQMCallback: Null Mbuf Ptr\n", - 0, 0, 0, 0, 0, 0); - return; - } -#endif - - /* convert the next entry - * (the conversion function takes care about null pointers which - * are used to mark the end of the loop) - */ - nextQEntry = *(++qEntryPtr); - nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry, - IX_ETHNPE_QM_Q_RXENET_ADDR_MASK); - - /* - * Get Port and Npe ID from message. - */ - npeId = ((IX_ETHNPE_QM_Q_RXENET_NPEID_MASK & - qEntry) >> IX_ETHNPE_QM_Q_FIELD_NPEID_R); - portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId); - - /* process frame, check the return code and skip the remaining of - * the loop if the frame is to be filtered out - */ - if (ixEthRxFrameProcess(portId, mbufPtr)) - { - /* destination portId for this packet */ - destPortId = IX_ETHACC_NE_DESTPORTID(mbufPtr); - - if (destPortId != IX_ETH_DB_UNKNOWN_PORT) - { - destPortId = IX_ETH_DB_NPE_LOGICAL_ID_TO_PORT_ID(destPortId); - } - - /* test if QoS is enabled in ethAcc - */ - if (ixEthAccDataInfo.schDiscipline == FIFO_PRIORITY) - { - /* check if there is a higher priority queue - * which may require processing and then process it. - */ - if (ixEthAccDataInfo.higherPriorityQueue[qId] < IX_QMGR_MAX_NUM_QUEUES) - { - ixEthRxFrameQMCallback(ixEthAccDataInfo.higherPriorityQueue[qId], - callbackId); - } - } - - /* - * increment priority stats - */ - RX_STATS_INC(portId,rxPriority[IX_ETHACC_NE_QOS(mbufPtr)]); - - /* - * increment callback count stats - */ - RX_STATS_INC(portId,rxFrameClientCallback); - - /* - * Call user level callback. - */ - ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn( - ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag, - mbufPtr, - destPortId); - } - } - } while (rxQReadStatus == IX_SUCCESS); -} - -/** - * @fn ixEthRxMultiBufferQMCallback - * - * @brief receive callback for Frame receive Q from NPE - * - * Frames are passed as an array to the user - * - * @param @ref IxQMgrCallback - * - * @return none - * - * @internal - * - * Design note : while processing the entry X, entry X+1 is preloaded - * into memory to reduce the number of stall cycles - * - */ -void ixEthRxMultiBufferQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId) -{ - IX_OSAL_MBUF *mbufPtr; - IX_OSAL_MBUF *nextMbufPtr; - UINT32 qEntry; - UINT32 nextQEntry; - UINT32 *qEntryPtr; - UINT32 portId; - UINT32 npeId; - UINT32 rxQReadStatus; - /* - * Design note : entries are read in a static buffer, This buffer contains - * an extra zeroed entry so the loop will - * always terminate on a null entry, whatever the result of Burst read is. - */ - static UINT32 rxQEntry[IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK + 1]; - static IX_OSAL_MBUF *rxMbufPortArray[IX_ETH_ACC_NUMBER_OF_PORTS][IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK + 1]; - IX_OSAL_MBUF **rxMbufPtr[IX_ETH_ACC_NUMBER_OF_PORTS]; - - for (portId = 0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) - { - rxMbufPtr[portId] = rxMbufPortArray[portId]; - } - - /* - * Indication of the number of times the callback is used. - */ - IX_ETH_ACC_STATS_INC(ixEthAccDataStats.rxCallbackCounter); - - do - { - /* - * Indication of the number of times the queue is drained - */ - IX_ETH_ACC_STATS_INC(ixEthAccDataStats.rxCallbackBurstRead); - - /* ensure the last entry of the array contains a zeroed value */ - qEntryPtr = rxQEntry; - qEntryPtr[IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK] = 0; - - rxQReadStatus = ixQMgrQBurstRead(qId, - IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK, - qEntryPtr); - -#ifndef NDEBUG - if ((rxQReadStatus != IX_QMGR_Q_UNDERFLOW) - && (rxQReadStatus != IX_SUCCESS)) - { - ixEthAccDataStats.unexpectedError++; - /*major error*/ - IX_ETH_ACC_FATAL_LOG( - "ixEthRxFrameMultiBufferQMCallback:Error: %u\n", - (UINT32)rxQReadStatus, 0, 0, 0, 0, 0); - return; - } -#endif - - /* convert and preload the next entry - * (the conversion function takes care about null pointers which - * are used to mark the end of the loop) - */ - nextQEntry = *qEntryPtr; - nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry, - IX_ETHNPE_QM_Q_RXENET_ADDR_MASK); - - while(nextQEntry != 0) - { - /* get the next entry */ - qEntry = nextQEntry; - mbufPtr = nextMbufPtr; - -#ifndef NDEBUG - if (mbufPtr == NULL) - { - ixEthAccDataStats.unexpectedError++; - IX_ETH_ACC_FATAL_LOG( - "ixEthRxFrameMultiBufferQMCallback:Error: Null Mbuf Ptr\n", - 0, 0, 0, 0, 0, 0); - return; - } -#endif - - /* convert the next entry - * (the conversion function takes care about null pointers which - * are used to mark the end of the loop) - */ - nextQEntry = *(++qEntryPtr); - nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry, - IX_ETHNPE_QM_Q_RXENET_ADDR_MASK); - - /* - * Get Port and Npe ID from message. - */ - npeId = ((IX_ETHNPE_QM_Q_RXENET_NPEID_MASK & - qEntry) >> - IX_ETHNPE_QM_Q_FIELD_NPEID_R); - portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId); - - /* skip the remaining of the loop if the frame is - * to be filtered out - */ - if (ixEthRxFrameProcess(portId, mbufPtr)) - { - /* store a mbuf pointer in an array */ - *rxMbufPtr[portId]++ = mbufPtr; - - /* - * increment priority stats - */ - RX_STATS_INC(portId,rxPriority[IX_ETHACC_NE_QOS(mbufPtr)]); - } - - /* test for QoS enabled in ethAcc */ - if (ixEthAccDataInfo.schDiscipline == FIFO_PRIORITY) - { - /* check if there is a higher priority queue - * which may require processing and then process it. - */ - if (ixEthAccDataInfo.higherPriorityQueue[qId] < IX_QMGR_MAX_NUM_QUEUES) - { - ixEthRxMultiBufferQMCallback(ixEthAccDataInfo.higherPriorityQueue[qId], - callbackId); - } - } - } - - /* check if any of the the arrays contains any entry */ - for (portId = 0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) - { - if (rxMbufPtr[portId] != rxMbufPortArray[portId]) - { - /* add a last NULL pointer at the end of the - * array of mbuf pointers - */ - *rxMbufPtr[portId] = NULL; - - /* - * increment callback count stats - */ - RX_STATS_INC(portId,rxFrameClientCallback); - - /* - * Call user level callback with an array of - * buffers (NULL terminated) - */ - ixEthAccPortData[portId].ixEthAccRxData. - rxMultiBufferCallbackFn( - ixEthAccPortData[portId].ixEthAccRxData. - rxMultiBufferCallbackTag, - rxMbufPortArray[portId]); - - /* reset the buffer pointer to the beginning of - * the array - */ - rxMbufPtr[portId] = rxMbufPortArray[portId]; - } - } - - } while (rxQReadStatus == IX_SUCCESS); -} - - -/** - * @brief rxFree low event handler - * - */ -void ixEthRxFreeQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId) -{ - IxEthAccPortId portId = (IxEthAccPortId) callbackId; - int lockVal; - UINT32 maxQWritesToPerform = IX_ETH_ACC_MAX_RX_FREE_BUFFERS_LOAD; - IX_STATUS qStatus = IX_SUCCESS; - - /* - * We have reached a low threshold on one of the Rx Free Qs - */ - - /*note that due to the fact that we are working off an Empty threshold, this callback - need only write a single entry to the Rx Free queue in order to re-arm the notification - */ - - RX_STATS_INC(portId,rxFreeLowCallback); - - /* - * Get buffers from approprite S/W Rx freeBufferList Q. - */ - -#ifndef NDEBUG - if (!IX_ETH_ACC_IS_PORT_VALID(portId)) - { - ixEthAccDataStats.unexpectedError++; - IX_ETH_ACC_FATAL_LOG( - "ixEthRxFreeQMCallback:Error: Invalid Port 0x%08X\n", - portId, 0, 0, 0, 0, 0); - return; - } -#endif - IX_ETH_ACC_DATA_PLANE_LOCK(lockVal); - if (IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(ixEthAccPortData[portId]. - ixEthAccRxData.freeBufferList)) - { - /* - * Turn off Q callback notification for Q in Question. - */ - qStatus = ixQMgrNotificationDisable( - IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(portId)); - - - IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); - - if (qStatus != IX_SUCCESS) - { - RX_INC(portId,rxUnexpectedError); - IX_ETH_ACC_FATAL_LOG( - "ixEthRxFreeQMCallback:Error: unexpected QM status 0x%08X\n", - qStatus, 0, 0, 0, 0, 0); - return; - } - } - else - { - IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); - /* - * Load the H/W Q with buffers from the s/w Q. - */ - - do - { - /* - * Consume Q entries. - Note Q contains Physical addresss, - * and have already been flushed to memory, - * And endianess converted if required. - */ - if (ixEthAccRxFreeFromSwQ(portId) != IX_SUCCESS) - { - /* - * No more entries in s/w Q. - * Turn off Q callback indication - */ - - IX_ETH_ACC_DATA_PLANE_LOCK(lockVal); - if (IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(ixEthAccPortData[portId]. - ixEthAccRxData.freeBufferList)) - { - qStatus = ixQMgrNotificationDisable( - IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(portId)); - } - IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); - break; - } - } - while (--maxQWritesToPerform); - } -} -/** - * @fn Tx queue low event handler - * - */ -void -ixEthTxFrameQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId) -{ - IxEthAccPortId portId = (IxEthAccPortId) callbackId; - int lockVal; - UINT32 maxQWritesToPerform = IX_ETH_ACC_MAX_TX_FRAME_TX_CONSUME_PER_CALLBACK; - IX_STATUS qStatus = IX_SUCCESS; - IxEthAccTxPriority highestPriority; - - - /* - * We have reached a low threshold on the Tx Q, and are being asked to - * supply a buffer for transmission from our S/W TX queues - */ - TX_STATS_INC(portId,txLowThreshCallback); - - /* - * Get buffers from approprite Q. - */ - -#ifndef NDEBUG - if (!IX_ETH_ACC_IS_PORT_VALID(portId)) - { - ixEthAccDataStats.unexpectedError++; - IX_ETH_ACC_FATAL_LOG( - "ixEthTxFrameQMCallback:Error: Invalid Port 0x%08X\n", - portId, 0, 0, 0, 0, 0); - return; - } -#endif - - do - { - /* - * Consume Q entries. - Note Q contains Physical addresss, - * and have already been flushed to memory, - * and endianess already sone if required. - */ - - IX_ETH_ACC_DATA_PLANE_LOCK(lockVal); - - if(ixEthAccTxSwQHighestPriorityGet(portId, &highestPriority) == - IX_ETH_ACC_FAIL) - { - /* - * No more entries in s/w Q. - * Turn off Q callback indication - */ - qStatus = ixQMgrNotificationDisable( - IX_ETH_ACC_PORT_TO_TX_Q_ID(portId)); - - IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); - - if (qStatus != IX_SUCCESS) - { - ixEthAccDataStats.unexpectedError++; - IX_ETH_ACC_FATAL_LOG( - "ixEthTxFrameQMCallback:Error: unexpected QM status 0x%08X\n", - qStatus, 0, 0, 0, 0, 0); - } - - return; - } - else - { - IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); - if (ixEthAccTxFromSwQ(portId,highestPriority)!=IX_SUCCESS) - { - /* nothing left in the sw queue or the hw queues are - * full. There is no point to continue to drain the - * sw queues - */ - return; - } - } - } - while (--maxQWritesToPerform); -} - -/** - * @brief TxDone event handler - * - * Design note : while processing the entry X, entry X+1 is preloaded - * into memory to reduce the number of stall cycles - * - */ - -void -ixEthTxFrameDoneQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId) -{ - IX_OSAL_MBUF *mbufPtr; - UINT32 qEntry; - UINT32 *qEntryPtr; - UINT32 txDoneQReadStatus; - UINT32 portId; - UINT32 npeId; - - /* - * Design note : entries are read in a static buffer, This buffer contains - * an extra entyry (which is zeroed by the compiler), so the loop will - * always terminate on a null entry, whatever the result of Burst read is. - */ - static UINT32 txDoneQEntry[IX_ETH_ACC_MAX_TX_FRAME_DONE_CONSUME_PER_CALLBACK + 1]; - - /* - * Indication that Tx frames have been transmitted from the NPE. - */ - - IX_ETH_ACC_STATS_INC(ixEthAccDataStats.txDoneCallbackCounter); - - do{ - qEntryPtr = txDoneQEntry; - txDoneQReadStatus = ixQMgrQBurstRead(IX_ETH_ACC_TX_FRAME_DONE_ETH_Q, - IX_ETH_ACC_MAX_TX_FRAME_DONE_CONSUME_PER_CALLBACK, - qEntryPtr); - -#ifndef NDEBUG - if (txDoneQReadStatus != IX_QMGR_Q_UNDERFLOW - && (txDoneQReadStatus != IX_SUCCESS)) - { - /*major error*/ - ixEthAccDataStats.unexpectedError++; - IX_ETH_ACC_FATAL_LOG( - "ixEthTxFrameDoneQMCallback:Error: %u\n", - (UINT32)txDoneQReadStatus, 0, 0, 0, 0, 0); - return; - } -#endif - - qEntry = *qEntryPtr; - - while(qEntry != 0) - { - mbufPtr = ixEthAccEntryFromQConvert(qEntry, - IX_ETHNPE_QM_Q_TXENET_ADDR_MASK); - -#ifndef NDEBUG - if (mbufPtr == NULL) - { - ixEthAccDataStats.unexpectedError++; - IX_ETH_ACC_FATAL_LOG( - "ixEthTxFrameDoneQMCallback:Error: Null Mbuf Ptr\n", - 0, 0, 0, 0, 0, 0); - return; - } -#endif - - /* endianness conversions and stats updates */ - ixEthAccMbufFromTxQ(mbufPtr); - - /* - * Get NPE id from message, then convert to portId. - */ - npeId = ((IX_ETHNPE_QM_Q_TXENETDONE_NPEID_MASK & - qEntry) >> - IX_ETHNPE_QM_Q_FIELD_NPEID_R); - portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId); - -#ifndef NDEBUG - /* Prudent to at least check the port is within range */ - if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS) - { - ixEthAccDataStats.unexpectedError++; - IX_ETH_ACC_FATAL_LOG( - "ixEthTxFrameDoneQMCallback: Illegal port: %u\n", - (UINT32)portId, 0, 0, 0, 0, 0); - return; - } -#endif - - TX_STATS_INC(portId,txDoneClientCallback); - - /* - * Call user level callback. - */ - ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn( - ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag, - mbufPtr); - - /* move to next queue entry */ - qEntry = *(++qEntryPtr); - - } - } while( txDoneQReadStatus == IX_SUCCESS ); -} - -IX_ETH_ACC_PUBLIC -void ixEthAccDataPlaneShow(void) -{ - UINT32 numTx0Entries; - UINT32 numTx1Entries; - UINT32 numTxDoneEntries; - UINT32 numRxEntries; - UINT32 numRxFree0Entries; - UINT32 numRxFree1Entries; - UINT32 portId; -#ifdef __ixp46X - UINT32 numTx2Entries; - UINT32 numRxFree2Entries; -#endif -#ifndef NDEBUG - UINT32 priority; - UINT32 numBuffersInRx=0; - UINT32 numBuffersInTx=0; - UINT32 numBuffersInSwQ=0; - UINT32 totalBuffers=0; - UINT32 rxFreeCallbackCounter = 0; - UINT32 txCallbackCounter = 0; -#endif - UINT32 key; - - /* snapshot of stats */ - IxEthAccTxDataStats tx[IX_ETH_ACC_NUMBER_OF_PORTS]; - IxEthAccRxDataStats rx[IX_ETH_ACC_NUMBER_OF_PORTS]; - IxEthAccDataPlaneStats stats; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return; - } - - /* get a reliable snapshot */ - key = ixOsalIrqLock(); - - numTx0Entries = 0; - ixQMgrQNumEntriesGet(IX_ETH_ACC_TX_FRAME_ENET0_Q, &numTx0Entries); - numTx1Entries = 0; - ixQMgrQNumEntriesGet(IX_ETH_ACC_TX_FRAME_ENET1_Q, &numTx1Entries); - numTxDoneEntries = 0; - ixQMgrQNumEntriesGet( IX_ETH_ACC_TX_FRAME_DONE_ETH_Q, &numTxDoneEntries); - numRxEntries = 0; - ixEthAccQMgrRxQEntryGet(&numRxEntries); - numRxFree0Entries = 0; - ixQMgrQNumEntriesGet(IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q, &numRxFree0Entries); - numRxFree1Entries = 0; - ixQMgrQNumEntriesGet(IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q, &numRxFree1Entries); - -#ifdef __ixp46X - numTx2Entries = 0; - ixQMgrQNumEntriesGet(IX_ETH_ACC_TX_FRAME_ENET2_Q, &numTx2Entries); - numRxFree2Entries = 0; - ixQMgrQNumEntriesGet(IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q, &numRxFree2Entries); -#endif - - for(portId=IX_ETH_PORT_1; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) - { - memcpy(&tx[portId], - &ixEthAccPortData[portId].ixEthAccTxData.stats, - sizeof(tx[portId])); - memcpy(&rx[portId], - &ixEthAccPortData[portId].ixEthAccRxData.stats, - sizeof(rx[portId])); - } - memcpy(&stats, &ixEthAccDataStats, sizeof(stats)); - - ixOsalIrqUnlock(key); - -#ifdef NDEBUG - printf("Detailed statistics collection not supported in this load\n"); -#endif - - /* print snapshot */ - for(portId=0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; 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 ((IX_ETH_PORT_1 == portId) && - (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) == - IX_FEATURE_CTRL_COMPONENT_DISABLED)) - { - continue ; - } - if ((IX_ETH_PORT_2 == portId) && - (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) == - IX_FEATURE_CTRL_COMPONENT_DISABLED)) - { - continue ; - } - if ((IX_ETH_PORT_3 == portId) && - (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA_ETH) == - IX_FEATURE_CTRL_COMPONENT_DISABLED)) - { - continue ; - } - } - - printf("PORT %u --------------------------------\n", - portId); -#ifndef NDEBUG - printf("Tx Done Frames : %u\n", - tx[portId].txDoneClientCallback + - tx[portId].txDoneSwQDuringDisable + - tx[portId].txDoneDuringDisable); - printf("Tx Frames : %u\n", - tx[portId].txQOK + tx[portId].txQDelayed); - printf("Tx H/W Q Added OK : %u\n", - tx[portId].txQOK); - printf("Tx H/W Q Delayed : %u\n", - tx[portId].txQDelayed); - printf("Tx From S/W Q Added OK : %u\n", - tx[portId].txFromSwQOK); - printf("Tx From S/W Q Delayed : %u\n", - tx[portId].txFromSwQDelayed); - printf("Tx Overflow : %u\n", - tx[portId].txOverflow); - printf("Tx Mutual Lock : %u\n", - tx[portId].txLock); - printf("Tx Late Ntf Enabled : %u\n", - tx[portId].txLateNotificationEnabled); - printf("Tx Low Thresh CB : %u\n", - tx[portId].txLowThreshCallback); - printf("Tx Done from H/W Q (Disable) : %u\n", - tx[portId].txDoneDuringDisable); - printf("Tx Done from S/W Q (Disable) : %u\n", - tx[portId].txDoneSwQDuringDisable); - for (priority = IX_ETH_ACC_TX_PRIORITY_0; - priority <= IX_ETH_ACC_TX_PRIORITY_7; - priority++) - { - if (tx[portId].txPriority[priority]) - { - printf("Tx Priority %u : %u\n", - priority, - tx[portId].txPriority[priority]); - } - } -#endif - printf("Tx unexpected errors : %u (should be 0)\n", - tx[portId].txUnexpectedError); - -#ifndef NDEBUG - printf("Rx Frames : %u\n", - rx[portId].rxFrameClientCallback + - rx[portId].rxSwQDuringDisable+ - rx[portId].rxDuringDisable); - printf("Rx Free Replenish : %u\n", - rx[portId].rxFreeRepOK + rx[portId].rxFreeRepDelayed); - printf("Rx Free H/W Q Added OK : %u\n", - rx[portId].rxFreeRepOK); - printf("Rx Free H/W Q Delayed : %u\n", - rx[portId].rxFreeRepDelayed); - printf("Rx Free From S/W Q Added OK : %u\n", - rx[portId].rxFreeRepFromSwQOK); - printf("Rx Free From S/W Q Delayed : %u\n", - rx[portId].rxFreeRepFromSwQDelayed); - printf("Rx Free Overflow : %u\n", - rx[portId].rxFreeOverflow); - printf("Rx Free Mutual Lock : %u\n", - rx[portId].rxFreeLock); - printf("Rx Free Late Ntf Enabled : %u\n", - rx[portId].rxFreeLateNotificationEnabled); - printf("Rx Free Low CB : %u\n", - rx[portId].rxFreeLowCallback); - printf("Rx From H/W Q (Disable) : %u\n", - rx[portId].rxDuringDisable); - printf("Rx From S/W Q (Disable) : %u\n", - rx[portId].rxSwQDuringDisable); - printf("Rx unlearned Mac Address : %u\n", - rx[portId].rxUnlearnedMacAddress); - printf("Rx Filtered (Rx => RxFree) : %u\n", - rx[portId].rxFiltered); - - for (priority = IX_ETH_ACC_TX_PRIORITY_0; - priority <= IX_ETH_ACC_TX_PRIORITY_7; - priority++) - { - if (rx[portId].rxPriority[priority]) - { - printf("Rx Priority %u : %u\n", - priority, - rx[portId].rxPriority[priority]); - } - } -#endif - printf("Rx unexpected errors : %u (should be 0)\n", - rx[portId].rxUnexpectedError); - -#ifndef NDEBUG - numBuffersInTx = tx[portId].txQOK + - tx[portId].txQDelayed - - tx[portId].txDoneClientCallback - - tx[portId].txDoneSwQDuringDisable - - tx[portId].txDoneDuringDisable; - - printf("# Tx Buffers currently for transmission : %u\n", - numBuffersInTx); - - numBuffersInRx = rx[portId].rxFreeRepOK + - rx[portId].rxFreeRepDelayed - - rx[portId].rxFrameClientCallback - - rx[portId].rxSwQDuringDisable - - rx[portId].rxDuringDisable; - - printf("# Rx Buffers currently for reception : %u\n", - numBuffersInRx); - - totalBuffers += numBuffersInRx + numBuffersInTx; -#endif - } - - printf("---------------------------------------\n"); - -#ifndef NDEBUG - printf("\n"); - printf("Mbufs :\n"); - printf("Tx Unchained mbufs : %u\n", - stats.unchainedTxMBufs); - printf("Tx Chained bufs : %u\n", - stats.chainedTxMBufs); - printf("TxDone Unchained mbufs : %u\n", - stats.unchainedTxDoneMBufs); - printf("TxDone Chained bufs : %u\n", - stats.chainedTxDoneMBufs); - printf("RxFree Unchained mbufs : %u\n", - stats.unchainedRxFreeMBufs); - printf("RxFree Chained bufs : %u\n", - stats.chainedRxFreeMBufs); - printf("Rx Unchained mbufs : %u\n", - stats.unchainedRxMBufs); - printf("Rx Chained bufs : %u\n", - stats.chainedRxMBufs); - - printf("\n"); - printf("Software queue usage :\n"); - printf("Buffers added to S/W Q : %u\n", - stats.addToSwQ); - printf("Buffers removed from S/W Q : %u\n", - stats.removeFromSwQ); - - printf("\n"); - printf("Hardware queues callbacks :\n"); - - for(portId=0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) - { - rxFreeCallbackCounter += rx[portId].rxFreeLowCallback; - txCallbackCounter += tx[portId].txLowThreshCallback; - } - printf("Tx Done QM Callback invoked : %u\n", - stats.txDoneCallbackCounter); - printf("Tx QM Callback invoked : %u\n", - txCallbackCounter); - printf("Rx QM Callback invoked : %u\n", - stats.rxCallbackCounter); - printf("Rx QM Callback burst read : %u\n", - stats.rxCallbackBurstRead); - printf("Rx Free QM Callback invoked : %u\n", - rxFreeCallbackCounter); -#endif - printf("Unexpected errors in CB : %u (should be 0)\n", - stats.unexpectedError); - printf("\n"); - - printf("Hardware queues levels :\n"); - printf("Transmit Port 1 Q : %u \n",numTx0Entries); - printf("Transmit Port 2 Q : %u \n",numTx1Entries); -#ifdef __ixp46X - printf("Transmit Port 3 Q : %u \n",numTx2Entries); -#endif - printf("Transmit Done Q : %u \n",numTxDoneEntries); - printf("Receive Q : %u \n",numRxEntries); - printf("Receive Free Port 1 Q : %u \n",numRxFree0Entries); - printf("Receive Free Port 2 Q : %u \n",numRxFree1Entries); -#ifdef __ixp46X - printf("Receive Free Port 3 Q : %u \n",numRxFree2Entries); -#endif - -#ifndef NDEBUG - printf("\n"); - printf("# Total Buffers accounted for : %u\n", - totalBuffers); - - numBuffersInSwQ = ixEthAccDataStats.addToSwQ - - ixEthAccDataStats.removeFromSwQ; - - printf(" Buffers in S/W Qs : %u\n", - numBuffersInSwQ); - printf(" Buffers in H/W Qs or NPEs : %u\n", - totalBuffers - numBuffersInSwQ); -#endif - - printf("Rx QoS Discipline : %s\n", - (ixEthAccDataInfo.schDiscipline == - FIFO_PRIORITY ) ? "Enabled" : "Disabled"); - - for(portId=0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) - { - printf("Tx QoS Discipline port %u : %s\n", - portId, - (ixEthAccPortData[portId].ixEthAccTxData.schDiscipline == - FIFO_PRIORITY ) ? "Enabled" : "Disabled"); - } - printf("\n"); -} - - - - - diff --git a/cpu/ixp/npe/IxEthAccMac.c b/cpu/ixp/npe/IxEthAccMac.c deleted file mode 100644 index 369ee91d94..0000000000 --- a/cpu/ixp/npe/IxEthAccMac.c +++ /dev/null @@ -1,2641 +0,0 @@ -/** - * @file IxEthAccMac.c - * - * @author Intel Corporation - * @date - * - * @brief MAC control functions - * - * Design Notes: - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#include "IxOsal.h" -#include "IxNpeMh.h" -#ifdef CONFIG_IXP425_COMPONENT_ETHDB -#include "IxEthDB.h" -#endif -#include "IxEthDBPortDefs.h" -#include "IxEthNpe.h" -#include "IxEthAcc.h" -#include "IxEthAccDataPlane_p.h" -#include "IxEthAcc_p.h" -#include "IxEthAccMac_p.h" - -/* Maximum number of retries during ixEthAccPortDisable, which - * is approximately 10 seconds -*/ -#define IX_ETH_ACC_MAX_RETRY 500 - -/* Maximum number of retries during ixEthAccPortDisable when expecting - * timeout - */ -#define IX_ETH_ACC_MAX_RETRY_TIMEOUT 5 - -#define IX_ETH_ACC_VALIDATE_PORT_ID(portId) \ - do \ - { \ - if(!IX_ETH_ACC_IS_PORT_VALID(portId)) \ - { \ - return IX_ETH_ACC_INVALID_PORT; \ - } \ - } while(0) - -PUBLIC IxEthAccMacState ixEthAccMacState[IX_ETH_ACC_NUMBER_OF_PORTS]; - -PRIVATE UINT32 ixEthAccMacBase[IX_ETH_ACC_NUMBER_OF_PORTS]; - -/*Forward function declarations*/ -PRIVATE void -ixEthAccPortDisableRx (IxEthAccPortId portId, - IX_OSAL_MBUF * mBufPtr, - BOOL useMultiBufferCallback); - -PRIVATE void -ixEthAccPortDisableRxAndReplenish (IxEthAccPortId portId, - IX_OSAL_MBUF * mBufPtr, - BOOL useMultiBufferCallback); - -PRIVATE void -ixEthAccPortDisableTxDone (UINT32 cbTag, - IX_OSAL_MBUF *mbuf); - -PRIVATE void -ixEthAccPortDisableTxDoneAndSubmit (UINT32 cbTag, - IX_OSAL_MBUF *mbuf); - -PRIVATE void -ixEthAccPortDisableRxCallback (UINT32 cbTag, - IX_OSAL_MBUF * mBufPtr, - UINT32 learnedPortId); - -PRIVATE void -ixEthAccPortDisableMultiBufferRxCallback (UINT32 cbTag, - IX_OSAL_MBUF **mBufPtr); - -PRIVATE IxEthAccStatus -ixEthAccPortDisableTryTransmit(UINT32 portId); - -PRIVATE IxEthAccStatus -ixEthAccPortDisableTryReplenish(UINT32 portId); - -PRIVATE IxEthAccStatus -ixEthAccPortMulticastMacAddressGet (IxEthAccPortId portId, - IxEthAccMacAddr *macAddr); - -PRIVATE IxEthAccStatus -ixEthAccPortMulticastMacFilterGet (IxEthAccPortId portId, - IxEthAccMacAddr *macAddr); - -PRIVATE void -ixEthAccMacNpeStatsMessageCallback (IxNpeMhNpeId npeId, - IxNpeMhMessage msg); - -PRIVATE void -ixEthAccMacNpeStatsResetMessageCallback (IxNpeMhNpeId npeId, - IxNpeMhMessage msg); - -PRIVATE void -ixEthAccNpeLoopbackMessageCallback (IxNpeMhNpeId npeId, - IxNpeMhMessage msg); - -PRIVATE void -ixEthAccMulticastAddressSet(IxEthAccPortId portId); - -PRIVATE BOOL -ixEthAccMacEqual(IxEthAccMacAddr *macAddr1, - IxEthAccMacAddr *macAddr2); - -PRIVATE void -ixEthAccMacPrint(IxEthAccMacAddr *m); - -PRIVATE void -ixEthAccMacStateUpdate(IxEthAccPortId portId); - -IxEthAccStatus -ixEthAccMacMemInit(void) -{ - ixEthAccMacBase[IX_ETH_PORT_1] = - (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_0_BASE, - IX_OSAL_IXP400_ETHA_MAP_SIZE); - ixEthAccMacBase[IX_ETH_PORT_2] = - (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_1_BASE, - IX_OSAL_IXP400_ETHB_MAP_SIZE); -#ifdef __ixp46X - ixEthAccMacBase[IX_ETH_PORT_3] = - (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_2_BASE, - IX_OSAL_IXP400_ETH_NPEA_MAP_SIZE); - if (ixEthAccMacBase[IX_ETH_PORT_3] == 0) - { - ixOsalLog(IX_OSAL_LOG_LVL_FATAL, - IX_OSAL_LOG_DEV_STDOUT, - "EthAcc: Could not map MAC I/O memory\n", - 0, 0, 0, 0, 0 ,0); - - return IX_ETH_ACC_FAIL; - } -#endif - - if (ixEthAccMacBase[IX_ETH_PORT_1] == 0 - || ixEthAccMacBase[IX_ETH_PORT_2] == 0) - { - ixOsalLog(IX_OSAL_LOG_LVL_FATAL, - IX_OSAL_LOG_DEV_STDOUT, - "EthAcc: Could not map MAC I/O memory\n", - 0, 0, 0, 0, 0 ,0); - - return IX_ETH_ACC_FAIL; - } - - return IX_ETH_ACC_SUCCESS; -} - -void -ixEthAccMacUnload(void) -{ - IX_OSAL_MEM_UNMAP(ixEthAccMacBase[IX_ETH_PORT_1]); - IX_OSAL_MEM_UNMAP(ixEthAccMacBase[IX_ETH_PORT_2]); -#ifdef __ixp46X - IX_OSAL_MEM_UNMAP(ixEthAccMacBase[IX_ETH_PORT_3]); - ixEthAccMacBase[IX_ETH_PORT_3] = 0; -#endif - ixEthAccMacBase[IX_ETH_PORT_2] = 0; - ixEthAccMacBase[IX_ETH_PORT_1] = 0; -} - -IxEthAccStatus -ixEthAccPortEnablePriv(IxEthAccPortId portId) -{ - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable port.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - printf("EthAcc: (Mac) cannot enable port %d, port not initialized\n", portId); - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - if (ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn == NULL) - { - /* TxDone callback not registered */ - printf("EthAcc: (Mac) cannot enable port %d, TxDone callback not registered\n", portId); - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - if ((ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn == NULL) - && (ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn == NULL)) - { - /* Receive callback not registered */ - printf("EthAcc: (Mac) cannot enable port %d, Rx callback not registered\n", portId); - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - if(!ixEthAccMacState[portId].initDone) - { - printf("EthAcc: (Mac) cannot enable port %d, MAC address not set\n", portId); - return (IX_ETH_ACC_MAC_UNINITIALIZED); - } - - /* if the state is being set to what it is already at, do nothing*/ - if (ixEthAccMacState[portId].enabled) - { - return IX_ETH_ACC_SUCCESS; - } - -#ifdef CONFIG_IXP425_COMPONENT_ETHDB - /* enable ethernet database for this port */ - if (ixEthDBPortEnable(portId) != IX_ETH_DB_SUCCESS) - { - printf("EthAcc: (Mac) cannot enable port %d, EthDB failure\n", portId); - return IX_ETH_ACC_FAIL; - } -#endif - - /* set the MAC core registers */ - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_TX_CNTRL2, - IX_ETH_ACC_TX_CNTRL2_RETRIES_MASK); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RANDOM_SEED, - IX_ETH_ACC_RANDOM_SEED_DEFAULT); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_THRESH_P_EMPTY, - IX_ETH_ACC_MAC_THRESH_P_EMPTY_DEFAULT); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_THRESH_P_FULL, - IX_ETH_ACC_MAC_THRESH_P_FULL_DEFAULT); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_TX_DEFER, - IX_ETH_ACC_MAC_TX_DEFER_DEFAULT); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_TX_TWO_DEFER_1, - IX_ETH_ACC_MAC_TX_TWO_DEFER_1_DEFAULT); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_TX_TWO_DEFER_2, - IX_ETH_ACC_MAC_TX_TWO_DEFER_2_DEFAULT); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_SLOT_TIME, - IX_ETH_ACC_MAC_SLOT_TIME_DEFAULT); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_INT_CLK_THRESH, - IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_BUF_SIZE_TX, - IX_ETH_ACC_MAC_BUF_SIZE_TX_DEFAULT); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_TX_CNTRL1, - IX_ETH_ACC_TX_CNTRL1_DEFAULT); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - IX_ETH_ACC_RX_CNTRL1_DEFAULT); - - /* set the global state */ - ixEthAccMacState[portId].portDisableState = ACTIVE; - ixEthAccMacState[portId].enabled = TRUE; - - /* rewrite the setup (including mac filtering) depending - * on current options - */ - ixEthAccMacStateUpdate(portId); - - return IX_ETH_ACC_SUCCESS; -} - -/* - * PortDisable local variables. They contain the intermediate steps - * while the port is being disabled and the buffers being drained out - * of the NPE. - */ -typedef void (*IxEthAccPortDisableRx)(IxEthAccPortId portId, - IX_OSAL_MBUF * mBufPtr, - BOOL useMultiBufferCallback); -static IxEthAccPortRxCallback -ixEthAccPortDisableFn[IX_ETH_ACC_NUMBER_OF_PORTS]; -static IxEthAccPortMultiBufferRxCallback -ixEthAccPortDisableMultiBufferFn[IX_ETH_ACC_NUMBER_OF_PORTS]; -static IxEthAccPortDisableRx -ixEthAccPortDisableRxTable[IX_ETH_ACC_NUMBER_OF_PORTS]; -static UINT32 -ixEthAccPortDisableCbTag[IX_ETH_ACC_NUMBER_OF_PORTS]; -static UINT32 -ixEthAccPortDisableMultiBufferCbTag[IX_ETH_ACC_NUMBER_OF_PORTS]; - -static IxEthAccPortTxDoneCallback -ixEthAccPortDisableTxDoneFn[IX_ETH_ACC_NUMBER_OF_PORTS]; -static UINT32 -ixEthAccPortDisableTxDoneCbTag[IX_ETH_ACC_NUMBER_OF_PORTS]; - -static UINT32 -ixEthAccPortDisableUserBufferCount[IX_ETH_ACC_NUMBER_OF_PORTS]; - -/* - * PortDisable private callbacks functions. They handle the user - * traffic, and the special buffers (one for tx, one for rx) used - * in portDisable. - */ -PRIVATE void -ixEthAccPortDisableTxDone(UINT32 cbTag, - IX_OSAL_MBUF *mbuf) -{ - IxEthAccPortId portId = (IxEthAccPortId)cbTag; - volatile IxEthAccPortDisableState *txState = &ixEthAccMacState[portId].txState; - - /* check for the special mbuf used in portDisable */ - if (mbuf == ixEthAccMacState[portId].portDisableTxMbufPtr) - { - *txState = TRANSMIT_DONE; - } - else - { - /* increment the count of user traffic during portDisable */ - ixEthAccPortDisableUserBufferCount[portId]++; - - /* call client TxDone function */ - ixEthAccPortDisableTxDoneFn[portId](ixEthAccPortDisableTxDoneCbTag[portId], mbuf); - } -} - -PRIVATE IxEthAccStatus -ixEthAccPortDisableTryTransmit(UINT32 portId) -{ - int key; - IxEthAccStatus status = IX_ETH_ACC_SUCCESS; - volatile IxEthAccPortDisableState *txState = &ixEthAccMacState[portId].txState; - /* transmit the special buffer again if it is transmitted - * and update the txState - * This section is protected because the portDisable context - * run an identical code, so the system keeps transmitting at the - * maximum rate. - */ - key = ixOsalIrqLock(); - if (*txState == TRANSMIT_DONE) - { - IX_OSAL_MBUF *mbufTxPtr = ixEthAccMacState[portId].portDisableTxMbufPtr; - *txState = TRANSMIT; - status = ixEthAccPortTxFrameSubmit(portId, - mbufTxPtr, - IX_ETH_ACC_TX_DEFAULT_PRIORITY); - } - ixOsalIrqUnlock(key); - - return status; -} - -PRIVATE void -ixEthAccPortDisableTxDoneAndSubmit(UINT32 cbTag, - IX_OSAL_MBUF *mbuf) -{ - IxEthAccPortId portId = (IxEthAccPortId)cbTag; - - /* call the callback which forwards the traffic to the client */ - ixEthAccPortDisableTxDone(cbTag, mbuf); - - /* try to transmit the buffer used in portDisable - * if seen in TxDone - */ - ixEthAccPortDisableTryTransmit(portId); -} - -PRIVATE void -ixEthAccPortDisableRx (IxEthAccPortId portId, - IX_OSAL_MBUF * mBufPtr, - BOOL useMultiBufferCallback) -{ - volatile IxEthAccPortDisableState *rxState = &ixEthAccMacState[portId].rxState; - IX_OSAL_MBUF *mNextPtr; - - while (mBufPtr) - { - mNextPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mBufPtr); - IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mBufPtr) = NULL; - - /* check for the special mbuf used in portDisable */ - if (mBufPtr == ixEthAccMacState[portId].portDisableRxMbufPtr) - { - *rxState = RECEIVE; - } - else - { - /* increment the count of user traffic during portDisable */ - ixEthAccPortDisableUserBufferCount[portId]++; - - /* reset the received payload length during portDisable */ - IX_OSAL_MBUF_MLEN(mBufPtr) = 0; - IX_OSAL_MBUF_PKT_LEN(mBufPtr) = 0; - - if (useMultiBufferCallback) - { - /* call the user callback with one unchained - * buffer, without payload. A small array is built - * to be used as a parameter (the user callback expects - * to receive an array ended by a NULL pointer. - */ - IX_OSAL_MBUF *mBufPtrArray[2]; - - mBufPtrArray[0] = mBufPtr; - mBufPtrArray[1] = NULL; - ixEthAccPortDisableMultiBufferFn[portId]( - ixEthAccPortDisableMultiBufferCbTag[portId], - mBufPtrArray); - } - else - { - /* call the user callback with a unchained - * buffer, without payload and the destination port is - * unknown. - */ - ixEthAccPortDisableFn[portId]( - ixEthAccPortDisableCbTag[portId], - mBufPtr, - IX_ETH_DB_UNKNOWN_PORT /* port not found */); - } - } - - mBufPtr = mNextPtr; - } -} - -PRIVATE IxEthAccStatus -ixEthAccPortDisableTryReplenish(UINT32 portId) -{ - int key; - IxEthAccStatus status = IX_ETH_ACC_SUCCESS; - volatile IxEthAccPortDisableState *rxState = &ixEthAccMacState[portId].rxState; - /* replenish with the special buffer again if it is received - * and update the rxState - * This section is protected because the portDisable context - * run an identical code, so the system keeps replenishing at the - * maximum rate. - */ - key = ixOsalIrqLock(); - if (*rxState == RECEIVE) - { - IX_OSAL_MBUF *mbufRxPtr = ixEthAccMacState[portId].portDisableRxMbufPtr; - *rxState = REPLENISH; - IX_OSAL_MBUF_MLEN(mbufRxPtr) = IX_ETHACC_RX_MBUF_MIN_SIZE; - status = ixEthAccPortRxFreeReplenish(portId, mbufRxPtr); - } - ixOsalIrqUnlock(key); - - return status; -} - -PRIVATE void -ixEthAccPortDisableRxAndReplenish (IxEthAccPortId portId, - IX_OSAL_MBUF * mBufPtr, - BOOL useMultiBufferCallback) -{ - /* call the callback which forwards the traffic to the client */ - ixEthAccPortDisableRx(portId, mBufPtr, useMultiBufferCallback); - - /* try to replenish with the buffer used in portDisable - * if seen in Rx - */ - ixEthAccPortDisableTryReplenish(portId); -} - -PRIVATE void -ixEthAccPortDisableRxCallback (UINT32 cbTag, - IX_OSAL_MBUF * mBufPtr, - UINT32 learnedPortId) -{ - IxEthAccPortId portId = (IxEthAccPortId)cbTag; - - /* call the portDisable receive callback */ - (ixEthAccPortDisableRxTable[portId])(portId, mBufPtr, FALSE); -} - -PRIVATE void -ixEthAccPortDisableMultiBufferRxCallback (UINT32 cbTag, - IX_OSAL_MBUF **mBufPtr) -{ - IxEthAccPortId portId = (IxEthAccPortId)cbTag; - - while (*mBufPtr) - { - /* call the portDisable receive callback with one buffer at a time */ - (ixEthAccPortDisableRxTable[portId])(portId, *mBufPtr++, TRUE); - } -} - -IxEthAccStatus -ixEthAccPortDisablePriv(IxEthAccPortId portId) -{ - IxEthAccStatus status = IX_ETH_ACC_SUCCESS; - int key; - int retry, retryTimeout; - volatile IxEthAccPortDisableState *state = &ixEthAccMacState[portId].portDisableState; - volatile IxEthAccPortDisableState *rxState = &ixEthAccMacState[portId].rxState; - volatile IxEthAccPortDisableState *txState = &ixEthAccMacState[portId].txState; - - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot disable port.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - /* if the state is being set to what it is already at, do nothing */ - if (!ixEthAccMacState[portId].enabled) - { - return IX_ETH_ACC_SUCCESS; - } - - *state = DISABLED; - - /* disable MAC receive first */ - ixEthAccPortRxDisablePriv(portId); - -#ifdef CONFIG_IXP425_COMPONENT_ETHDB - /* disable ethernet database for this port - It is done now to avoid - * issuing ELT maintenance after requesting 'port disable' in an NPE - */ - if (ixEthDBPortDisable(portId) != IX_ETH_DB_SUCCESS) - { - status = IX_ETH_ACC_FAIL; - IX_ETH_ACC_FATAL_LOG("ixEthAccPortDisable: failed to disable EthDB for this port\n", 0, 0, 0, 0, 0, 0); - } -#endif - - /* enter the critical section */ - key = ixOsalIrqLock(); - - /* swap the Rx and TxDone callbacks */ - ixEthAccPortDisableFn[portId] = ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn; - ixEthAccPortDisableMultiBufferFn[portId] = ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn; - ixEthAccPortDisableCbTag[portId] = ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag; - ixEthAccPortDisableMultiBufferCbTag[portId] = ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag; - ixEthAccPortDisableTxDoneFn[portId] = ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn; - ixEthAccPortDisableTxDoneCbTag[portId] = ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag; - ixEthAccPortDisableRxTable[portId] = ixEthAccPortDisableRx; - - /* register temporary callbacks */ - ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn = ixEthAccPortDisableRxCallback; - ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag = portId; - - ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn = ixEthAccPortDisableMultiBufferRxCallback; - ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag = portId; - - ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn = ixEthAccPortDisableTxDone; - ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag = portId; - - /* initialise the Rx state and Tx states */ - *txState = TRANSMIT_DONE; - *rxState = RECEIVE; - - /* exit the critical section */ - ixOsalIrqUnlock(key); - - /* enable a NPE loopback */ - if (ixEthAccNpeLoopbackEnablePriv(portId) != IX_ETH_ACC_SUCCESS) - { - status = IX_ETH_ACC_FAIL; - } - - if (status == IX_ETH_ACC_SUCCESS) - { - retry = 0; - - /* Step 1 : Drain Tx traffic and TxDone queues : - * - * Transmit and replenish at least once with the - * special buffers until both of them are seen - * in the callback hook - * - * (the receive callback keeps replenishing, so once we see - * the special Tx buffer, we can be sure that Tx drain is complete) - */ - ixEthAccPortDisableRxTable[portId] - = ixEthAccPortDisableRxAndReplenish; - ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn - = ixEthAccPortDisableTxDone; - - do - { - /* keep replenishing */ - status = ixEthAccPortDisableTryReplenish(portId); - if (status == IX_ETH_ACC_SUCCESS) - { - /* keep transmitting */ - status = ixEthAccPortDisableTryTransmit(portId); - } - if (status == IX_ETH_ACC_SUCCESS) - { - /* wait for some traffic being processed */ - ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS); - } - } - while ((status == IX_ETH_ACC_SUCCESS) - && (retry++ < IX_ETH_ACC_MAX_RETRY) - && (*txState == TRANSMIT)); - - /* Step 2 : Drain Rx traffic, RxFree and Rx queues : - * - * Transmit and replenish at least once with the - * special buffers until both of them are seen - * in the callback hook - * (the transmit callback keeps transmitting, and when we see - * the special Rx buffer, we can be sure that rxFree drain - * is complete) - * - * The nested loop helps to retry if the user was keeping - * replenishing or transmitting during portDisable. - * - * The 2 nested loops ensure more retries if user traffic is - * seen during portDisable : the user should not replenish - * or transmit while portDisable is running. However, because of - * the queueing possibilities in ethAcc dataplane, it is possible - * that a lot of traffic is left in the queues (e.g. when - * transmitting over a low speed link) and therefore, more - * retries are allowed to help flushing the buffers out. - */ - ixEthAccPortDisableRxTable[portId] - = ixEthAccPortDisableRx; - ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn - = ixEthAccPortDisableTxDoneAndSubmit; - - do - { - do - { - ixEthAccPortDisableUserBufferCount[portId] = 0; - - /* keep replenishing */ - status = ixEthAccPortDisableTryReplenish(portId); - if (status == IX_ETH_ACC_SUCCESS) - { - /* keep transmitting */ - status = ixEthAccPortDisableTryTransmit(portId); - } - if (status == IX_ETH_ACC_SUCCESS) - { - /* wait for some traffic being processed */ - ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS); - } - } - while ((status == IX_ETH_ACC_SUCCESS) - && (retry++ < IX_ETH_ACC_MAX_RETRY) - && ((ixEthAccPortDisableUserBufferCount[portId] != 0) - || (*rxState == REPLENISH))); - - /* After the first iteration, change the receive callbacks, - * to process only 1 buffer at a time - */ - ixEthAccPortDisableRxTable[portId] - = ixEthAccPortDisableRx; - ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn - = ixEthAccPortDisableTxDone; - - /* repeat the whole process while user traffic is seen in TxDone - * - * The conditions to stop the loop are - * - Xscale has both Rx and Tx special buffers - * (txState = transmit, rxState = receive) - * - any error in txSubmit or rxReplenish - * - no user traffic seen - * - an excessive amount of retries - */ - } - while ((status == IX_ETH_ACC_SUCCESS) - && (retry < IX_ETH_ACC_MAX_RETRY) - && (*txState == TRANSMIT)); - - /* check the loop exit conditions. The NPE should not hold - * the special buffers. - */ - if ((*rxState == REPLENISH) || (*txState == TRANSMIT)) - { - status = IX_ETH_ACC_FAIL; - } - - if (status == IX_ETH_ACC_SUCCESS) - { - /* Step 3 : Replenish without transmitting until a timeout - * occurs, in order to drain the internal NPE fifos - * - * we can expect a few frames srill held - * in the NPE. - * - * The 2 nested loops take care about the NPE dropping traffic - * (including loopback traffic) when the Rx queue is full. - * - * The timeout value is very conservative - * since the loopback used keeps replenishhing. - * - */ - do - { - ixEthAccPortDisableRxTable[portId] = ixEthAccPortDisableRxAndReplenish; - ixEthAccPortDisableUserBufferCount[portId] = 0; - retryTimeout = 0; - do - { - /* keep replenishing */ - status = ixEthAccPortDisableTryReplenish(portId); - if (status == IX_ETH_ACC_SUCCESS) - { - /* wait for some traffic being processed */ - ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS); - } - } - while ((status == IX_ETH_ACC_SUCCESS) - && (retryTimeout++ < IX_ETH_ACC_MAX_RETRY_TIMEOUT)); - - /* Step 4 : Transmit once. Stop replenish - * - * After the Rx timeout, we are sure that the NPE does not - * hold any frame in its internal NPE fifos. - * - * At this point, the NPE still holds the last rxFree buffer. - * By transmitting a single frame, this should unblock the - * last rxFree buffer. This code just transmit once and - * wait for both frames seen in TxDone and in rxFree. - * - */ - ixEthAccPortDisableRxTable[portId] = ixEthAccPortDisableRx; - status = ixEthAccPortDisableTryTransmit(portId); - - /* the NPE should immediatelyt release - * the last Rx buffer and the last transmitted buffer - * unless the last Tx frame was dropped (rx queue full) - */ - if (status == IX_ETH_ACC_SUCCESS) - { - retryTimeout = 0; - do - { - ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS); - } - while ((*rxState == REPLENISH) - && (retryTimeout++ < IX_ETH_ACC_MAX_RETRY_TIMEOUT)); - } - - /* the NPE may have dropped the traffic because of Rx - * queue being full. This code ensures that the last - * Tx and Rx frames are both received. - */ - } - while ((status == IX_ETH_ACC_SUCCESS) - && (retry++ < IX_ETH_ACC_MAX_RETRY) - && ((*txState == TRANSMIT) - || (*rxState == REPLENISH) - || (ixEthAccPortDisableUserBufferCount[portId] != 0))); - - /* Step 5 : check the final states : the NPE has - * no buffer left, nor in Tx , nor in Rx directions. - */ - if ((*rxState == REPLENISH) || (*txState == TRANSMIT)) - { - status = IX_ETH_ACC_FAIL; - } - } - - /* now all the buffers are drained, disable NPE loopback - * This is done regardless of the logic to drain the queues and - * the internal buffers held by the NPE. - */ - if (ixEthAccNpeLoopbackDisablePriv(portId) != IX_ETH_ACC_SUCCESS) - { - status = IX_ETH_ACC_FAIL; - } - } - - /* disable MAC Tx and Rx services */ - ixEthAccMacState[portId].enabled = FALSE; - ixEthAccMacStateUpdate(portId); - - /* restore the Rx and TxDone callbacks (within a critical section) */ - key = ixOsalIrqLock(); - - ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn = ixEthAccPortDisableFn[portId]; - ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag = ixEthAccPortDisableCbTag[portId]; - ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn = ixEthAccPortDisableMultiBufferFn[portId]; - ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag = ixEthAccPortDisableMultiBufferCbTag[portId]; - ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn = ixEthAccPortDisableTxDoneFn[portId]; - ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag = ixEthAccPortDisableTxDoneCbTag[portId]; - - ixOsalIrqUnlock(key); - - /* the MAC core rx/tx disable may left the MAC hardware in an - * unpredictable state. A hw reset is executed before resetting - * all the MAC parameters to a known value. - */ - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_CORE_CNTRL, - IX_ETH_ACC_CORE_RESET); - - ixOsalSleep(IX_ETH_ACC_MAC_RESET_DELAY); - - /* rewrite all parameters to their current value */ - ixEthAccMacStateUpdate(portId); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_INT_CLK_THRESH, - IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_CORE_CNTRL, - IX_ETH_ACC_CORE_MDC_EN); - - return status; -} - -IxEthAccStatus -ixEthAccPortEnabledQueryPriv(IxEthAccPortId portId, BOOL *enabled) -{ - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable port.\n",(INT32)portId,0,0,0,0,0); - - /* Since Eth NPE is not available, port must be disabled */ - *enabled = FALSE ; - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - /* Since Eth NPE is not available, port must be disabled */ - *enabled = FALSE ; - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - *enabled = ixEthAccMacState[portId].enabled; - - return IX_ETH_ACC_SUCCESS; -} - -IxEthAccStatus -ixEthAccPortMacResetPriv(IxEthAccPortId portId) -{ - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot reset Ethernet coprocessor.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_CORE_CNTRL, - IX_ETH_ACC_CORE_RESET); - - ixOsalSleep(IX_ETH_ACC_MAC_RESET_DELAY); - - /* rewrite all parameters to their current value */ - ixEthAccMacStateUpdate(portId); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_INT_CLK_THRESH, - IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_CORE_CNTRL, - IX_ETH_ACC_CORE_MDC_EN); - - return IX_ETH_ACC_SUCCESS; -} - -IxEthAccStatus -ixEthAccPortLoopbackEnable(IxEthAccPortId portId) -{ - UINT32 regval; - - /* Turn off promiscuous mode */ - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable loopback.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - /* read register */ - REG_READ(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - regval); - - /* update register */ - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - regval | IX_ETH_ACC_RX_CNTRL1_LOOP_EN); - - return IX_ETH_ACC_SUCCESS; -} - -PRIVATE void -ixEthAccNpeLoopbackMessageCallback (IxNpeMhNpeId npeId, - IxNpeMhMessage msg) -{ - IxEthAccPortId portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId); - -#ifndef NDEBUG - /* Prudent to at least check the port is within range */ - if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS) - { - IX_ETH_ACC_FATAL_LOG("IXETHACC:ixEthAccPortDisableMessageCallback: Illegal port: %u\n", - (UINT32) portId, 0, 0, 0, 0, 0); - - return; - } -#endif - - /* unlock message reception mutex */ - ixOsalMutexUnlock(&ixEthAccMacState[portId].npeLoopbackMessageLock); -} - -IxEthAccStatus -ixEthAccNpeLoopbackEnablePriv(IxEthAccPortId portId) -{ - IX_STATUS npeMhStatus; - IxNpeMhMessage message; - IxEthAccStatus status = IX_ETH_ACC_SUCCESS; - - /* Turn off promiscuous mode */ - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable NPE loopback.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - /* enable NPE loopback (lsb of the message contains the value 1) */ - message.data[0] = (IX_ETHNPE_SETLOOPBACK_MODE << IX_ETH_ACC_MAC_MSGID_SHL) - | 0x01; - message.data[1] = 0; - - npeMhStatus = ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId), - message, - IX_ETHNPE_SETLOOPBACK_MODE_ACK, - ixEthAccNpeLoopbackMessageCallback, - IX_NPEMH_SEND_RETRIES_DEFAULT); - - if (npeMhStatus != IX_SUCCESS) - { - status = IX_ETH_ACC_FAIL; - } - else - { - /* wait for NPE loopbackEnable response */ - if (ixOsalMutexLock(&ixEthAccMacState[portId]. npeLoopbackMessageLock, - IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS) - != IX_SUCCESS) - { - status = IX_ETH_ACC_FAIL; - } - } - - return status; -} - -IxEthAccStatus -ixEthAccPortTxEnablePriv(IxEthAccPortId portId) -{ - UINT32 regval; - - /* Turn off promiscuous mode */ - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable TX.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - /* read register */ - REG_READ(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_TX_CNTRL1, - regval); - - /* update register */ - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_TX_CNTRL1, - regval | IX_ETH_ACC_TX_CNTRL1_TX_EN); - - return IX_ETH_ACC_SUCCESS; -} - -IxEthAccStatus -ixEthAccPortRxEnablePriv(IxEthAccPortId portId) -{ - UINT32 regval; - - /* Turn off promiscuous mode */ - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable RX.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - /* read register */ - REG_READ(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - regval); - - /* update register */ - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - regval | IX_ETH_ACC_RX_CNTRL1_RX_EN); - - return IX_ETH_ACC_SUCCESS; -} - -IxEthAccStatus -ixEthAccPortLoopbackDisable(IxEthAccPortId portId) -{ - UINT32 regval; - - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot disable loopback.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - /*disable MAC loopabck */ - REG_READ(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - regval); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - (regval & ~IX_ETH_ACC_RX_CNTRL1_LOOP_EN)); - - return IX_ETH_ACC_SUCCESS; -} - -IxEthAccStatus -ixEthAccNpeLoopbackDisablePriv(IxEthAccPortId portId) -{ - IX_STATUS npeMhStatus; - IxNpeMhMessage message; - IxEthAccStatus status = IX_ETH_ACC_SUCCESS; - - /* Turn off promiscuous mode */ - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable NPE loopback.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - /* disable NPE loopback (lsb of the message contains the value 0) */ - message.data[0] = (IX_ETHNPE_SETLOOPBACK_MODE << IX_ETH_ACC_MAC_MSGID_SHL); - message.data[1] = 0; - - npeMhStatus = ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId), - message, - IX_ETHNPE_SETLOOPBACK_MODE_ACK, - ixEthAccNpeLoopbackMessageCallback, - IX_NPEMH_SEND_RETRIES_DEFAULT); - - if (npeMhStatus != IX_SUCCESS) - { - status = IX_ETH_ACC_FAIL; - } - else - { - /* wait for NPE loopbackEnable response */ - if (ixOsalMutexLock(&ixEthAccMacState[portId].npeLoopbackMessageLock, - IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS) - != IX_SUCCESS) - { - status = IX_ETH_ACC_FAIL; - } - } - - return status; -} - -IxEthAccStatus -ixEthAccPortTxDisablePriv(IxEthAccPortId portId) -{ - UINT32 regval; - - /* Turn off promiscuous mode */ - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot disable TX.\n", (INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - /* read register */ - REG_READ(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_TX_CNTRL1, - regval); - - /* update register */ - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_TX_CNTRL1, - (regval & ~IX_ETH_ACC_TX_CNTRL1_TX_EN)); - - return IX_ETH_ACC_SUCCESS; -} - -IxEthAccStatus -ixEthAccPortRxDisablePriv(IxEthAccPortId portId) -{ - UINT32 regval; - - /* Turn off promiscuous mode */ - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot disable RX.\n", (INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - /* read register */ - REG_READ(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - regval); - - /* update register */ - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - (regval & ~IX_ETH_ACC_RX_CNTRL1_RX_EN)); - - return IX_ETH_ACC_SUCCESS; -} - -IxEthAccStatus -ixEthAccPortPromiscuousModeClearPriv(IxEthAccPortId portId) -{ - UINT32 regval; - - /* Turn off promiscuous mode */ - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot clear promiscuous mode.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - /*set bit 5 of Rx control 1 - enable address filtering*/ - REG_READ(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - regval); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - regval | IX_ETH_ACC_RX_CNTRL1_ADDR_FLTR_EN); - - ixEthAccMacState[portId].promiscuous = FALSE; - - ixEthAccMulticastAddressSet(portId); - - return IX_ETH_ACC_SUCCESS; -} - -IxEthAccStatus -ixEthAccPortPromiscuousModeSetPriv(IxEthAccPortId portId) -{ - UINT32 regval; - - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot set promiscuous mode.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - /* - * Set bit 5 of Rx control 1 - We enable address filtering even in - * promiscuous mode because we want the MAC to set the appropriate - * bits in m_flags which doesn't happen if we turn off filtering. - */ - REG_READ(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - regval); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - regval | IX_ETH_ACC_RX_CNTRL1_ADDR_FLTR_EN); - - ixEthAccMacState[portId].promiscuous = TRUE; - - ixEthAccMulticastAddressSet(portId); - - return IX_ETH_ACC_SUCCESS; -} - -IxEthAccStatus -ixEthAccPortUnicastMacAddressSetPriv (IxEthAccPortId portId, - IxEthAccMacAddr *macAddr) -{ - UINT32 i; - - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot set Unicast Mac Address.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - - if (macAddr == NULL) - { - return IX_ETH_ACC_FAIL; - } - - if ( macAddr->macAddress[0] & IX_ETH_ACC_ETH_MAC_BCAST_MCAST_BIT ) - { - /* This is a multicast/broadcast address cant set it ! */ - return IX_ETH_ACC_FAIL; - } - - if ( macAddr->macAddress[0] == 0 && - macAddr->macAddress[1] == 0 && - macAddr->macAddress[2] == 0 && - macAddr->macAddress[3] == 0 && - macAddr->macAddress[4] == 0 && - macAddr->macAddress[5] == 0 ) - { - /* This is an invalid mac address cant set it ! */ - return IX_ETH_ACC_FAIL; - } - -#ifdef CONFIG_IXP425_COMPONENT_ETHDB - /* update the MAC address in the ethernet database */ - if (ixEthDBPortAddressSet(portId, (IxEthDBMacAddr *) macAddr) != IX_ETH_DB_SUCCESS) - { - return IX_ETH_ACC_FAIL; - } -#endif - - /*Set the Unicast MAC to the specified value*/ - for(i=0;imacAddress[i]); - } - ixEthAccMacState[portId].initDone = TRUE; - - return IX_ETH_ACC_SUCCESS; -} - -IxEthAccStatus -ixEthAccPortUnicastMacAddressGetPriv (IxEthAccPortId portId, - IxEthAccMacAddr *macAddr) -{ - /*Return the current value of the Unicast MAC from h/w - for the specified port*/ - UINT32 i; - - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot get Unicast Mac Address.\n",(INT32)portId,0,0,0,0,0); - /* Since Eth Npe is unavailable, return invalid MAC Address = 00:00:00:00:00:00 */ - for(i=0;imacAddress[i] = 0; - } - return IX_ETH_ACC_SUCCESS ; - } - - if(!ixEthAccMacState[portId].initDone) - { - return (IX_ETH_ACC_MAC_UNINITIALIZED); - } - - if (macAddr == NULL) - { - return IX_ETH_ACC_FAIL; - } - - - for(i=0;imacAddress[i]); - } - return IX_ETH_ACC_SUCCESS; -} - -PRIVATE IxEthAccStatus -ixEthAccPortMulticastMacAddressGet (IxEthAccPortId portId, - IxEthAccMacAddr *macAddr) -{ - /*Return the current value of the Multicast MAC from h/w - for the specified port*/ - UINT32 i; - - for(i=0;imacAddress[i]); - } - - return IX_ETH_ACC_SUCCESS; -} - -PRIVATE IxEthAccStatus -ixEthAccPortMulticastMacFilterGet (IxEthAccPortId portId, - IxEthAccMacAddr *macAddr) -{ - /*Return the current value of the Multicast MAC from h/w - for the specified port*/ - UINT32 i; - - for(i=0;imacAddress[i]); - } - return IX_ETH_ACC_SUCCESS; -} - -IxEthAccStatus -ixEthAccPortMulticastAddressJoinPriv (IxEthAccPortId portId, - IxEthAccMacAddr *macAddr) -{ - UINT32 i; - IxEthAccMacAddr broadcastAddr = {{0xff,0xff,0xff,0xff,0xff,0xff}}; - - /*Check that the port parameter is valid*/ - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot join Multicast Mac Address.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - /*Check that the mac address is valid*/ - if(macAddr == NULL) - { - return IX_ETH_ACC_FAIL; - } - - /* Check that this is a multicast address */ - if (!(macAddr->macAddress[0] & IX_ETH_ACC_ETH_MAC_BCAST_MCAST_BIT)) - { - return IX_ETH_ACC_FAIL; - } - - /* We don't add the Broadcast address */ - if(ixEthAccMacEqual(&broadcastAddr, macAddr)) - { - return IX_ETH_ACC_FAIL; - } - - for (i = 0; - i= IX_ETH_ACC_MAX_MULTICAST_ADDRESSES) - { - return IX_ETH_ACC_FAIL; - } - - /*First add the address to the multicast table for the - specified port*/ - i=ixEthAccMacState[portId].mcastAddrIndex; - - memcpy(&ixEthAccMacState[portId].mcastAddrsTable[i], - &macAddr->macAddress, - IX_IEEE803_MAC_ADDRESS_SIZE); - - /*Increment the index into the table, this must be done here - as MulticastAddressSet below needs to know about the latest - entry. - */ - ixEthAccMacState[portId].mcastAddrIndex++; - - /*Then calculate the new value to be written to the address and - address mask registers*/ - ixEthAccMulticastAddressSet(portId); - - return IX_ETH_ACC_SUCCESS; -} - - -IxEthAccStatus -ixEthAccPortMulticastAddressJoinAllPriv (IxEthAccPortId portId) -{ - IxEthAccMacAddr mcastMacAddr = {{0x1,0x0,0x0,0x0,0x0,0x0}}; - - /*Check that the port parameter is valid*/ - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot join all Multicast Address.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - /* remove all entries from the database and - * insert a multicast entry - */ - memcpy(&ixEthAccMacState[portId].mcastAddrsTable[0], - &mcastMacAddr.macAddress, - IX_IEEE803_MAC_ADDRESS_SIZE); - - ixEthAccMacState[portId].mcastAddrIndex = 1; - ixEthAccMacState[portId].joinAll = TRUE; - - ixEthAccMulticastAddressSet(portId); - - return IX_ETH_ACC_SUCCESS; -} - -IxEthAccStatus -ixEthAccPortMulticastAddressLeavePriv (IxEthAccPortId portId, - IxEthAccMacAddr *macAddr) -{ - UINT32 i; - IxEthAccMacAddr mcastMacAddr = {{0x1,0x0,0x0,0x0,0x0,0x0}}; - - /*Check that the port parameter is valid*/ - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot leave Multicast Address.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - /*Check that the mac address is valid*/ - if(macAddr == NULL) - { - return IX_ETH_ACC_FAIL; - } - /* Remove this mac address from the mask for the specified port - * we copy down all entries above the blanked entry, and - * decrement the index - */ - i=0; - - while(i= IX_ETH_ACC_NUMBER_OF_PORTS) - { - IX_ETH_ACC_FATAL_LOG( - "IXETHACC:ixEthAccMacNpeStatsMessageCallback: Illegal port: %u\n", - (UINT32)portId, 0, 0, 0, 0, 0); - return; - } -#endif - - /*Unblock Stats Get call*/ - ixOsalMutexUnlock(&ixEthAccMacState[portId].ackMIBStatsLock); - -} - -PRIVATE void -ixEthAccMibIIStatsEndianConvert (IxEthEthObjStats *retStats) -{ - /* endianness conversion */ - - /* Rx stats */ - retStats->dot3StatsAlignmentErrors = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsAlignmentErrors); - retStats->dot3StatsFCSErrors = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsFCSErrors); - retStats->dot3StatsInternalMacReceiveErrors = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsInternalMacReceiveErrors); - retStats->RxOverrunDiscards = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxOverrunDiscards); - retStats->RxLearnedEntryDiscards = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxLearnedEntryDiscards); - retStats->RxLargeFramesDiscards = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxLargeFramesDiscards); - retStats->RxSTPBlockedDiscards = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxSTPBlockedDiscards); - retStats->RxVLANTypeFilterDiscards = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxVLANTypeFilterDiscards); - retStats->RxVLANIdFilterDiscards = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxVLANIdFilterDiscards); - retStats->RxInvalidSourceDiscards = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxInvalidSourceDiscards); - retStats->RxBlackListDiscards = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxBlackListDiscards); - retStats->RxWhiteListDiscards = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxWhiteListDiscards); - retStats->RxUnderflowEntryDiscards = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxUnderflowEntryDiscards); - - /* Tx stats */ - retStats->dot3StatsSingleCollisionFrames = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsSingleCollisionFrames); - retStats->dot3StatsMultipleCollisionFrames = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsMultipleCollisionFrames); - retStats->dot3StatsDeferredTransmissions = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsDeferredTransmissions); - retStats->dot3StatsLateCollisions = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsLateCollisions); - retStats->dot3StatsExcessiveCollsions = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsExcessiveCollsions); - retStats->dot3StatsInternalMacTransmitErrors = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsInternalMacTransmitErrors); - retStats->dot3StatsCarrierSenseErrors = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsCarrierSenseErrors); - retStats->TxLargeFrameDiscards = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->TxLargeFrameDiscards); - retStats->TxVLANIdFilterDiscards = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->TxVLANIdFilterDiscards); -} - -IxEthAccStatus -ixEthAccMibIIStatsGet (IxEthAccPortId portId, - IxEthEthObjStats *retStats ) -{ - IxNpeMhMessage message; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - printf("EthAcc: ixEthAccMibIIStatsGet (Mac) EthAcc service is not initialized\n"); - return (IX_ETH_ACC_FAIL); - } - - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (retStats == NULL) - { - printf("EthAcc: ixEthAccMibIIStatsGet (Mac) NULL argument\n"); - return (IX_ETH_ACC_FAIL); - } - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - printf("EthAcc: ixEthAccMibIIStatsGet (Mac) NPE for port %d is not available\n", portId); - - IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot get MIB II Stats.\n",(INT32)portId,0,0,0,0,0); - - /* Return all zero stats */ - IX_ETH_ACC_MEMSET(retStats, 0, sizeof(IxEthEthObjStats)); - - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - printf("EthAcc: ixEthAccMibIIStatsGet (Mac) port %d is not initialized\n", portId); - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - IX_OSAL_CACHE_INVALIDATE(retStats, sizeof(IxEthEthObjStats)); - - message.data[0] = IX_ETHNPE_GETSTATS << IX_ETH_ACC_MAC_MSGID_SHL; - message.data[1] = (UINT32) IX_OSAL_MMU_VIRT_TO_PHYS(retStats); - - /* Permit only one task to request MIB statistics Get operation - at a time */ - ixOsalMutexLock(&ixEthAccMacState[portId].MIBStatsGetAccessLock, IX_OSAL_WAIT_FOREVER); - - if(ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId), - message, - IX_ETHNPE_GETSTATS, - ixEthAccMacNpeStatsMessageCallback, - IX_NPEMH_SEND_RETRIES_DEFAULT) - != IX_SUCCESS) - { - ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetAccessLock); - - printf("EthAcc: (Mac) StatsGet failed to send NPE message\n"); - - return IX_ETH_ACC_FAIL; - } - - /* Wait for callback invocation indicating response to - this request - we need this mutex in order to ensure - that the return from this function is synchronous */ - ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsLock, IX_ETH_ACC_MIB_STATS_DELAY_MSECS); - - /* Permit other tasks to perform MIB statistics Get operation */ - ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetAccessLock); - - ixEthAccMibIIStatsEndianConvert (retStats); - - return IX_ETH_ACC_SUCCESS; -} - - -PRIVATE void -ixEthAccMacNpeStatsResetMessageCallback (IxNpeMhNpeId npeId, - IxNpeMhMessage msg) -{ - IxEthAccPortId portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId); - -#ifndef NDEBUG - /* Prudent to at least check the port is within range */ - if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS) - { - IX_ETH_ACC_FATAL_LOG( - "IXETHACC:ixEthAccMacNpeStatsResetMessageCallback: Illegal port: %u\n", - (UINT32)portId, 0, 0, 0, 0, 0); - return; - } -#endif - - /*Unblock Stats Get & reset call*/ - ixOsalMutexUnlock(&ixEthAccMacState[portId].ackMIBStatsResetLock); - -} - - - -IxEthAccStatus -ixEthAccMibIIStatsGetClear (IxEthAccPortId portId, - IxEthEthObjStats *retStats) -{ - IxNpeMhMessage message; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) EthAcc service is not initialized\n"); - return (IX_ETH_ACC_FAIL); - } - - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (retStats == NULL) - { - printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) NULL argument\n"); - return (IX_ETH_ACC_FAIL); - } - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) NPE for port %d is not available\n", portId); - - IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot get and clear MIB II Stats.\n", (INT32)portId, 0, 0, 0, 0, 0); - - /* Return all zero stats */ - IX_ETH_ACC_MEMSET(retStats, 0, sizeof(IxEthEthObjStats)); - - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) port %d is not initialized\n", portId); - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - IX_OSAL_CACHE_INVALIDATE(retStats, sizeof(IxEthEthObjStats)); - - message.data[0] = IX_ETHNPE_RESETSTATS << IX_ETH_ACC_MAC_MSGID_SHL; - message.data[1] = (UINT32) IX_OSAL_MMU_VIRT_TO_PHYS(retStats); - - /* Permit only one task to request MIB statistics Get-Reset operation at a time */ - ixOsalMutexLock(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock, IX_OSAL_WAIT_FOREVER); - - if(ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId), - message, - IX_ETHNPE_RESETSTATS, - ixEthAccMacNpeStatsResetMessageCallback, - IX_NPEMH_SEND_RETRIES_DEFAULT) - != IX_SUCCESS) - { - ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock); - - printf("EthAcc: (Mac) ixEthAccMibIIStatsGetClear failed to send NPE message\n"); - - return IX_ETH_ACC_FAIL; - } - - /* Wait for callback invocation indicating response to this request */ - ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsResetLock, IX_ETH_ACC_MIB_STATS_DELAY_MSECS); - - /* permit other tasks to get and reset MIB stats*/ - ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock); - - ixEthAccMibIIStatsEndianConvert(retStats); - - return IX_ETH_ACC_SUCCESS; -} - -IxEthAccStatus -ixEthAccMibIIStatsClear (IxEthAccPortId portId) -{ - static IxEthEthObjStats retStats; - IxEthAccStatus status; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot clear MIB II Stats.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - /* there is no reset operation without a corresponding Get */ - status = ixEthAccMibIIStatsGetClear(portId, &retStats); - - return status; -} - -/* Initialize the ethernet MAC settings */ -IxEthAccStatus -ixEthAccMacInit(IxEthAccPortId portId) -{ - IX_OSAL_MBUF_POOL* portDisablePool; - UINT8 *data; - - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot initialize Mac.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if(ixEthAccMacState[portId].macInitialised == FALSE) - { - ixEthAccMacState[portId].fullDuplex = TRUE; - ixEthAccMacState[portId].rxFCSAppend = TRUE; - ixEthAccMacState[portId].txFCSAppend = TRUE; - ixEthAccMacState[portId].txPADAppend = TRUE; - ixEthAccMacState[portId].enabled = FALSE; - ixEthAccMacState[portId].promiscuous = TRUE; - ixEthAccMacState[portId].joinAll = FALSE; - ixEthAccMacState[portId].initDone = FALSE; - ixEthAccMacState[portId].macInitialised = TRUE; - - /* initialize MIB stats mutexes */ - ixOsalMutexInit(&ixEthAccMacState[portId].ackMIBStatsLock); - ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsLock, IX_OSAL_WAIT_FOREVER); - - ixOsalMutexInit(&ixEthAccMacState[portId].ackMIBStatsResetLock); - ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsResetLock, IX_OSAL_WAIT_FOREVER); - - ixOsalMutexInit(&ixEthAccMacState[portId].MIBStatsGetAccessLock); - - ixOsalMutexInit(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock); - - ixOsalMutexInit(&ixEthAccMacState[portId].npeLoopbackMessageLock); - - ixEthAccMacState[portId].portDisableRxMbufPtr = NULL; - ixEthAccMacState[portId].portDisableTxMbufPtr = NULL; - - portDisablePool = IX_OSAL_MBUF_POOL_INIT(2, - IX_ETHACC_RX_MBUF_MIN_SIZE, - "portDisable Pool"); - - IX_OSAL_ENSURE(portDisablePool != NULL, "Failed to initialize PortDisable pool"); - - ixEthAccMacState[portId].portDisableRxMbufPtr = IX_OSAL_MBUF_POOL_GET(portDisablePool); - ixEthAccMacState[portId].portDisableTxMbufPtr = IX_OSAL_MBUF_POOL_GET(portDisablePool); - - IX_OSAL_ENSURE(ixEthAccMacState[portId].portDisableRxMbufPtr != NULL, - "Pool allocation failed"); - IX_OSAL_ENSURE(ixEthAccMacState[portId].portDisableTxMbufPtr != NULL, - "Pool allocation failed"); - /* fill the payload of the Rx mbuf used in portDisable */ - IX_OSAL_MBUF_MLEN(ixEthAccMacState[portId].portDisableRxMbufPtr) = IX_ETHACC_RX_MBUF_MIN_SIZE; - - memset(IX_OSAL_MBUF_MDATA(ixEthAccMacState[portId].portDisableRxMbufPtr), - 0xAA, - IX_ETHACC_RX_MBUF_MIN_SIZE); - - /* fill the payload of the Tx mbuf used in portDisable (64 bytes) */ - IX_OSAL_MBUF_MLEN(ixEthAccMacState[portId].portDisableTxMbufPtr) = 64; - IX_OSAL_MBUF_PKT_LEN(ixEthAccMacState[portId].portDisableTxMbufPtr) = 64; - - data = (UINT8 *) IX_OSAL_MBUF_MDATA(ixEthAccMacState[portId].portDisableTxMbufPtr); - memset(data, 0xBB, 64); - data[0] = 0x00; /* unicast destination MAC address */ - data[6] = 0x00; /* unicast source MAC address */ - data[12] = 0x08; /* typelength : IP frame */ - data[13] = 0x00; /* typelength : IP frame */ - - IX_OSAL_CACHE_FLUSH(data, 64); - } - - IX_OSAL_ASSERT (ixEthAccMacBase[portId] != 0); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_CORE_CNTRL, - IX_ETH_ACC_CORE_RESET); - - ixOsalSleep(IX_ETH_ACC_MAC_RESET_DELAY); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_CORE_CNTRL, - IX_ETH_ACC_CORE_MDC_EN); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_INT_CLK_THRESH, - IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT); - - ixEthAccMacStateUpdate(portId); - - return IX_ETH_ACC_SUCCESS; -} - -/* PRIVATE Functions*/ - -PRIVATE void -ixEthAccMacStateUpdate(IxEthAccPortId portId) -{ - UINT32 regval; - - if ( ixEthAccMacState[portId].enabled == FALSE ) - { - /* Just disable both the transmitter and reciver in the MAC. */ - REG_READ(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - regval); - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - regval & ~IX_ETH_ACC_RX_CNTRL1_RX_EN); - - REG_READ(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_TX_CNTRL1, - regval); - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_TX_CNTRL1, - regval & ~IX_ETH_ACC_TX_CNTRL1_TX_EN); - } - - if(ixEthAccMacState[portId].fullDuplex) - { - ixEthAccPortDuplexModeSetPriv (portId, IX_ETH_ACC_FULL_DUPLEX); - } - else - { - ixEthAccPortDuplexModeSetPriv (portId, IX_ETH_ACC_HALF_DUPLEX); - } - - if(ixEthAccMacState[portId].rxFCSAppend) - { - ixEthAccPortRxFrameAppendFCSEnablePriv (portId); - } - else - { - ixEthAccPortRxFrameAppendFCSDisablePriv (portId); - } - - if(ixEthAccMacState[portId].txFCSAppend) - { - ixEthAccPortTxFrameAppendFCSEnablePriv (portId); - } - else - { - ixEthAccPortTxFrameAppendFCSDisablePriv (portId); - } - - if(ixEthAccMacState[portId].txPADAppend) - { - ixEthAccPortTxFrameAppendPaddingEnablePriv (portId); - } - else - { - ixEthAccPortTxFrameAppendPaddingDisablePriv (portId); - } - - if(ixEthAccMacState[portId].promiscuous) - { - ixEthAccPortPromiscuousModeSetPriv(portId); - } - else - { - ixEthAccPortPromiscuousModeClearPriv(portId); - } - - if ( ixEthAccMacState[portId].enabled == TRUE ) - { - /* Enable both the transmitter and reciver in the MAC. */ - REG_READ(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - regval); - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - regval | IX_ETH_ACC_RX_CNTRL1_RX_EN); - - REG_READ(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_TX_CNTRL1, - regval); - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_TX_CNTRL1, - regval | IX_ETH_ACC_TX_CNTRL1_TX_EN); - } -} - - -PRIVATE BOOL -ixEthAccMacEqual(IxEthAccMacAddr *macAddr1, - IxEthAccMacAddr *macAddr2) -{ - UINT32 i; - for(i=0;imacAddress[i] != macAddr2->macAddress[i]) - { - return FALSE; - } - } - return TRUE; -} - -PRIVATE void -ixEthAccMacPrint(IxEthAccMacAddr *m) -{ - printf("%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x", - m->macAddress[0], m->macAddress[1], - m->macAddress[2], m->macAddress[3], - m->macAddress[4], m->macAddress[5]); -} - -/* Set the multicast address and address mask registers - * - * A bit in the address mask register must be set if - * all multicast addresses always have that bit set, or if - * all multicast addresses always have that bit cleared. - * - * A bit in the address register must be set if all multicast - * addresses have that bit set, otherwise, it should be cleared - */ - -PRIVATE void -ixEthAccMulticastAddressSet(IxEthAccPortId portId) -{ - UINT32 i; - UINT32 j; - IxEthAccMacAddr addressMask; - IxEthAccMacAddr address; - IxEthAccMacAddr alwaysClearBits; - IxEthAccMacAddr alwaysSetBits; - - /* calculate alwaysClearBits and alwaysSetBits: - * alwaysClearBits is calculated by ORing all - * multicast addresses, those bits that are always - * clear are clear in the result - * - * alwaysSetBits is calculated by ANDing all - * multicast addresses, those bits that are always set - * are set in the result - */ - - if (ixEthAccMacState[portId].promiscuous == TRUE) - { - /* Promiscuous Mode is set, and filtering - * allow all packets, and enable the mcast and - * bcast detection. - */ - memset(&addressMask.macAddress, - 0, - IX_IEEE803_MAC_ADDRESS_SIZE); - memset(&address.macAddress, - 0, - IX_IEEE803_MAC_ADDRESS_SIZE); - } - else - { - if(ixEthAccMacState[portId].joinAll == TRUE) - { - /* Join all is set. The mask and address are - * the multicast settings. - */ - IxEthAccMacAddr macAddr = {{0x1,0x0,0x0,0x0,0x0,0x0}}; - - memcpy(addressMask.macAddress, - macAddr.macAddress, - IX_IEEE803_MAC_ADDRESS_SIZE); - memcpy(address.macAddress, - macAddr.macAddress, - IX_IEEE803_MAC_ADDRESS_SIZE); - } - else if(ixEthAccMacState[portId].mcastAddrIndex == 0) - { - /* No entry in the filtering database, - * Promiscuous Mode is cleared, Broadcast filtering - * is configured. - */ - memset(addressMask.macAddress, - IX_ETH_ACC_MAC_ALL_BITS_SET, - IX_IEEE803_MAC_ADDRESS_SIZE); - memset(address.macAddress, - IX_ETH_ACC_MAC_ALL_BITS_SET, - IX_IEEE803_MAC_ADDRESS_SIZE); - } - else - { - /* build a mask and an address which mix all entreis - * from the list of multicast addresses - */ - memset(alwaysClearBits.macAddress, - 0, - IX_IEEE803_MAC_ADDRESS_SIZE); - memset(alwaysSetBits.macAddress, - IX_ETH_ACC_MAC_ALL_BITS_SET, - IX_IEEE803_MAC_ADDRESS_SIZE); - - for(i=0;i> 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; -} - diff --git a/cpu/ixp/npe/IxEthDBAPI.c b/cpu/ixp/npe/IxEthDBAPI.c deleted file mode 100644 index b2bfb72606..0000000000 --- a/cpu/ixp/npe/IxEthDBAPI.c +++ /dev/null @@ -1,448 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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; -} diff --git a/cpu/ixp/npe/IxEthDBAPISupport.c b/cpu/ixp/npe/IxEthDBAPISupport.c deleted file mode 100644 index 25633a3d56..0000000000 --- a/cpu/ixp/npe/IxEthDBAPISupport.c +++ /dev/null @@ -1,678 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#include -#include -#include - -#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; - IxOsalMutex *ackPortAddressLock; - 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; - } - - ackPortAddressLock = &ixEthDBPortInfo[portID].npeAckLock; - - /* 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; -} diff --git a/cpu/ixp/npe/IxEthDBCore.c b/cpu/ixp/npe/IxEthDBCore.c deleted file mode 100644 index 25b7cbb8b8..0000000000 --- a/cpu/ixp/npe/IxEthDBCore.c +++ /dev/null @@ -1,463 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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; -} diff --git a/cpu/ixp/npe/IxEthDBEvents.c b/cpu/ixp/npe/IxEthDBEvents.c deleted file mode 100644 index 4d44e03337..0000000000 --- a/cpu/ixp/npe/IxEthDBEvents.c +++ /dev/null @@ -1,520 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#include -#include - -#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); -} - diff --git a/cpu/ixp/npe/IxEthDBFeatures.c b/cpu/ixp/npe/IxEthDBFeatures.c deleted file mode 100644 index 7a58d268ca..0000000000 --- a/cpu/ixp/npe/IxEthDBFeatures.c +++ /dev/null @@ -1,662 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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 < sizeof (ixEthDBTrafficClassDefinitions) / sizeof (ixEthDBTrafficClassDefinitions[0]); - 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 == sizeof (ixEthDBTrafficClassDefinitions) / sizeof (ixEthDBTrafficClassDefinitions[0])) - { - 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; -} diff --git a/cpu/ixp/npe/IxEthDBFirewall.c b/cpu/ixp/npe/IxEthDBFirewall.c deleted file mode 100644 index eb46174b6c..0000000000 --- a/cpu/ixp/npe/IxEthDBFirewall.c +++ /dev/null @@ -1,266 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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; -} diff --git a/cpu/ixp/npe/IxEthDBHashtable.c b/cpu/ixp/npe/IxEthDBHashtable.c deleted file mode 100644 index f1b18e6b48..0000000000 --- a/cpu/ixp/npe/IxEthDBHashtable.c +++ /dev/null @@ -1,642 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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 entry 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 reference and places the - * pointer to the resulting node in searchResult. - * 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 IX_ETH_DB_SUCCESS 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 reference. - * 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; -} - -/** - * @} - */ diff --git a/cpu/ixp/npe/IxEthDBLearning.c b/cpu/ixp/npe/IxEthDBLearning.c deleted file mode 100644 index 2287dbe96c..0000000000 --- a/cpu/ixp/npe/IxEthDBLearning.c +++ /dev/null @@ -1,149 +0,0 @@ -/** - * @file IxEthDBLearning.c - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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; -} - diff --git a/cpu/ixp/npe/IxEthDBMem.c b/cpu/ixp/npe/IxEthDBMem.c deleted file mode 100644 index 133cbef8d6..0000000000 --- a/cpu/ixp/npe/IxEthDBMem.c +++ /dev/null @@ -1,649 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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, its associated descriptor - * and recursively of all its child nodes. - * - * @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 - */ diff --git a/cpu/ixp/npe/IxEthDBNPEAdaptor.c b/cpu/ixp/npe/IxEthDBNPEAdaptor.c deleted file mode 100644 index 112a46c998..0000000000 --- a/cpu/ixp/npe/IxEthDBNPEAdaptor.c +++ /dev/null @@ -1,719 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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 diff --git a/cpu/ixp/npe/IxEthDBPortUpdate.c b/cpu/ixp/npe/IxEthDBPortUpdate.c deleted file mode 100644 index cdf114bfc4..0000000000 --- a/cpu/ixp/npe/IxEthDBPortUpdate.c +++ /dev/null @@ -1,740 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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 route balanced - * not perfectly balanced. 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; -} - diff --git a/cpu/ixp/npe/IxEthDBReports.c b/cpu/ixp/npe/IxEthDBReports.c deleted file mode 100644 index 9c7ae1cc6a..0000000000 --- a/cpu/ixp/npe/IxEthDBReports.c +++ /dev/null @@ -1,652 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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; -} - diff --git a/cpu/ixp/npe/IxEthDBSearch.c b/cpu/ixp/npe/IxEthDBSearch.c deleted file mode 100644 index 4a10878b68..0000000000 --- a/cpu/ixp/npe/IxEthDBSearch.c +++ /dev/null @@ -1,327 +0,0 @@ -/** - * @file IxEthDBSearch.c - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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; -} diff --git a/cpu/ixp/npe/IxEthDBSpanningTree.c b/cpu/ixp/npe/IxEthDBSpanningTree.c deleted file mode 100644 index 6d9fd6ec18..0000000000 --- a/cpu/ixp/npe/IxEthDBSpanningTree.c +++ /dev/null @@ -1,107 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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; -} diff --git a/cpu/ixp/npe/IxEthDBUtil.c b/cpu/ixp/npe/IxEthDBUtil.c deleted file mode 100644 index e708bf1bce..0000000000 --- a/cpu/ixp/npe/IxEthDBUtil.c +++ /dev/null @@ -1,120 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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; -} diff --git a/cpu/ixp/npe/IxEthDBVlan.c b/cpu/ixp/npe/IxEthDBVlan.c deleted file mode 100644 index e2efb9b339..0000000000 --- a/cpu/ixp/npe/IxEthDBVlan.c +++ /dev/null @@ -1,1179 +0,0 @@ -/** - * @file IxEthDBVlan.c - * - * @brief Implementation of the VLAN API - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#include "IxEthDB.h" -#include "IxEthDB_p.h" - -/* forward prototypes */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBUpdateTrafficClass(IxEthDBPortId portID, UINT32 classIndex); -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBVlanTableGet(IxEthDBPortId portID, IxEthDBVlanSet portVlanTable, IxEthDBVlanSet vlanSet); - -/* contants used by various functions as "action" parameter */ -#define ADD_VLAN (0x1) -#define REMOVE_VLAN (0x2) - -/** - * @brief adds or removes a VLAN from a VLAN set - * - * @param vlanID VLAN ID to add or remove - * @param table VLAN set to add into or remove from - * @param action ADD_VLAN or REMOVE_VLAN - * - * @internal - */ -IX_ETH_DB_PRIVATE -void ixEthDBLocalVlanMembershipChange(UINT32 vlanID, IxEthDBVlanSet table, UINT32 action) -{ - UINT32 setOffset; - - /* add/remove VID to membership table */ - setOffset = VLAN_SET_OFFSET(vlanID); /* we need 9 bits to index the 512 byte membership array */ - - if (action == ADD_VLAN) - { - table[setOffset] |= 1 << VLAN_SET_MASK(vlanID); - } - else if (action == REMOVE_VLAN) - { - table[setOffset] &= ~(1 << VLAN_SET_MASK(vlanID)); - } -} - -/** - * @brief updates a set of 8 VLANs in an NPE - * - * @param portID ID of the port - * @param setOffset offset of the 8 VLANs - * - * This function updates the VLAN membership table - * and Transmit Tagging Info table for 8 consecutive - * VLAN IDs indexed by setOffset. - * - * For example, a setOffset of 0 indexes VLAN IDs 0 - * through 7, 1 indexes VLAN IDs 8 through 9 etc. - * - * @return IX_ETH_DB_SUCCESS if the operation completed - * successfully or an appropriate error message otherwise - * - * @internal - */ -IX_ETH_DB_PRIVATE -IxEthDBStatus ixEthDBVlanTableEntryUpdate(IxEthDBPortId portID, UINT32 setOffset) -{ - PortInfo *portInfo = &ixEthDBPortInfo[portID]; - IxNpeMhMessage message; - IX_STATUS result; - - FILL_SETPORTVLANTABLEENTRY_MSG(message, IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), - 2 * setOffset, - portInfo->vlanMembership[setOffset], - portInfo->transmitTaggingInfo[setOffset]); - - IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); - - return result; -} - -/** - * @brief updates a VLAN range in an NPE - * - * @param portID ID of the port - * - * This function is similar to @ref ixEthDBVlanTableEntryUpdate - * except that it can update more than one VLAN set (up to - * the entire VLAN membership and TTI tables if the offset is 0 - * and length is sizeof (IxEthDBVlanSet) (512 bytes). - * - * Updating the NPE via this method is slower as it requires - * a memory copy from SDRAM, hence it is recommended that the - * ixEthDBVlanTableEntryUpdate function is used where possible. - * - * @return IX_ETH_DB_SUCCESS if the operation completed - * successfully or an appropriate error message otherwise - * - * @internal - */ -IX_ETH_DB_PRIVATE -IxEthDBStatus ixEthDBVlanTableRangeUpdate(IxEthDBPortId portID) -{ - PortInfo *portInfo = &ixEthDBPortInfo[portID]; - UINT8 *vlanUpdateZone = (UINT8 *) portInfo->updateMethod.vlanUpdateZone; - IxNpeMhMessage message; - UINT32 setIndex; - IX_STATUS result; - - /* copy membership info and transmit tagging into into exchange area */ - for (setIndex = 0 ; setIndex < sizeof (portInfo->vlanMembership) ; setIndex++) - { - /* membership and TTI data are interleaved */ - vlanUpdateZone[setIndex * 2] = portInfo->vlanMembership[setIndex]; - vlanUpdateZone[setIndex * 2 + 1] = portInfo->transmitTaggingInfo[setIndex]; - } - - IX_OSAL_CACHE_FLUSH(vlanUpdateZone, FULL_VLAN_BYTE_SIZE); - - /* build NPE message */ - FILL_SETPORTVLANTABLERANGE_MSG(message, IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), 0, 0, - IX_OSAL_MMU_VIRT_TO_PHYS(vlanUpdateZone)); - - /* send message */ - IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); - - return result; -} - -/** - * @brief adds or removes a VLAN from a port's VLAN membership table - * or Transmit Tagging Information table - * - * @param portID ID of the port - * @param vlanID VLAN ID to add or remove - * @param table to add or remove from - * @param action ADD_VLAN or REMOVE_VLAN - * - * @return IX_ETH_DB_SUCCESS if the operation completed - * successfully or an appropriate error message otherwise - * - * @internal - */ -IX_ETH_DB_PRIVATE -IxEthDBStatus ixEthDBPortVlanMembershipChange(IxEthDBPortId portID, IxEthDBVlanId vlanID, IxEthDBVlanSet table, UINT32 action) -{ - /* change VLAN in local membership table */ - ixEthDBLocalVlanMembershipChange(vlanID, table, action); - - /* send updated entry to NPE */ - return ixEthDBVlanTableEntryUpdate(portID, VLAN_SET_OFFSET(vlanID)); -} - -/** - * @brief sets the default port VLAN tag (the lower 3 bytes are the PVID) - * - * @param portID ID of the port - * @param vlanTag port VLAN tag (802.1Q tag) - * - * 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 ixEthDBPortVlanTagSet(IxEthDBPortId portID, IxEthDBVlanTag vlanTag) -{ - IxNpeMhMessage message; - IX_STATUS result; - - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_VLAN_TAG(vlanTag); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - /* add VLAN ID to local membership table */ - ixEthDBPortVlanMembershipChange(portID, - vlanTag & IX_ETH_DB_802_1Q_VLAN_MASK, - ixEthDBPortInfo[portID].vlanMembership, - ADD_VLAN); - - /* set tag in portInfo */ - ixEthDBPortInfo[portID].vlanTag = vlanTag; - - /* build VLAN_SetDefaultRxVID message */ - FILL_SETDEFAULTRXVID_MSG(message, - IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), - IX_IEEE802_1Q_VLAN_TPID, - vlanTag); - - IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); - - return result; -} - -/** - * @brief retrieves the default port VLAN tag (the lower 3 bytes are the PVID) - * - * @param portID ID of the port - * @param vlanTag address to write the port VLAN tag (802.1Q tag) 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 ixEthDBPortVlanTagGet(IxEthDBPortId portID, IxEthDBVlanTag *vlanTag) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - IX_ETH_DB_CHECK_REFERENCE(vlanTag); - - *vlanTag = ixEthDBPortInfo[portID].vlanTag; - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief sets the VLAN tag (the lower 3 bytes are the PVID) of a - * database filtering record - * - * @param portID ID of the port - * @param vlanTag VLAN tag (802.1Q tag) - * - * Important: filtering records are automatically converted to - * IX_ETH_DB_FILTERING_VLAN record when added a VLAN tag. - * - * 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 ixEthDBVlanTagSet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag vlanTag) -{ - HashNode *searchResult; - MacDescriptor *descriptor; - - IX_ETH_DB_CHECK_REFERENCE(macAddr); - - IX_ETH_DB_CHECK_VLAN_TAG(vlanTag); - - searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS); - - if (searchResult == NULL) - { - return IX_ETH_DB_NO_SUCH_ADDR; - } - - descriptor = (MacDescriptor *) searchResult->data; - - /* set record type to VLAN if not already set */ - descriptor->type = IX_ETH_DB_FILTERING_VLAN_RECORD; - - /* add vlan tag */ - descriptor->recordData.filteringVlanData.ieee802_1qTag = vlanTag; - - /* transaction completed */ - ixEthDBReleaseHashNode(searchResult); - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief retrieves the VLAN tag (the lower 3 bytes are the PVID) from a - * database VLAN filtering record - * - * @param portID ID of the port - * @param vlanTag address to write the VLAN tag (802.1Q tag) 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 ixEthDBVlanTagGet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag *vlanTag) -{ - HashNode *searchResult; - MacDescriptor *descriptor; - - IX_ETH_DB_CHECK_REFERENCE(macAddr); - - IX_ETH_DB_CHECK_REFERENCE(vlanTag); - - searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_FILTERING_VLAN_RECORD); - - if (searchResult == NULL) - { - return IX_ETH_DB_NO_SUCH_ADDR; - } - - descriptor = (MacDescriptor *) searchResult->data; - - /* get vlan tag */ - *vlanTag = descriptor->recordData.filteringVlanData.ieee802_1qTag; - - /* transaction completed */ - ixEthDBReleaseHashNode(searchResult); - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief adds a VLAN to a port's VLAN membership table - * - * @param portID ID of the port - * @param vlanID VLAN ID to add - * - * 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 ixEthDBPortVlanMembershipAdd(IxEthDBPortId portID, IxEthDBVlanId vlanID) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_VLAN_ID(vlanID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - return ixEthDBPortVlanMembershipChange(portID, vlanID, ixEthDBPortInfo[portID].vlanMembership, ADD_VLAN); -} - -/** - * @brief removes a VLAN from a port's VLAN membership table - * - * @param portID ID of the port - * @param vlanID VLAN ID 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 ixEthDBPortVlanMembershipRemove(IxEthDBPortId portID, IxEthDBVlanId vlanID) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - IX_ETH_DB_CHECK_VLAN_ID(vlanID); - - /* for safety isolate only the VLAN ID in the tag (the lower 12 bits) */ - vlanID = vlanID & IX_ETH_DB_802_1Q_VLAN_MASK; - - /* check we're not asked to remove the default port VID */ - if (vlanID == IX_ETH_DB_GET_VLAN_ID(ixEthDBPortInfo[portID].vlanTag)) - { - return IX_ETH_DB_NO_PERMISSION; - } - - return ixEthDBPortVlanMembershipChange(portID, vlanID, ixEthDBPortInfo[portID].vlanMembership, REMOVE_VLAN); -} - -/** - * @brief adds or removes a VLAN range from a port's - * VLAN membership table or TTI table - * - * @param portID ID of the port - * @param vlanIDMin start of the VLAN range - * @param vlanIDMax end of the VLAN range - * @param table VLAN set to add or remove from - * @param action ADD_VLAN or REMOVE_VLAN - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - * - * @internal - */ -IX_ETH_DB_PRIVATE -IxEthDBStatus ixEthDBPortVlanMembershipRangeChange(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax, IxEthDBVlanSet table, UINT32 action) -{ - UINT32 setOffsetMin, setOffsetMax; - - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - IX_ETH_DB_CHECK_VLAN_ID(vlanIDMin); - - IX_ETH_DB_CHECK_VLAN_ID(vlanIDMax); - - /* for safety isolate only the VLAN ID in the tags (the lower 12 bits) */ - vlanIDMin = vlanIDMin & IX_ETH_DB_802_1Q_VLAN_MASK; - vlanIDMax = vlanIDMax & IX_ETH_DB_802_1Q_VLAN_MASK; - - /* is this a range? */ - if (vlanIDMax < vlanIDMin) - { - return IX_ETH_DB_INVALID_VLAN; - } - - /* check that we're not specifically asked to remove the default port VID */ - if (action == REMOVE_VLAN && vlanIDMax == vlanIDMin && IX_ETH_DB_GET_VLAN_ID(ixEthDBPortInfo[portID].vlanTag) == vlanIDMin) - { - return IX_ETH_DB_NO_PERMISSION; - } - - /* compute set offsets */ - setOffsetMin = VLAN_SET_OFFSET(vlanIDMin); - setOffsetMax = VLAN_SET_OFFSET(vlanIDMax); - - /* change VLAN range */ - for (; vlanIDMin <= vlanIDMax ; vlanIDMin++) - { - /* change vlan in local membership table */ - ixEthDBLocalVlanMembershipChange(vlanIDMin, table, action); - } - - /* if the range is within one set (max 8 VLANs in one table byte) we can just update that entry in the NPE */ - if (setOffsetMin == setOffsetMax) - { - /* send updated entry to NPE */ - return ixEthDBVlanTableEntryUpdate(portID, setOffsetMin); - } - else - { - /* update a zone of the membership/transmit tag info table */ - return ixEthDBVlanTableRangeUpdate(portID); - } -} - -/** - * @brief adds a VLAN range to a port's VLAN membership table - * - * @param portID ID of the port - * @param vlanIDMin start of the VLAN range - * @param vlanIDMax end of the VLAN range - * - * 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 ixEthDBPortVlanMembershipRangeAdd(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - return ixEthDBPortVlanMembershipRangeChange(portID, vlanIDMin, vlanIDMax, ixEthDBPortInfo[portID].vlanMembership, ADD_VLAN); -} - -/** - * @brief removes a VLAN range from a port's VLAN membership table - * - * @param portID ID of the port - * @param vlanIDMin start of the VLAN range - * @param vlanIDMax end of the VLAN range - * - * 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 ixEthDBPortVlanMembershipRangeRemove(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - return ixEthDBPortVlanMembershipRangeChange(portID, vlanIDMin, vlanIDMax, ixEthDBPortInfo[portID].vlanMembership, REMOVE_VLAN); -} - -/** - * @brief sets a port's VLAN membership table or TTI table and - * updates the NPE VLAN configuration - * - * @param portID ID of the port - * @param portVlanTable port VLAN table to set - * @param vlanSet new set contents - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - * - * @internal - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortVlanTableSet(IxEthDBPortId portID, IxEthDBVlanSet portVlanTable, IxEthDBVlanSet vlanSet) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - IX_ETH_DB_CHECK_REFERENCE(vlanSet); - - memcpy(portVlanTable, vlanSet, sizeof (IxEthDBVlanSet)); - - return ixEthDBVlanTableRangeUpdate(portID); -} - -/** - * @brief retireves a port's VLAN membership table or TTI table - * - * @param portID ID of the port - * @param portVlanTable port VLAN table to retrieve - * @param vlanSet address to - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - * - * @internal - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBVlanTableGet(IxEthDBPortId portID, IxEthDBVlanSet portVlanTable, IxEthDBVlanSet vlanSet) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - IX_ETH_DB_CHECK_REFERENCE(vlanSet); - - memcpy(vlanSet, portVlanTable, sizeof (IxEthDBVlanSet)); - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief sets a port's VLAN membership table - * - * @param portID ID of the port - * @param vlanSet new VLAN membership table - * - * 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 ixEthDBPortVlanMembershipSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet) -{ - IxEthDBVlanId vlanID; - - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_REFERENCE(vlanSet); - - /* set the bit corresponding to the PVID just in case */ - vlanID = IX_ETH_DB_GET_VLAN_ID(ixEthDBPortInfo[portID].vlanTag); - vlanSet[VLAN_SET_OFFSET(vlanID)] |= 1 << VLAN_SET_MASK(vlanID); - - return ixEthDBPortVlanTableSet(portID, ixEthDBPortInfo[portID].vlanMembership, vlanSet); -} - -/** - * @brief retrieves a port's VLAN membership table - * - * @param portID ID of the port - * @param vlanSet location to store the port's VLAN membership table - * - * 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 ixEthDBPortVlanMembershipGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - return ixEthDBVlanTableGet(portID, ixEthDBPortInfo[portID].vlanMembership, vlanSet); -} - -/** - * @brief enables or disables Egress tagging for one VLAN ID - * - * @param portID ID of the port - * @param vlanID VLAN ID to enable or disable Egress tagging on - * @param enabled TRUE to enable and FALSE to disable tagging - * - * 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 ixEthDBEgressVlanEntryTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL enabled) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_VLAN_ID(vlanID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - return ixEthDBPortVlanMembershipChange(portID, vlanID, ixEthDBPortInfo[portID].transmitTaggingInfo, enabled? ADD_VLAN : REMOVE_VLAN); -} - -/** - * @brief retrieves the Egress tagging status for one VLAN ID - * - * @param portID ID of the port - * @param vlanID VLAN ID to retrieve the tagging status for - * @param enabled location to store the tagging status - * (TRUE - tagging enabled, FALSE - tagging disabled) - * - * 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 ixEthDBEgressVlanEntryTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL *enabled) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - IX_ETH_DB_CHECK_REFERENCE(enabled); - - IX_ETH_DB_CHECK_VLAN_ID(vlanID); - - *enabled = ((ixEthDBPortInfo[portID].transmitTaggingInfo[VLAN_SET_OFFSET(vlanID)] & (1 << VLAN_SET_MASK(vlanID))) != 0); - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief enables or disables Egress VLAN tagging for a VLAN range - * - * @param portID ID of the port - * @param vlanIDMin start of VLAN range - * @param vlanIDMax end of VLAN range - * @param enabled TRUE to enable or FALSE to disable VLAN tagging - * - * 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 ixEthDBEgressVlanRangeTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax, BOOL enabled) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - return ixEthDBPortVlanMembershipRangeChange(portID, vlanIDMin, vlanIDMax, ixEthDBPortInfo[portID].transmitTaggingInfo, enabled? ADD_VLAN : REMOVE_VLAN); -} - -/** - * @brief sets the Egress VLAN tagging table (the Transmit Tagging - * Information table) - * - * @param portID ID of the port - * @param vlanSet new TTI table - * - * 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 ixEthDBEgressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet) -{ - IxEthDBVlanId vlanID; - - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_REFERENCE(vlanSet); - - /* set the PVID bit just in case */ - vlanID = IX_ETH_DB_GET_VLAN_ID(ixEthDBPortInfo[portID].vlanTag); - vlanSet[VLAN_SET_OFFSET(vlanID)] |= 1 << VLAN_SET_MASK(vlanID); - - return ixEthDBPortVlanTableSet(portID, ixEthDBPortInfo[portID].transmitTaggingInfo, vlanSet); -} - -/** - * @brief retrieves the Egress VLAN tagging table (the Transmit - * Tagging Information table) - * - * @param portID ID of the port - * @param vlanSet location to store the port's TTI table - * - * 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 ixEthDBEgressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - return ixEthDBVlanTableGet(portID, ixEthDBPortInfo[portID].transmitTaggingInfo, vlanSet); -} - -/** - * @brief sends the NPE the updated frame filter and default - * Ingress tagging - * - * @param portID ID of the port - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - * - * @internal - */ -IX_ETH_DB_PRIVATE -IxEthDBStatus ixEthDBIngressVlanModeUpdate(IxEthDBPortId portID) -{ - PortInfo *portInfo = &ixEthDBPortInfo[portID]; - IxNpeMhMessage message; - IX_STATUS result; - - FILL_SETRXTAGMODE_MSG(message, portID, portInfo->npeFrameFilter, portInfo->npeTaggingAction); - IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); - - return result; -} - -/** - * @brief sets the default Ingress tagging behavior - * - * @param portID ID of the port - * @param taggingAction default tagging behavior - * - * 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 ixEthDBIngressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBTaggingAction taggingAction) -{ - PortInfo *portInfo; - - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - portInfo = &ixEthDBPortInfo[portID]; - - if (taggingAction == IX_ETH_DB_PASS_THROUGH) - { - portInfo->npeTaggingAction = 0x00; - } - else if (taggingAction == IX_ETH_DB_ADD_TAG) - { - portInfo->npeTaggingAction = 0x02; - } - else if (taggingAction == IX_ETH_DB_REMOVE_TAG) - { - portInfo->npeTaggingAction = 0x01; - } - else - { - return IX_ETH_DB_INVALID_ARG; - } - - portInfo->taggingAction = taggingAction; - - return ixEthDBIngressVlanModeUpdate(portID); -} - -/** - * @brief retrieves the default Ingress tagging behavior of a port - * - * @param portID ID of the port - * @param taggingAction location to save the default tagging behavior - * - * 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 ixEthDBIngressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBTaggingAction *taggingAction) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - IX_ETH_DB_CHECK_REFERENCE(taggingAction); - - *taggingAction = ixEthDBPortInfo[portID].taggingAction; - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief sets the Ingress acceptable frame type filter - * - * @param portID ID of the port - * @param frameFilter acceptable frame type filter - * - * 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 ixEthDBAcceptableFrameTypeSet(IxEthDBPortId portID, IxEthDBFrameFilter frameFilter) -{ - PortInfo *portInfo; - IxEthDBStatus result = IX_ETH_DB_SUCCESS; - - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - /* check parameter range - the ORed value of the valid values is 0x7 - a value having extra bits is invalid */ - if ((frameFilter | 0x7) != 0x7 || frameFilter == 0) - { - return IX_ETH_DB_INVALID_ARG; - } - - portInfo = &ixEthDBPortInfo[portID]; - - portInfo->frameFilter = frameFilter; - portInfo->npeFrameFilter = 0; /* allow all by default */ - - /* if accepting priority tagged but not all VLAN tagged - set the membership table to contain only VLAN ID 0 - hence remove vlans 1-4094 and add VLAN ID 0 */ - if (((frameFilter & IX_ETH_DB_PRIORITY_TAGGED_FRAMES) != 0) - && ((frameFilter & IX_ETH_DB_VLAN_TAGGED_FRAMES) == 0)) - { - result = ixEthDBPortVlanMembershipRangeChange(portID, - 1, IX_ETH_DB_802_1Q_MAX_VLAN_ID, portInfo->vlanMembership, REMOVE_VLAN); - - if (result == IX_ETH_DB_SUCCESS) - { - ixEthDBLocalVlanMembershipChange(0, portInfo->vlanMembership, ADD_VLAN); - result = ixEthDBVlanTableRangeUpdate(portID); - } - } - - /* untagged only? */ - if (frameFilter == IX_ETH_DB_UNTAGGED_FRAMES) - { - portInfo->npeFrameFilter = 0x01; - } - - /* tagged only? */ - if ((frameFilter & IX_ETH_DB_UNTAGGED_FRAMES) == 0) - { - portInfo->npeFrameFilter = 0x02; - } - - if (result == IX_ETH_DB_SUCCESS) - { - result = ixEthDBIngressVlanModeUpdate(portID); - } - - return result; -} - -/** - * @brief retrieves the acceptable frame type filter for a port - * - * @param portID ID of the port - * @param frameFilter location to store the frame filter - * - * 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 ixEthDBAcceptableFrameTypeGet(IxEthDBPortId portID, IxEthDBFrameFilter *frameFilter) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - IX_ETH_DB_CHECK_REFERENCE(frameFilter); - - *frameFilter = ixEthDBPortInfo[portID].frameFilter; - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief sends an NPE the updated configuration related - * to one QoS priority (associated traffic class and AQM mapping) - * - * @param portID ID of the port - * @param classIndex QoS priority (traffic class index) - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - * - * @internal - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBUpdateTrafficClass(IxEthDBPortId portID, UINT32 classIndex) -{ - IxNpeMhMessage message; - IX_STATUS result; - - UINT32 trafficClass = ixEthDBPortInfo[portID].priorityTable[classIndex]; - UINT32 aqmQueue = ixEthDBPortInfo[portID].ixEthDBTrafficClassAQMAssignments[trafficClass]; - - FILL_SETRXQOSENTRY(message, IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), classIndex, trafficClass, aqmQueue); - - IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); - - return result; -} - -/** - * @brief sets the priority mapping table - * - * @param portID ID of the port - * @param priorityTable new priority mapping table - * - * 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 ixEthDBPriorityMappingTableSet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable) -{ - UINT32 classIndex; - - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - IX_ETH_DB_CHECK_REFERENCE(priorityTable); - - for (classIndex = 0 ; classIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; classIndex++) - { - /* check range */ - if (priorityTable[classIndex] >= ixEthDBPortInfo[portID].ixEthDBTrafficClassCount) - { - return IX_ETH_DB_INVALID_PRIORITY; - } - } - - /* set new traffic classes */ - for (classIndex = 0 ; classIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; classIndex++) - { - ixEthDBPortInfo[portID].priorityTable[classIndex] = priorityTable[classIndex]; - - if (ixEthDBUpdateTrafficClass(portID, classIndex) != IX_ETH_DB_SUCCESS) - { - return IX_ETH_DB_FAIL; - } - } - - return IX_ETH_DB_SUCCESS; - } - -/** - * @brief retrieves a port's priority mapping table - * - * @param portID ID of the port - * @param priorityTable location to store the priority table - * - * 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 ixEthDBPriorityMappingTableGet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - IX_ETH_DB_CHECK_REFERENCE(priorityTable); - - memcpy(priorityTable, ixEthDBPortInfo[portID].priorityTable, sizeof (IxEthDBPriorityTable)); - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief sets one QoS priority => traffic class mapping - * - * @param portID ID of the port - * @param userPriority QoS (user) priority - * @param trafficClass associated traffic class - * - * 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 ixEthDBPriorityMappingClassSet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority trafficClass) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - /* check ranges for userPriority and trafficClass */ - if (userPriority >= IX_IEEE802_1Q_QOS_PRIORITY_COUNT || trafficClass >= ixEthDBPortInfo[portID].ixEthDBTrafficClassCount) - { - return IX_ETH_DB_INVALID_PRIORITY; - } - - ixEthDBPortInfo[portID].priorityTable[userPriority] = trafficClass; - - return ixEthDBUpdateTrafficClass(portID, userPriority); -} - -/** - * @brief retrieves one QoS priority => traffic class mapping - * - * @param portID ID of the port - * @param userPriority QoS (user) priority - * @param trafficClass location to store the associated traffic class - * - * 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 ixEthDBPriorityMappingClassGet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority *trafficClass) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - IX_ETH_DB_CHECK_REFERENCE(trafficClass); - - /* check userPriority range */ - if (userPriority >= IX_IEEE802_1Q_QOS_PRIORITY_COUNT) - { - return IX_ETH_DB_INVALID_PRIORITY; - } - - *trafficClass = ixEthDBPortInfo[portID].priorityTable[userPriority]; - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief enables or disables the source port extraction - * from the VLAN TPID field - * - * @param portID ID of the port - * @param enable TRUE to enable or FALSE to disable - * - * 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 ixEthDBVlanPortExtractionEnable(IxEthDBPortId portID, BOOL enable) -{ - 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_VLAN_QOS); - - FILL_SETPORTIDEXTRACTIONMODE(message, portID, enable); - - IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); - - return result; -} diff --git a/cpu/ixp/npe/IxEthDBWiFi.c b/cpu/ixp/npe/IxEthDBWiFi.c deleted file mode 100644 index 0a6043f364..0000000000 --- a/cpu/ixp/npe/IxEthDBWiFi.c +++ /dev/null @@ -1,480 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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; -} diff --git a/cpu/ixp/npe/IxEthMii.c b/cpu/ixp/npe/IxEthMii.c deleted file mode 100644 index 4d92f17eef..0000000000 --- a/cpu/ixp/npe/IxEthMii.c +++ /dev/null @@ -1,497 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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 0 && i= 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; -} - diff --git a/cpu/ixp/npe/IxFeatureCtrl.c b/cpu/ixp/npe/IxFeatureCtrl.c deleted file mode 100644 index 2e196a19aa..0000000000 --- a/cpu/ixp/npe/IxFeatureCtrl.c +++ /dev/null @@ -1,422 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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_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 -} diff --git a/cpu/ixp/npe/IxNpeDl.c b/cpu/ixp/npe/IxNpeDl.c deleted file mode 100644 index 3738337538..0000000000 --- a/cpu/ixp/npe/IxNpeDl.c +++ /dev/null @@ -1,940 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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; - } -} diff --git a/cpu/ixp/npe/IxNpeDlImageMgr.c b/cpu/ixp/npe/IxNpeDlImageMgr.c deleted file mode 100644 index 9bcdc9c0d8..0000000000 --- a/cpu/ixp/npe/IxNpeDlImageMgr.c +++ /dev/null @@ -1,687 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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; -} - diff --git a/cpu/ixp/npe/IxNpeDlNpeMgr.c b/cpu/ixp/npe/IxNpeDlNpeMgr.c deleted file mode 100644 index f5a4c5f508..0000000000 --- a/cpu/ixp/npe/IxNpeDlNpeMgr.c +++ /dev/null @@ -1,936 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- -*/ - - -/* - * Put the user defined include files required. - */ - - -/* - * 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 (); -} diff --git a/cpu/ixp/npe/IxNpeDlNpeMgrUtils.c b/cpu/ixp/npe/IxNpeDlNpeMgrUtils.c deleted file mode 100644 index 18cac50208..0000000000 --- a/cpu/ixp/npe/IxNpeDlNpeMgrUtils.c +++ /dev/null @@ -1,806 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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; -} diff --git a/cpu/ixp/npe/IxNpeMh.c b/cpu/ixp/npe/IxNpeMh.c deleted file mode 100644 index 8703def8bc..0000000000 --- a/cpu/ixp/npe/IxNpeMh.c +++ /dev/null @@ -1,582 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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; -} diff --git a/cpu/ixp/npe/IxNpeMhConfig.c b/cpu/ixp/npe/IxNpeMhConfig.c deleted file mode 100644 index 50c8f21138..0000000000 --- a/cpu/ixp/npe/IxNpeMhConfig.c +++ /dev/null @@ -1,608 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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; -} - - diff --git a/cpu/ixp/npe/IxNpeMhReceive.c b/cpu/ixp/npe/IxNpeMhReceive.c deleted file mode 100644 index 57c8be30e5..0000000000 --- a/cpu/ixp/npe/IxNpeMhReceive.c +++ /dev/null @@ -1,320 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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; -} diff --git a/cpu/ixp/npe/IxNpeMhSend.c b/cpu/ixp/npe/IxNpeMhSend.c deleted file mode 100644 index 318913ac84..0000000000 --- a/cpu/ixp/npe/IxNpeMhSend.c +++ /dev/null @@ -1,307 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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; -} diff --git a/cpu/ixp/npe/IxNpeMhSolicitedCbMgr.c b/cpu/ixp/npe/IxNpeMhSolicitedCbMgr.c deleted file mode 100644 index 8e083a63bf..0000000000 --- a/cpu/ixp/npe/IxNpeMhSolicitedCbMgr.c +++ /dev/null @@ -1,358 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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; -} diff --git a/cpu/ixp/npe/IxNpeMhUnsolicitedCbMgr.c b/cpu/ixp/npe/IxNpeMhUnsolicitedCbMgr.c deleted file mode 100644 index d37f9f9306..0000000000 --- a/cpu/ixp/npe/IxNpeMhUnsolicitedCbMgr.c +++ /dev/null @@ -1,246 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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; -} diff --git a/cpu/ixp/npe/IxOsalBufferMgt.c b/cpu/ixp/npe/IxOsalBufferMgt.c deleted file mode 100644 index fa8db477af..0000000000 --- a/cpu/ixp/npe/IxOsalBufferMgt.c +++ /dev/null @@ -1,800 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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 */ diff --git a/cpu/ixp/npe/IxOsalIoMem.c b/cpu/ixp/npe/IxOsalIoMem.c deleted file mode 100644 index 34df92bf79..0000000000 --- a/cpu/ixp/npe/IxOsalIoMem.c +++ /dev/null @@ -1,332 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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 = - sizeof (ixOsalGlobalMemoryMap) / sizeof (IxOsalMemoryMap); - - 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); - } -} diff --git a/cpu/ixp/npe/IxOsalOsCacheMMU.c b/cpu/ixp/npe/IxOsalOsCacheMMU.c deleted file mode 100644 index 3db1a70da9..0000000000 --- a/cpu/ixp/npe/IxOsalOsCacheMMU.c +++ /dev/null @@ -1,67 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#include "IxOsal.h" - -#include - -/* - * 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); -} diff --git a/cpu/ixp/npe/IxOsalOsMsgQ.c b/cpu/ixp/npe/IxOsalOsMsgQ.c deleted file mode 100644 index 45a5c68b16..0000000000 --- a/cpu/ixp/npe/IxOsalOsMsgQ.c +++ /dev/null @@ -1,79 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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; -} - diff --git a/cpu/ixp/npe/IxOsalOsSemaphore.c b/cpu/ixp/npe/IxOsalOsSemaphore.c deleted file mode 100644 index 443aefd4fc..0000000000 --- a/cpu/ixp/npe/IxOsalOsSemaphore.c +++ /dev/null @@ -1,233 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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); -} diff --git a/cpu/ixp/npe/IxOsalOsServices.c b/cpu/ixp/npe/IxOsalOsServices.c deleted file mode 100644 index e18c6c4c1e..0000000000 --- a/cpu/ixp/npe/IxOsalOsServices.c +++ /dev/null @@ -1,251 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#include -#include -#include "IxOsal.h" -#include -#include -#include -#include -#include - -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)); -} diff --git a/cpu/ixp/npe/IxOsalOsThread.c b/cpu/ixp/npe/IxOsalOsThread.c deleted file mode 100644 index e6a4967fcd..0000000000 --- a/cpu/ixp/npe/IxOsalOsThread.c +++ /dev/null @@ -1,98 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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; -} diff --git a/cpu/ixp/npe/IxQMgrAqmIf.c b/cpu/ixp/npe/IxQMgrAqmIf.c deleted file mode 100644 index 738651322c..0000000000 --- a/cpu/ixp/npe/IxQMgrAqmIf.c +++ /dev/null @@ -1,963 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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_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++; - } -} - diff --git a/cpu/ixp/npe/IxQMgrDispatcher.c b/cpu/ixp/npe/IxQMgrDispatcher.c deleted file mode 100644 index 09f69ce322..0000000000 --- a/cpu/ixp/npe/IxQMgrDispatcher.c +++ /dev/null @@ -1,1347 +0,0 @@ -/** - * @file IxQMgrDispatcher.c - * - * @author Intel Corporation - * @date 20-Dec-2001 - * - * @brief This file contains the implementation of the Dispatcher sub component - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- -*/ - -/* - * User defined include files. - */ -#include "IxQMgr.h" -#include "IxQMgrAqmIf_p.h" -#include "IxQMgrQCfg_p.h" -#include "IxQMgrDispatcher_p.h" -#include "IxQMgrLog_p.h" -#include "IxQMgrDefines_p.h" -#include "IxFeatureCtrl.h" -#include "IxOsal.h" - - - -/* - * #defines and macros used in this file. - */ - - -/* - * This constant is used to indicate the number of priority levels supported - */ -#define IX_QMGR_NUM_PRIORITY_LEVELS 3 - -/* - * This constant is used to set the size of the array of status words - */ -#define MAX_Q_STATUS_WORDS 4 - -/* - * This macro is used to check if a given priority is valid - */ -#define IX_QMGR_DISPATCHER_PRIORITY_CHECK(priority) \ -(((priority) >= IX_QMGR_Q_PRIORITY_0) && ((priority) <= IX_QMGR_Q_PRIORITY_2)) - -/* - * This macto is used to check that a given interrupt source is valid - */ -#define IX_QMGR_DISPATCHER_SOURCE_ID_CHECK(srcSel) \ -(((srcSel) >= IX_QMGR_Q_SOURCE_ID_E) && ((srcSel) <= IX_QMGR_Q_SOURCE_ID_NOT_F)) - -/* - * Number of times a dummy callback is called before logging a trace - * message - */ -#define LOG_THROTTLE_COUNT 1000000 - -/* Priority tables limits */ -#define IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX (0) -#define IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX (16) -#define IX_QMGR_MAX_LOW_QUE_PRIORITY_TABLE_INDEX (31) -#define IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX (32) -#define IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX (48) -#define IX_QMGR_MAX_UPP_QUE_PRIORITY_TABLE_INDEX (63) - -/* - * This macro is used to check if a given callback type is valid - */ -#define IX_QMGR_DISPATCHER_CALLBACK_TYPE_CHECK(type) \ - (((type) >= IX_QMGR_TYPE_REALTIME_OTHER) && \ - ((type) <= IX_QMGR_TYPE_REALTIME_SPORADIC)) - -/* - * define max index in lower queue to use in loops - */ -#define IX_QMGR_MAX_LOW_QUE_TABLE_INDEX (31) - -/* - * Typedefs whose scope is limited to this file. - */ - -/* - * Information on a queue needed by the Dispatcher - */ -typedef struct -{ - IxQMgrCallback callback; /* Notification callback */ - IxQMgrCallbackId callbackId; /* Notification callback identifier */ - unsigned dummyCallbackCount; /* Number of times runs of dummy callback */ - IxQMgrPriority priority; /* Dispatch priority */ - unsigned int statusWordOffset; /* Offset to the status word to check */ - UINT32 statusMask; /* Status mask */ - UINT32 statusCheckValue; /* Status check value */ - UINT32 intRegCheckMask; /* Interrupt register check mask */ -} IxQMgrQInfo; - -/* - * Variable declarations global to this file. Externs are followed by - * statics. - */ - -/* - * Flag to keep record of what dispatcher set in featureCtrl when ixQMgrInit() - * is called. This is needed because it is possible that a client might - * change whether the live lock prevention dispatcher is used between - * calls to ixQMgrInit() and ixQMgrDispatcherLoopGet(). - */ -PRIVATE IX_STATUS ixQMgrOrigB0Dispatcher = IX_FEATURE_CTRL_COMPONENT_ENABLED; - -/* - * keep record of Q types - not in IxQMgrQInfo for performance as - * it is only used with ixQMgrDispatcherLoopRunB0LLP() - */ -PRIVATE IxQMgrType ixQMgrQTypes[IX_QMGR_MAX_NUM_QUEUES]; - -/* - * This array contains a list of queue identifiers ordered by priority. The table - * is split logically between queue identifiers 0-31 and 32-63. - */ -static IxQMgrQId priorityTable[IX_QMGR_MAX_NUM_QUEUES]; - -/* - * This flag indicates to the dispatcher that the priority table needs to be rebuilt. - */ -static BOOL rebuildTable = FALSE; - -/* Dispatcher statistics */ -static IxQMgrDispatcherStats dispatcherStats; - -/* Table of queue information */ -static IxQMgrQInfo dispatchQInfo[IX_QMGR_MAX_NUM_QUEUES]; - -/* Masks use to identify the first queues in the priority tables -* when comparing with the interrupt register -*/ -static unsigned int lowPriorityTableFirstHalfMask; -static unsigned int uppPriorityTableFirstHalfMask; - -/* - * Static function prototypes - */ - -/* - * This function is the default callback for all queues - */ -PRIVATE void -dummyCallback (IxQMgrQId qId, - IxQMgrCallbackId cbId); - -PRIVATE void -ixQMgrDispatcherReBuildPriorityTable (void); - -/* - * Function definitions. - */ -void -ixQMgrDispatcherInit (void) -{ - int i; - IxFeatureCtrlProductId productId = 0; - IxFeatureCtrlDeviceId deviceId = 0; - BOOL stickyIntSilicon = TRUE; - - /* Set default priorities */ - for (i=0; i< IX_QMGR_MAX_NUM_QUEUES; i++) - { - dispatchQInfo[i].callback = dummyCallback; - dispatchQInfo[i].callbackId = 0; - dispatchQInfo[i].dummyCallbackCount = 0; - dispatchQInfo[i].priority = IX_QMGR_Q_PRIORITY_2; - dispatchQInfo[i].statusWordOffset = 0; - dispatchQInfo[i].statusCheckValue = 0; - dispatchQInfo[i].statusMask = 0; - /* - * There are two interrupt registers, 32 bits each. One for the lower - * queues(0-31) and one for the upper queues(32-63). Therefore need to - * mod by 32 i.e the min upper queue identifier. - */ - dispatchQInfo[i].intRegCheckMask = (1<<(i%(IX_QMGR_MIN_QUEUPP_QID))); - - /* - * Set the Q types - will only be used with livelock - */ - ixQMgrQTypes[i] = IX_QMGR_TYPE_REALTIME_OTHER; - - /* Reset queue statistics */ - dispatcherStats.queueStats[i].callbackCnt = 0; - dispatcherStats.queueStats[i].priorityChangeCnt = 0; - dispatcherStats.queueStats[i].intNoCallbackCnt = 0; - dispatcherStats.queueStats[i].intLostCallbackCnt = 0; - dispatcherStats.queueStats[i].notificationEnabled = FALSE; - dispatcherStats.queueStats[i].srcSel = 0; - - } - - /* Priority table. Order the table from queue 0 to 63 */ - ixQMgrDispatcherReBuildPriorityTable(); - - /* Reset statistics */ - dispatcherStats.loopRunCnt = 0; - - /* Get the device ID for the underlying silicon */ - deviceId = ixFeatureCtrlDeviceRead(); - - /* Get the product ID for the underlying silicon */ - productId = ixFeatureCtrlProductIdRead(); - - /* - * Check featureCtrl to see if Livelock prevention is required - */ - ixQMgrOrigB0Dispatcher = ixFeatureCtrlSwConfigurationCheck( - IX_FEATURECTRL_ORIGB0_DISPATCHER); - - /* - * Check if the silicon supports the sticky interrupt feature. - * IF (IXP42X AND A0) -> No sticky interrupt feature supported - */ - if ((IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X == - (IX_FEATURE_CTRL_DEVICE_TYPE_MASK & deviceId)) && - (IX_FEATURE_CTRL_SILICON_TYPE_A0 == - (IX_FEATURE_CTRL_SILICON_STEPPING_MASK & productId))) - { - stickyIntSilicon = FALSE; - } - - /* - * IF user wants livelock prev option AND silicon supports sticky interrupt - * feature -> enable the sticky interrupt bit - */ - if ((IX_FEATURE_CTRL_SWCONFIG_DISABLED == ixQMgrOrigB0Dispatcher) && - stickyIntSilicon) - { - ixQMgrStickyInterruptRegEnable(); - } -} - -IX_STATUS -ixQMgrDispatcherPrioritySet (IxQMgrQId qId, - IxQMgrPriority priority) -{ - int ixQMgrLockKey; - - if (!ixQMgrQIsConfigured(qId)) - { - return IX_QMGR_Q_NOT_CONFIGURED; - } - - if (!IX_QMGR_DISPATCHER_PRIORITY_CHECK(priority)) - { - return IX_QMGR_Q_INVALID_PRIORITY; - } - - ixQMgrLockKey = ixOsalIrqLock(); - - /* Change priority */ - dispatchQInfo[qId].priority = priority; - /* Set flag */ - rebuildTable = TRUE; - - ixOsalIrqUnlock(ixQMgrLockKey); - -#ifndef NDEBUG - /* Update statistics */ - dispatcherStats.queueStats[qId].priorityChangeCnt++; -#endif - - return IX_SUCCESS; -} - -IX_STATUS -ixQMgrNotificationCallbackSet (IxQMgrQId qId, - IxQMgrCallback callback, - IxQMgrCallbackId callbackId) -{ - if (!ixQMgrQIsConfigured(qId)) - { - return IX_QMGR_Q_NOT_CONFIGURED; - } - - if (NULL == callback) - { - /* Reset to dummy callback */ - dispatchQInfo[qId].callback = dummyCallback; - dispatchQInfo[qId].dummyCallbackCount = 0; - dispatchQInfo[qId].callbackId = 0; - } - else - { - dispatchQInfo[qId].callback = callback; - dispatchQInfo[qId].callbackId = callbackId; - } - - return IX_SUCCESS; -} - -IX_STATUS -ixQMgrNotificationEnable (IxQMgrQId qId, - IxQMgrSourceId srcSel) -{ - IxQMgrQStatus qStatusOnEntry;/* The queue status on entry/exit */ - IxQMgrQStatus qStatusOnExit; /* to this function */ - int ixQMgrLockKey; - -#ifndef NDEBUG - if (!ixQMgrQIsConfigured (qId)) - { - return IX_QMGR_Q_NOT_CONFIGURED; - } - - if ((qId < IX_QMGR_MIN_QUEUPP_QID) && - !IX_QMGR_DISPATCHER_SOURCE_ID_CHECK(srcSel)) - { - /* QId 0-31 source id invalid */ - return IX_QMGR_INVALID_INT_SOURCE_ID; - } - - if ((IX_QMGR_Q_SOURCE_ID_NE != srcSel) && - (qId >= IX_QMGR_MIN_QUEUPP_QID)) - { - /* - * For queues 32-63 the interrupt source is fixed to the Nearly - * Empty status flag and therefore should have a srcSel of NE. - */ - return IX_QMGR_INVALID_INT_SOURCE_ID; - } -#endif - -#ifndef NDEBUG - dispatcherStats.queueStats[qId].notificationEnabled = TRUE; - dispatcherStats.queueStats[qId].srcSel = srcSel; -#endif - - /* Get the current queue status */ - ixQMgrAqmIfQueStatRead (qId, &qStatusOnEntry); - - /* - * Enabling interrupts results in Read-Modify-Write - * so need critical section - */ - - ixQMgrLockKey = ixOsalIrqLock(); - - /* Calculate the checkMask and checkValue for this q */ - ixQMgrAqmIfQStatusCheckValsCalc (qId, - srcSel, - &dispatchQInfo[qId].statusWordOffset, - &dispatchQInfo[qId].statusCheckValue, - &dispatchQInfo[qId].statusMask); - - - /* Set the interupt source is this queue is in the range 0-31 */ - if (qId < IX_QMGR_MIN_QUEUPP_QID) - { - ixQMgrAqmIfIntSrcSelWrite (qId, srcSel); - } - - /* Enable the interrupt */ - ixQMgrAqmIfQInterruptEnable (qId); - - ixOsalIrqUnlock(ixQMgrLockKey); - - /* 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 -ixQMgrNotificationDisable (IxQMgrQId qId) -{ - int ixQMgrLockKey; - -#ifndef NDEBUG - /* Validate parameters */ - if (!ixQMgrQIsConfigured (qId)) - { - return IX_QMGR_Q_NOT_CONFIGURED; - } -#endif - - /* - * Enabling interrupts results in Read-Modify-Write - * so need critical section - */ -#ifndef NDEBUG - dispatcherStats.queueStats[qId].notificationEnabled = FALSE; -#endif - - ixQMgrLockKey = ixOsalIrqLock(); - - ixQMgrAqmIfQInterruptDisable (qId); - - ixOsalIrqUnlock(ixQMgrLockKey); - - return IX_SUCCESS; -} - -void -ixQMgrStickyInterruptRegEnable(void) -{ - /* Use Aqm If function to set Interrupt Register0 Bit-3 */ - ixQMgrAqmIfIntSrcSelReg0Bit3Set (); -} - -#if !defined __XSCALE__ || defined __linux - -/* Count the number of leading zero bits in a word, - * and return the same value than the CLZ instruction. - * - * word (in) return value (out) - * 0x80000000 0 - * 0x40000000 1 - * ,,, ,,, - * 0x00000002 30 - * 0x00000001 31 - * 0x00000000 32 - * - * The C version of this function is used as a replacement - * for system not providing the equivalent of the CLZ - * assembly language instruction. - * - * Note that this version is big-endian - */ -unsigned int -ixQMgrCountLeadingZeros(UINT32 word) -{ - unsigned int leadingZerosCount = 0; - - if (word == 0) - { - return 32; - } - /* search the first bit set by testing the MSB and shifting the input word */ - while ((word & 0x80000000) == 0) - { - word <<= 1; - leadingZerosCount++; - } - return leadingZerosCount; -} -#endif /* not __XSCALE__ or __linux */ - -void -ixQMgrDispatcherLoopGet (IxQMgrDispatcherFuncPtr *qDispatcherFuncPtr) -{ - IxFeatureCtrlProductId productId = 0; - IxFeatureCtrlDeviceId deviceId = 0; - - /* Get the device ID for the underlying silicon */ - deviceId = ixFeatureCtrlDeviceRead(); - - /* Get the product ID for the underlying silicon */ - productId = ixFeatureCtrlProductIdRead (); - - /* IF (IXP42X AND A0 silicon) -> use ixQMgrDispatcherLoopRunA0 */ - if ((IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X == - (IX_FEATURE_CTRL_DEVICE_TYPE_MASK & deviceId)) && - (IX_FEATURE_CTRL_SILICON_TYPE_A0 == - (IX_FEATURE_CTRL_SILICON_STEPPING_MASK & productId))) - { - /*For IXP42X A0 silicon */ - *qDispatcherFuncPtr = &ixQMgrDispatcherLoopRunA0 ; - } - else /*For IXP42X B0 or IXP46X silicon*/ - { - if (IX_FEATURE_CTRL_SWCONFIG_ENABLED == ixQMgrOrigB0Dispatcher) - { - /* Default for IXP42X B0 and IXP46X silicon */ - *qDispatcherFuncPtr = &ixQMgrDispatcherLoopRunB0; - } - else - { - /* FeatureCtrl indicated that livelock dispatcher be used */ - *qDispatcherFuncPtr = &ixQMgrDispatcherLoopRunB0LLP; - } - } -} - -void -ixQMgrDispatcherLoopRunA0 (IxQMgrDispatchGroup group) -{ - UINT32 intRegVal; /* Interrupt reg val */ - UINT32 intRegValAfterWrite; /* Interrupt reg val after writing back */ - UINT32 intRegCheckMask; /* Mask for checking interrupt bits */ - UINT32 qStatusWordsB4Write[MAX_Q_STATUS_WORDS]; /* Status b4 interrupt write */ - UINT32 qStatusWordsAfterWrite[MAX_Q_STATUS_WORDS]; /* Status after interrupt write */ - IxQMgrQInfo *currDispatchQInfo; - BOOL statusChangeFlag; - - int priorityTableIndex;/* Priority table index */ - int qIndex; /* Current queue being processed */ - int endIndex; /* Index of last queue to process */ - -#ifndef NDEBUG - IX_OSAL_ASSERT((group == IX_QMGR_QUEUPP_GROUP) || - (group == IX_QMGR_QUELOW_GROUP)); -#endif - - /* Read Q status registers before interrupt status read/write */ - ixQMgrAqmIfQStatusRegsRead (group, qStatusWordsB4Write); - - /* Read the interrupt register */ - ixQMgrAqmIfQInterruptRegRead (group, &intRegVal); - - /* No bit set : nothing to process (the reaminder of the algorithm is - * based on the fact that the interrupt register value contains at - * least one bit set - */ - if (intRegVal == 0) - { -#ifndef NDEBUG - /* Update statistics */ - dispatcherStats.loopRunCnt++; -#endif - - /* Rebuild the priority table if needed */ - if (rebuildTable) - { - ixQMgrDispatcherReBuildPriorityTable (); - } - - return; - } - - /* Write it back to clear the interrupt */ - ixQMgrAqmIfQInterruptRegWrite (group, intRegVal); - - /* Read Q status registers after interrupt status read/write */ - ixQMgrAqmIfQStatusRegsRead (group, qStatusWordsAfterWrite); - - /* get the first queue Id from the interrupt register value */ - qIndex = (BITS_PER_WORD - 1) - ixQMgrCountLeadingZeros(intRegVal); - - /* check if any change occured during hw register modifications */ - if (IX_QMGR_QUELOW_GROUP == group) - { - statusChangeFlag = - (qStatusWordsB4Write[0] != qStatusWordsAfterWrite[0]) || - (qStatusWordsB4Write[1] != qStatusWordsAfterWrite[1]) || - (qStatusWordsB4Write[2] != qStatusWordsAfterWrite[2]) || - (qStatusWordsB4Write[3] != qStatusWordsAfterWrite[3]); - } - else - { - statusChangeFlag = - (qStatusWordsB4Write[0] != qStatusWordsAfterWrite[0]); - /* Set the queue range based on the queue group to proccess */ - qIndex += IX_QMGR_MIN_QUEUPP_QID; - } - - if (statusChangeFlag == FALSE) - { - /* check if the interrupt register contains - * only 1 bit set (happy day scenario) - */ - currDispatchQInfo = &dispatchQInfo[qIndex]; - if (intRegVal == currDispatchQInfo->intRegCheckMask) - { - /* only 1 queue event triggered a notification * - * Call the callback function for this queue - */ - currDispatchQInfo->callback (qIndex, - currDispatchQInfo->callbackId); -#ifndef NDEBUG - /* Update statistics */ - dispatcherStats.queueStats[qIndex].callbackCnt++; -#endif - } - else - { - /* the event is triggered by more than 1 queue, - * the queue search will be starting from the beginning - * or the middle of the priority table - * - * the serach will end when all the bits of the interrupt - * register are cleared. There is no need to maintain - * a seperate value and test it at each iteration. - */ - if (IX_QMGR_QUELOW_GROUP == group) - { - /* check if any bit related to queues in the first - * half of the priority table is set - */ - if (intRegVal & lowPriorityTableFirstHalfMask) - { - priorityTableIndex = IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX; - } - else - { - priorityTableIndex = IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX; - } - } - else - { - /* check if any bit related to queues in the first - * half of the priority table is set - */ - if (intRegVal & uppPriorityTableFirstHalfMask) - { - priorityTableIndex = IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX; - } - else - { - priorityTableIndex = IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX; - } - } - - /* iterate following the priority table until all the bits - * of the interrupt register are cleared. - */ - do - { - qIndex = priorityTable[priorityTableIndex++]; - currDispatchQInfo = &dispatchQInfo[qIndex]; - intRegCheckMask = currDispatchQInfo->intRegCheckMask; - - /* If this queue caused this interrupt to be raised */ - if (intRegVal & intRegCheckMask) - { - /* Call the callback function for this queue */ - currDispatchQInfo->callback (qIndex, - currDispatchQInfo->callbackId); -#ifndef NDEBUG - /* Update statistics */ - dispatcherStats.queueStats[qIndex].callbackCnt++; -#endif - - /* Clear the interrupt register bit */ - intRegVal &= ~intRegCheckMask; - } - } - while(intRegVal); - } - } - else - { - /* A change in queue status occured during the hw interrupt - * register update. To maintain the interrupt consistency, it - * is necessary to iterate through all queues of the queue group. - */ - - /* Read interrupt status again */ - ixQMgrAqmIfQInterruptRegRead (group, &intRegValAfterWrite); - - if (IX_QMGR_QUELOW_GROUP == group) - { - priorityTableIndex = IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX; - endIndex = IX_QMGR_MAX_LOW_QUE_PRIORITY_TABLE_INDEX; - } - else - { - priorityTableIndex = IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX; - endIndex = IX_QMGR_MAX_UPP_QUE_PRIORITY_TABLE_INDEX; - } - - for ( ; priorityTableIndex<=endIndex; priorityTableIndex++) - { - qIndex = priorityTable[priorityTableIndex]; - currDispatchQInfo = &dispatchQInfo[qIndex]; - intRegCheckMask = currDispatchQInfo->intRegCheckMask; - - /* If this queue caused this interrupt to be raised */ - if (intRegVal & intRegCheckMask) - { - /* Call the callback function for this queue */ - currDispatchQInfo->callback (qIndex, - currDispatchQInfo->callbackId); -#ifndef NDEBUG - /* Update statistics */ - dispatcherStats.queueStats[qIndex].callbackCnt++; -#endif - - } /* if (intRegVal .. */ - - /* - * If interrupt bit is set in intRegValAfterWrite don't - * proceed as this will be caught in next interrupt - */ - else if ((intRegValAfterWrite & intRegCheckMask) == 0) - { - /* Check if an interrupt was lost for this Q */ - if (ixQMgrAqmIfQStatusCheck(qStatusWordsB4Write, - qStatusWordsAfterWrite, - currDispatchQInfo->statusWordOffset, - currDispatchQInfo->statusCheckValue, - currDispatchQInfo->statusMask)) - { - /* Call the callback function for this queue */ - currDispatchQInfo->callback (qIndex, - dispatchQInfo[qIndex].callbackId); -#ifndef NDEBUG - /* Update statistics */ - dispatcherStats.queueStats[qIndex].callbackCnt++; - dispatcherStats.queueStats[qIndex].intLostCallbackCnt++; -#endif - } /* if ixQMgrAqmIfQStatusCheck(.. */ - } /* else if ((intRegValAfterWrite ... */ - } /* for (priorityTableIndex=0 ... */ - } - - /* Rebuild the priority table if needed */ - if (rebuildTable) - { - ixQMgrDispatcherReBuildPriorityTable (); - } - -#ifndef NDEBUG - /* Update statistics */ - dispatcherStats.loopRunCnt++; -#endif -} - - - -void -ixQMgrDispatcherLoopRunB0 (IxQMgrDispatchGroup group) -{ - UINT32 intRegVal; /* Interrupt reg val */ - UINT32 intRegCheckMask; /* Mask for checking interrupt bits */ - IxQMgrQInfo *currDispatchQInfo; - - - int priorityTableIndex; /* Priority table index */ - int qIndex; /* Current queue being processed */ - -#ifndef NDEBUG - IX_OSAL_ASSERT((group == IX_QMGR_QUEUPP_GROUP) || - (group == IX_QMGR_QUELOW_GROUP)); - IX_OSAL_ASSERT((group == IX_QMGR_QUEUPP_GROUP) || - (group == IX_QMGR_QUELOW_GROUP)); -#endif - - /* Read the interrupt register */ - ixQMgrAqmIfQInterruptRegRead (group, &intRegVal); - - - /* No queue has interrupt register set */ - if (intRegVal != 0) - { - - /* Write it back to clear the interrupt */ - ixQMgrAqmIfQInterruptRegWrite (group, intRegVal); - - /* get the first queue Id from the interrupt register value */ - qIndex = (BITS_PER_WORD - 1) - ixQMgrCountLeadingZeros(intRegVal); - - if (IX_QMGR_QUEUPP_GROUP == group) - { - /* Set the queue range based on the queue group to proccess */ - qIndex += IX_QMGR_MIN_QUEUPP_QID; - } - - /* check if the interrupt register contains - * only 1 bit set - * For example: - * intRegVal = 0x0010 - * currDispatchQInfo->intRegCheckMask = 0x0010 - * intRegVal == currDispatchQInfo->intRegCheckMask is TRUE. - */ - currDispatchQInfo = &dispatchQInfo[qIndex]; - if (intRegVal == currDispatchQInfo->intRegCheckMask) - { - /* only 1 queue event triggered a notification * - * Call the callback function for this queue - */ - currDispatchQInfo->callback (qIndex, - currDispatchQInfo->callbackId); -#ifndef NDEBUG - /* Update statistics */ - dispatcherStats.queueStats[qIndex].callbackCnt++; -#endif - } - else - { - /* the event is triggered by more than 1 queue, - * the queue search will be starting from the beginning - * or the middle of the priority table - * - * the serach will end when all the bits of the interrupt - * register are cleared. There is no need to maintain - * a seperate value and test it at each iteration. - */ - if (IX_QMGR_QUELOW_GROUP == group) - { - /* check if any bit related to queues in the first - * half of the priority table is set - */ - if (intRegVal & lowPriorityTableFirstHalfMask) - { - priorityTableIndex = IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX; - } - else - { - priorityTableIndex = IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX; - } - } - else - { - /* check if any bit related to queues in the first - * half of the priority table is set - */ - if (intRegVal & uppPriorityTableFirstHalfMask) - { - priorityTableIndex = IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX; - } - else - { - priorityTableIndex = IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX; - } - } - - /* iterate following the priority table until all the bits - * of the interrupt register are cleared. - */ - do - { - qIndex = priorityTable[priorityTableIndex++]; - currDispatchQInfo = &dispatchQInfo[qIndex]; - intRegCheckMask = currDispatchQInfo->intRegCheckMask; - - /* If this queue caused this interrupt to be raised */ - if (intRegVal & intRegCheckMask) - { - /* Call the callback function for this queue */ - currDispatchQInfo->callback (qIndex, - currDispatchQInfo->callbackId); -#ifndef NDEBUG - /* Update statistics */ - dispatcherStats.queueStats[qIndex].callbackCnt++; -#endif - - /* Clear the interrupt register bit */ - intRegVal &= ~intRegCheckMask; - } - } - while(intRegVal); - } /*End of intRegVal == currDispatchQInfo->intRegCheckMask */ - } /* End of intRegVal != 0 */ - -#ifndef NDEBUG - /* Update statistics */ - dispatcherStats.loopRunCnt++; -#endif - - /* Rebuild the priority table if needed */ - if (rebuildTable) - { - ixQMgrDispatcherReBuildPriorityTable (); - } -} - -void -ixQMgrDispatcherLoopRunB0LLP (IxQMgrDispatchGroup group) -{ - UINT32 intRegVal =0; /* Interrupt reg val */ - UINT32 intRegCheckMask; /* Mask for checking interrupt bits */ - IxQMgrQInfo *currDispatchQInfo; - - int priorityTableIndex; /* Priority table index */ - int qIndex; /* Current queue being processed */ - - UINT32 intRegValCopy = 0; - UINT32 intEnableRegVal = 0; - UINT8 i = 0; - -#ifndef NDEBUG - IX_OSAL_ASSERT((group == IX_QMGR_QUEUPP_GROUP) || - (group == IX_QMGR_QUELOW_GROUP)); -#endif - - /* Read the interrupt register */ - ixQMgrAqmIfQInterruptRegRead (group, &intRegVal); - - /* - * mask any interrupts that are not enabled - */ - ixQMgrAqmIfQInterruptEnableRegRead (group, &intEnableRegVal); - intRegVal &= intEnableRegVal; - - /* No queue has interrupt register set */ - if (intRegVal != 0) - { - if (IX_QMGR_QUELOW_GROUP == group) - { - /* - * As the sticky bit is set, the interrupt register will - * not clear if write back at this point because the condition - * has not been cleared. Take a copy and write back later after - * the condition has been cleared - */ - intRegValCopy = intRegVal; - } - else - { - /* no sticky for upper Q's, so write back now */ - ixQMgrAqmIfQInterruptRegWrite (group, intRegVal); - } - - /* get the first queue Id from the interrupt register value */ - qIndex = (BITS_PER_WORD - 1) - ixQMgrCountLeadingZeros(intRegVal); - - if (IX_QMGR_QUEUPP_GROUP == group) - { - /* Set the queue range based on the queue group to proccess */ - qIndex += IX_QMGR_MIN_QUEUPP_QID; - } - - /* check if the interrupt register contains - * only 1 bit set - * For example: - * intRegVal = 0x0010 - * currDispatchQInfo->intRegCheckMask = 0x0010 - * intRegVal == currDispatchQInfo->intRegCheckMask is TRUE. - */ - currDispatchQInfo = &dispatchQInfo[qIndex]; - if (intRegVal == currDispatchQInfo->intRegCheckMask) - { - - /* - * check if Q type periodic - only lower queues can - * have there type set to periodic - */ - if (IX_QMGR_TYPE_REALTIME_PERIODIC == ixQMgrQTypes[qIndex]) - { - /* - * Disable the notifications on any sporadics - */ - for (i=0; i <= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++) - { - if (IX_QMGR_TYPE_REALTIME_SPORADIC == ixQMgrQTypes[i]) - { - ixQMgrNotificationDisable(i); -#ifndef NDEBUG - /* Update statistics */ - dispatcherStats.queueStats[i].disableCount++; -#endif - } - } - } - - currDispatchQInfo->callback (qIndex, - currDispatchQInfo->callbackId); -#ifndef NDEBUG - /* Update statistics */ - dispatcherStats.queueStats[qIndex].callbackCnt++; -#endif - } - else - { - /* the event is triggered by more than 1 queue, - * the queue search will be starting from the beginning - * or the middle of the priority table - * - * the serach will end when all the bits of the interrupt - * register are cleared. There is no need to maintain - * a seperate value and test it at each iteration. - */ - if (IX_QMGR_QUELOW_GROUP == group) - { - /* check if any bit related to queues in the first - * half of the priority table is set - */ - if (intRegVal & lowPriorityTableFirstHalfMask) - { - priorityTableIndex = - IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX; - } - else - { - priorityTableIndex = - IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX; - } - } - else - { - /* check if any bit related to queues in the first - * half of the priority table is set - */ - if (intRegVal & uppPriorityTableFirstHalfMask) - { - priorityTableIndex = - IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX; - } - else - { - priorityTableIndex = - IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX; - } - } - - /* iterate following the priority table until all the bits - * of the interrupt register are cleared. - */ - do - { - qIndex = priorityTable[priorityTableIndex++]; - currDispatchQInfo = &dispatchQInfo[qIndex]; - intRegCheckMask = currDispatchQInfo->intRegCheckMask; - - /* If this queue caused this interrupt to be raised */ - if (intRegVal & intRegCheckMask) - { - /* - * check if Q type periodic - only lower queues can - * have there type set to periodic. There can only be one - * periodic queue, so the sporadics are only disabled once. - */ - if (IX_QMGR_TYPE_REALTIME_PERIODIC == ixQMgrQTypes[qIndex]) - { - /* - * Disable the notifications on any sporadics - */ - for (i=0; i <= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++) - { - if (IX_QMGR_TYPE_REALTIME_SPORADIC == - ixQMgrQTypes[i]) - { - ixQMgrNotificationDisable(i); - /* - * remove from intRegVal as we don't want - * to service any sporadics now - */ - intRegVal &= ~dispatchQInfo[i].intRegCheckMask; -#ifndef NDEBUG - /* Update statistics */ - dispatcherStats.queueStats[i].disableCount++; -#endif - } - } - } - - currDispatchQInfo->callback (qIndex, - currDispatchQInfo->callbackId); -#ifndef NDEBUG - /* Update statistics */ - dispatcherStats.queueStats[qIndex].callbackCnt++; -#endif - /* Clear the interrupt register bit */ - intRegVal &= ~intRegCheckMask; - } - } - while(intRegVal); - } /*End of intRegVal == currDispatchQInfo->intRegCheckMask */ - } /* End of intRegVal != 0 */ - -#ifndef NDEBUG - /* Update statistics */ - dispatcherStats.loopRunCnt++; -#endif - - if ((intRegValCopy != 0) && (IX_QMGR_QUELOW_GROUP == group)) - { - /* - * lower groups (therefore sticky) AND at least one enabled interrupt - * Write back to clear the interrupt - */ - ixQMgrAqmIfQInterruptRegWrite (IX_QMGR_QUELOW_GROUP, intRegValCopy); - } - - /* Rebuild the priority table if needed */ - if (rebuildTable) - { - ixQMgrDispatcherReBuildPriorityTable (); - } -} - -PRIVATE void -ixQMgrDispatcherReBuildPriorityTable (void) -{ - UINT32 qIndex; - UINT32 priority; - int lowQuePriorityTableIndex = IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX; - int uppQuePriorityTableIndex = IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX; - - /* Reset the rebuild flag */ - rebuildTable = FALSE; - - /* initialize the mak used to identify the queues in the first half - * of the priority table - */ - lowPriorityTableFirstHalfMask = 0; - uppPriorityTableFirstHalfMask = 0; - - /* For each priority level */ - for(priority=0; priority dummyCallback: qId (%d), callbackId (%d)\n",qId,cbId); - } - dispatchQInfo[qId].dummyCallbackCount++; - -#ifndef NDEBUG - /* Update statistcs */ - dispatcherStats.queueStats[qId].intNoCallbackCnt++; -#endif -} -void -ixQMgrLLPShow (int resetStats) -{ -#ifndef NDEBUG - UINT8 i = 0; - IxQMgrQInfo *q; - UINT32 intEnableRegVal = 0; - - printf ("Livelock statistics are printed on the fly.\n"); - printf ("qId Type EnableCnt DisableCnt IntEnableState Callbacks\n"); - printf ("=== ======== ========= ========== ============== =========\n"); - - for (i=0; i<= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++) - { - q = &dispatchQInfo[i]; - - if (ixQMgrQTypes[i] != IX_QMGR_TYPE_REALTIME_OTHER) - { - printf (" %2d ", i); - - if (ixQMgrQTypes[i] == IX_QMGR_TYPE_REALTIME_SPORADIC) - { - printf ("Sporadic"); - } - else - { - printf ("Periodic"); - } - - - ixQMgrAqmIfQInterruptEnableRegRead (IX_QMGR_QUELOW_GROUP, - &intEnableRegVal); - - - intEnableRegVal &= dispatchQInfo[i].intRegCheckMask; - intEnableRegVal = intEnableRegVal >> i; - - printf (" %10d %10d %10d %10d\n", - dispatcherStats.queueStats[i].enableCount, - dispatcherStats.queueStats[i].disableCount, - intEnableRegVal, - dispatcherStats.queueStats[i].callbackCnt); - - if (resetStats) - { - dispatcherStats.queueStats[i].enableCount = - dispatcherStats.queueStats[i].disableCount = - dispatcherStats.queueStats[i].callbackCnt = 0; - } - } - } -#else - IX_QMGR_LOG0("Livelock Prevention statistics are only collected in debug mode\n"); -#endif -} - -void -ixQMgrPeriodicDone (void) -{ - UINT32 i = 0; - UINT32 ixQMgrLockKey = 0; - - /* - * for the lower queues - */ - for (i=0; i <= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++) - { - /* - * check for sporadics - */ - if (IX_QMGR_TYPE_REALTIME_SPORADIC == ixQMgrQTypes[i]) - { - /* - * enable any sporadics - */ - ixQMgrLockKey = ixOsalIrqLock(); - ixQMgrAqmIfQInterruptEnable(i); - ixOsalIrqUnlock(ixQMgrLockKey); -#ifndef NDEBUG - /* - * Update statistics - */ - dispatcherStats.queueStats[i].enableCount++; - dispatcherStats.queueStats[i].notificationEnabled = TRUE; -#endif - } - } -} -IX_STATUS -ixQMgrCallbackTypeSet (IxQMgrQId qId, - IxQMgrType type) -{ - UINT32 ixQMgrLockKey = 0; - IxQMgrType ixQMgrOldType =0; - -#ifndef NDEBUG - if (!ixQMgrQIsConfigured(qId)) - { - return IX_QMGR_Q_NOT_CONFIGURED; - } - if (qId >= IX_QMGR_MIN_QUEUPP_QID) - { - return IX_QMGR_PARAMETER_ERROR; - } - if(!IX_QMGR_DISPATCHER_CALLBACK_TYPE_CHECK(type)) - { - return IX_QMGR_PARAMETER_ERROR; - } -#endif - - ixQMgrOldType = ixQMgrQTypes[qId]; - ixQMgrQTypes[qId] = type; - - /* - * check if Q has been changed from type SPORADIC - */ - if (IX_QMGR_TYPE_REALTIME_SPORADIC == ixQMgrOldType) - { - /* - * previously Q was a SPORADIC, this means that LLP - * might have had it disabled. enable it now. - */ - ixQMgrLockKey = ixOsalIrqLock(); - ixQMgrAqmIfQInterruptEnable(qId); - ixOsalIrqUnlock(ixQMgrLockKey); - -#ifndef NDEBUG - /* - * Update statistics - */ - dispatcherStats.queueStats[qId].enableCount++; -#endif - } - - return IX_SUCCESS; -} - -IX_STATUS -ixQMgrCallbackTypeGet (IxQMgrQId qId, - IxQMgrType *type) -{ -#ifndef NDEBUG - if (!ixQMgrQIsConfigured(qId)) - { - return IX_QMGR_Q_NOT_CONFIGURED; - } - if (qId >= IX_QMGR_MIN_QUEUPP_QID) - { - return IX_QMGR_PARAMETER_ERROR; - } - if(type == NULL) - { - return IX_QMGR_PARAMETER_ERROR; - } -#endif - - *type = ixQMgrQTypes[qId]; - return IX_SUCCESS; -} diff --git a/cpu/ixp/npe/IxQMgrInit.c b/cpu/ixp/npe/IxQMgrInit.c deleted file mode 100644 index b00c22d08e..0000000000 --- a/cpu/ixp/npe/IxQMgrInit.c +++ /dev/null @@ -1,233 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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; iqStats[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; -} - - - - diff --git a/cpu/ixp/npe/IxQMgrQAccess.c b/cpu/ixp/npe/IxQMgrQAccess.c deleted file mode 100644 index 8885736246..0000000000 --- a/cpu/ixp/npe/IxQMgrQAccess.c +++ /dev/null @@ -1,796 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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 */ diff --git a/cpu/ixp/npe/IxQMgrQCfg.c b/cpu/ixp/npe/IxQMgrQCfg.c deleted file mode 100644 index ec7d837c38..0000000000 --- a/cpu/ixp/npe/IxQMgrQCfg.c +++ /dev/null @@ -1,543 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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; -} diff --git a/cpu/ixp/npe/Makefile b/cpu/ixp/npe/Makefile deleted file mode 100644 index 8fefd29eb5..0000000000 --- a/cpu/ixp/npe/Makefile +++ /dev/null @@ -1,98 +0,0 @@ -# -# (C) Copyright 2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB := $(obj)libnpe.a - -LOCAL_CFLAGS += -I$(TOPDIR)/cpu/ixp/npe/include -DCONFIG_IXP425_COMPONENT_ETHDB -D__linux -CFLAGS += $(LOCAL_CFLAGS) -HOSTCFLAGS += $(LOCAL_CFLAGS) - -COBJS-$(CONFIG_IXP4XX_NPE) := 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 - -SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS-y)) -SOBJS := $(addprefix $(obj),$(SOBJS)) - -all: $(LIB) - -$(LIB): $(obj).depend $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/ixp/npe/include/IxAssert.h b/cpu/ixp/npe/include/IxAssert.h deleted file mode 100644 index eae8b3f273..0000000000 --- a/cpu/ixp/npe/include/IxAssert.h +++ /dev/null @@ -1,71 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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 - */ - - - diff --git a/cpu/ixp/npe/include/IxAtmSch.h b/cpu/ixp/npe/include/IxAtmSch.h deleted file mode 100644 index 73c3be29ab..0000000000 --- a/cpu/ixp/npe/include/IxAtmSch.h +++ /dev/null @@ -1,504 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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 - * - IX_SUCCESS : indicates that - * -# The ATM scheduler component has been successfully initialized. - * -# The scheduler is ready to accept Port modelling requests. - * - IX_FAIL : 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 - * - IX_SUCCESS : 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. - * - IX_FAIL : 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 - * - IX_SUCCESS : The port rate has been successfully modified.
- * - IX_FAIL : 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 - * - IX_SUCCESS : The VC has been successfully established on - * this port. The client may begin to submit demand on this VC. - * - IX_ATMSCH_RET_NOT_ADMITTED : The VC cannot be established - * on this port because there is insufficient upstream capacity - * available to support the requested traffic contract descriptor - * - IX_FAIL :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 - * - IX_SUCCESS : The id has successfully been set. - * - IX_FAIL :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 - * - IX_SUCCESS : The VC has been successfully removed from - * this port. It is no longer modelled on this port. - * - IX_FAIL :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 - * - IX_SUCCESS : The VC queue has been successfully updated. - * - IX_ATMSCH_RET_QUEUE_FULL : 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. - * - IX_FAIL : 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 - * - IX_SUCCESS : The VC queue has been successfully cleared. - * - IX_FAIL : 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 - * - IX_SUCCESS : The schedule table has been published. - * Currently there is at least one VC queue that is nonempty. - * - IX_ATMSCH_RET_QUEUE_EMPTY : 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. - * - IX_FAIL : 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 */ - -/** @} */ diff --git a/cpu/ixp/npe/include/IxAtmTypes.h b/cpu/ixp/npe/include/IxAtmTypes.h deleted file mode 100644 index 8624c3328e..0000000000 --- a/cpu/ixp/npe/include/IxAtmTypes.h +++ /dev/null @@ -1,409 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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 - */ - - diff --git a/cpu/ixp/npe/include/IxAtmdAcc.h b/cpu/ixp/npe/include/IxAtmdAcc.h deleted file mode 100644 index ae7b2434c3..0000000000 --- a/cpu/ixp/npe/include/IxAtmdAcc.h +++ /dev/null @@ -1,1194 +0,0 @@ - -/** - * @file IxAtmdAcc.h - * - * @date 07-Nov-2001 - * - * @brief IxAtmdAcc Public API - * - * This file contains the public API of IxAtmdAcc, related to the - * data functions of the component - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -/* ------------------------------------------------------ - Doxygen group definitions - ------------------------------------------------------ */ - -/** - * - * @defgroup IxAtmdAccAPI IXP400 ATM Driver Access (IxAtmdAcc) API - * - * @brief The public API for the IXP400 Atm Driver Data component - * - * IxAtmdAcc is the low level interface by which AAL0/AAL5 and - * OAM data gets transmitted to,and received from the Utopia bus. - * - * For AAL0/AAL5 services transmit and receive connections may - * be established independantly for unique combinations of - * port,VPI,and VCI. - * - * Two AAL0 services supporting 48 or 52 byte cell data are provided. - * Submitted AAL0 PDUs must be a multiple of the cell data size (48/52). - * AAL0_52 is a raw cell service the client must format - * the PDU with an ATM cell header (excluding HEC) at the start of - * each cell, note that AtmdAcc does not validate the cell headers in - * a submitted PDU. - * - * OAM cells cannot be received over the AAL0 service but instead - * are received over a dedicated OAM service. - * - * For the OAM service an "OAM Tx channel" may be enabled for a port - * by establishing a single dedicated OAM Tx connection on that port. - * A single "OAM Rx channel" for all ports may be enabled by - * establishing a dedicated OAM Rx connection. - * - * The OAM service allows buffers containing 52 byte OAM F4/F5 cells - * to be transmitted and received over the dedicated OAM channels. - * HEC is appended/removed, and CRC-10 performed by the NPE. The OAM - * service offered by AtmdAcc is a raw cell transport service. - * It is assumed that ITU I.610 procedures that make use of this - * service are implemented above AtmdAcc. - * - * Note that the dedicated OAM connections are established on - * reserved VPI,VCI, and (in the case of Rx) port values defined below. - * These values are used purely to descriminate the dedicated OAM channels - * and do not identify a particular OAM F4/F5 flow. F4/F5 flows may be - * realised for particluar VPI/VCIs by manipulating the VPI,VCI - * fields of the ATM cell headers of cells in the buffers passed - * to AtmdAcc. Note that AtmdAcc does not validate the cell headers - * in a submitted OAM PDU. - * - * - * - * This part is related to the User datapath processing - * - * @{ - */ - -#ifndef IXATMDACC_H -#define IXATMDACC_H - -#include "IxAtmTypes.h" - -/* ------------------------------------------------------ - AtmdAcc Data Types definition - ------------------------------------------------------ */ - -/** - * - * @ingroup IxAtmdAccAPI - * - * @def IX_ATMDACC_WARNING - * - * @brief Warning return code - * - * This constant is used to tell IxAtmDAcc user about a special case. - * - */ -#define IX_ATMDACC_WARNING 2 - -/** - * - * @ingroup IxAtmdAccAPI - * - * @def IX_ATMDACC_BUSY - * - * @brief Busy return code - * - * This constant is used to tell IxAtmDAcc user that the request - * is correct, but cannot be processed because the IxAtmAcc resources - * are already used. The user has to retry its request later - * - */ -#define IX_ATMDACC_BUSY 3 - -/** - * - * @ingroup IxAtmdAccAPI - * - * @def IX_ATMDACC_RESOURCES_STILL_ALLOCATED - * - * @brief Disconnect return code - * - * This constant is used to tell IxAtmDAcc user that the disconnect - * functions are not complete because the resources used by the driver - * are not yet released. The user has to retry the disconnect call - * later. - * - */ -#define IX_ATMDACC_RESOURCES_STILL_ALLOCATED 4 - -/** - * - * @ingroup IxAtmdAccAPI - * - * @def IX_ATMDACC_DEFAULT_REPLENISH_COUNT - * - * @brief Default resources usage for RxVcFree replenish mechanism - * - * This constant is used to tell IxAtmDAcc to allocate and use - * the minimum of resources for rx free replenish. - * - * @sa ixAtmdAccRxVcConnect - */ -#define IX_ATMDACC_DEFAULT_REPLENISH_COUNT 0 - - -/** - * @ingroup IxAtmdAccAPI - * - * @def IX_ATMDACC_OAM_TX_VPI - * - * @brief The reserved value used for the dedicated OAM - * Tx connection. This "well known" value is used by atmdAcc and - * its clients to dsicriminate the OAM channel, and should be chosen so - * that it does not coencide with the VPI value used in an AAL0/AAL5 connection. - * Any attempt to connect a service type other than OAM on this VPI will fail. - * - * - */ -#define IX_ATMDACC_OAM_TX_VPI 0 - -/** - * @ingroup IxAtmdAccAPI - * - * @def IX_ATMDACC_OAM_TX_VCI - * - * @brief The reserved value used for the dedicated OAM - * Tx connection. This "well known" value is used by atmdAcc and - * its clients to dsicriminate the OAM channel, and should be chosen so - * that it does not coencide with the VCI value used in an AAL0/AAL5 connection. - * Any attempt to connect a service type other than OAM on this VCI will fail. - */ -#define IX_ATMDACC_OAM_TX_VCI 0 - - - /** - * @ingroup IxAtmdAccAPI - * - * @def IX_ATMDACC_OAM_RX_PORT - * - * @brief The reserved dummy PORT used for all dedicated OAM - * Rx connections. Note that this is not a real port but must - * have a value that lies within the valid range of port values. - */ -#define IX_ATMDACC_OAM_RX_PORT IX_UTOPIA_PORT_0 - - /** - * @ingroup IxAtmdAccAPI - * - * @def IX_ATMDACC_OAM_RX_VPI - * - * @brief The reserved value value used for the dedicated OAM - * Rx connection. This value should be chosen so that it does not - * coencide with the VPI value used in an AAL0/AAL5 connection. - * Any attempt to connect a service type other than OAM on this VPI will fail. - */ -#define IX_ATMDACC_OAM_RX_VPI 0 - -/** - * @ingroup IxAtmdAccAPI - * - * @def IX_ATMDACC_OAM_RX_VCI - * - * @brief The reserved value value used for the dedicated OAM - * Rx connection. This value should be chosen so that it does not - * coencide with the VCI value used in an AAL0/AAL5 connection. - * Any attempt to connect a service type other than OAM on this VCI will fail. - */ -#define IX_ATMDACC_OAM_RX_VCI 0 - - -/** - * @enum IxAtmdAccPduStatus - * - * @ingroup IxAtmdAccAPI - * - * @brief IxAtmdAcc Pdu status : - * - * IxAtmdAccPduStatus is used during a RX operation to indicate - * the status of the received PDU - * - */ - -typedef enum -{ - IX_ATMDACC_AAL0_VALID = 0, /**< aal0 pdu */ - IX_ATMDACC_OAM_VALID, /**< OAM pdu */ - IX_ATMDACC_AAL2_VALID, /**< aal2 pdu @b reserved for future use */ - IX_ATMDACC_AAL5_VALID, /**< aal5 pdu complete and trailer is valid */ - IX_ATMDACC_AAL5_PARTIAL, /**< aal5 pdu not complete, trailer is missing */ - IX_ATMDACC_AAL5_CRC_ERROR, /**< aal5 pdu not complete, crc error/length error */ - IX_ATMDACC_MBUF_RETURN /**< empty buffer returned to the user */ -} IxAtmdAccPduStatus; - - -/** - * - * @enum IxAtmdAccAalType - * - * @ingroup IxAtmdAccAPI - * - * @brief IxAtmdAcc AAL Service Type : - * - * IxAtmdAccAalType defines the type of traffic to run on this VC - * - */ -typedef enum -{ - IX_ATMDACC_AAL5, /**< ITU-T AAL5 */ - IX_ATMDACC_AAL2, /**< ITU-T AAL2 @b reserved for future use */ - IX_ATMDACC_AAL0_48, /**< AAL0 48 byte payloads (cell header is added by NPE)*/ - IX_ATMDACC_AAL0_52, /**< AAL0 52 byte cell data (HEC is added by NPE) */ - IX_ATMDACC_OAM, /**< OAM cell transport service (HEC is added by NPE)*/ - IX_ATMDACC_MAX_SERVICE_TYPE /**< not a service, used for parameter validation */ -} IxAtmdAccAalType; - -/** - * - * @enum IxAtmdAccClpStatus - * - * @ingroup IxAtmdAccAPI - * - * @brief IxAtmdAcc CLP indication - * - * IxAtmdAccClpStatus defines the CLP status of the current PDU - * - */ -typedef enum -{ - IX_ATMDACC_CLP_NOT_SET = 0, /**< CLP indication is not set */ - IX_ATMDACC_CLP_SET = 1 /**< CLP indication is set */ -} IxAtmdAccClpStatus; - -/** - * @typedef IxAtmdAccUserId - * - * @ingroup IxAtmdAccAPI - * - * @brief User-supplied Id - * - * IxAtmdAccUserId is passed through callbacks and allows the - * IxAtmdAcc user to identify the source of a call back. The range of - * this user-owned Id is [0...2^32-1)]. - * - * The user provides this own Ids on a per-channel basis as a parameter - * in a call to @a ixAtmdAccRxVcConnect() or @a ixAtmdAccRxVcConnect() - * - * @sa ixAtmdAccRxVcConnect - * @sa ixAtmdAccTxVcConnect - * - */ -typedef unsigned int IxAtmdAccUserId; - -/* ------------------------------------------------------ - Part of the IxAtmdAcc interface related to RX traffic - ------------------------------------------------------ */ - -/** - * - * @ingroup IxAtmdAccAPI - * - * @brief Rx callback prototype - * - * IxAtmdAccRxVcRxCallback is the prototype of the Rx callback user - * function called once per PDU to pass a receive Pdu to a user on a - * partilcular connection. The callback is likely to push the mbufs - * to a protocol layer, and recycle the mbufs for a further use. - * - * @note -This function is called ONLY in the context of - * the @a ixAtmdAccRxDispatch() function - * - * @sa ixAtmdAccRxDispatch - * @sa ixAtmdAccRxVcConnect - * - * @param port @ref IxAtmLogicalPort [in] - the port on which this PDU was received - * a logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] - * @param userId @ref IxAtmdAccUserId [in] - user Id provided in the call - * to @a ixAtmdAccRxVcConnect() - * @param status @ref IxAtmdAccPduStatus [in] - an indication about the PDU validity. - * In the case of AAL0 the only possibile value is - * AAL0_VALID, in this case the client may optionally determine - * that an rx timeout occured by checking if the mbuf is - * compleletly or only partially filled, the later case - * indicating a timeout. - * In the case of OAM the only possible value is OAM valid. - * The status is set to @a IX_ATMDACC_MBUF_RETURN when - * the mbuf is released during a disconnect process. - * @param clp @ref IxAtmdAccClpStatus [in] - clp indication for this PDU. - * For AAL5/AAL0_48 this information - * is set if the clp bit of any rx cell is set - * For AAL0-52/OAM the client may inspect the CLP in individual - * cell headers in the PDU, and this parameter is set to 0. - * @param *mbufPtr @ref IX_OSAL_MBUF [in] - depending on the servive type a pointer to - * an mbuf (AAL5/AAL0/OAM) or mbuf chain (AAL5 only), - * that comprises the complete PDU data. - * - * This parameter is guaranteed not to be a null pointer. - * - */ -typedef void (*IxAtmdAccRxVcRxCallback) (IxAtmLogicalPort port, - IxAtmdAccUserId userId, - IxAtmdAccPduStatus status, - IxAtmdAccClpStatus clp, - IX_OSAL_MBUF * mbufPtr); - -/** - * - * @ingroup IxAtmdAccAPI - * - * @brief Callback prototype for free buffer level is low. - * - * IxAtmdAccRxVcFreeLowCallback is the prototype of the user function - * which get called on a per-VC basis, when more mbufs are needed to - * continue the ATM data reception. This function is likely to supply - * more available mbufs by one or many calls to the replenish function - * @a ixAtmdAccRxVcFreeReplenish() - * - * This function is called when the number of available buffers for - * reception is going under the threshold level as defined - * in @a ixAtmdAccRxVcFreeLowCallbackRegister() - * - * This function is called inside an Qmgr dispatch context. No system - * resource or interrupt-unsafe feature should be used inside this - * callback. - * - * @sa ixAtmdAccRxVcFreeLowCallbackRegister - * @sa IxAtmdAccRxVcFreeLowCallback - * @sa ixAtmdAccRxVcFreeReplenish - * @sa ixAtmdAccRxVcFreeEntriesQuery - * @sa ixAtmdAccRxVcConnect - * - * @param userId @ref IxAtmdAccUserId [in] - user Id provided in the call - * to @a ixAtmdAccRxVcConnect() - * - * @return None - * - */ -typedef void (*IxAtmdAccRxVcFreeLowCallback) (IxAtmdAccUserId userId); - -/* ------------------------------------------------------ - Part of the IxAtmdAcc interface related to TX traffic - ------------------------------------------------------ */ - -/** - * - * @ingroup IxAtmdAccAPI - * - * @brief Buffer callback prototype. - * - * This function is called to relinguish ownership of a transmitted - * buffer chain to the user. - * - * @note -In the case of a chained mbuf the AmtdAcc component can - * chain many user buffers together and pass ownership to the user in - * one function call. - * - * @param userId @ref IxAtmdAccUserId [in] - user If provided at registration of this - * callback. - * @param mbufPtr @ref IX_OSAL_MBUF [in] - a pointer to mbufs or chain of mbufs and is - * guaranteed not to be a null pointer. - * - */ -typedef void (*IxAtmdAccTxVcBufferReturnCallback) (IxAtmdAccUserId userId, - IX_OSAL_MBUF * mbufPtr); - -/* ------------------------------------------------------ - Part of the IxAtmdAcc interface related to Initialisation - ------------------------------------------------------ */ - -/** - * - * @ingroup IxAtmdAccAPI - * - * @fn ixAtmdAccInit (void) - * - * @brief Initialise the IxAtmdAcc Component - * - * This function initialise the IxAtmdAcc component. This function shall - * be called before any other function of the API. Its role is to - * initialise all internal resources of the IxAtmdAcc component. - * - * The ixQmgr component needs to be initialized prior the use of - * @a ixAtmdAccInit() - * - * @param none - * - * Failing to initilialize the IxAtmdAcc API before any use of it will - * result in a failed status. - * If the specified component is not present, a success status will still be - * returned, however, a warning indicating the NPE to download to is not - * present will be issued. - * - * @return @li IX_SUCCESS initialisation is complete (in case of component not - * being present, a warning is clearly indicated) - * @return @li IX_FAIL unable to process this request either - * because this IxAtmdAcc is already initialised - * or some unspecified error has occrred. - */ -PUBLIC IX_STATUS ixAtmdAccInit (void); - -/** - * - * @ingroup IxAtmdAccAPI - * - * @fn ixAtmdAccShow (void) - * - * @brief Show IxAtmdAcc configuration on a per port basis - * - * @param none - * - * @return none - * - * @note - Display use printf() and are redirected to stdout - */ -PUBLIC void -ixAtmdAccShow (void); - -/** - * - * @ingroup IxAtmdAccAPI - * - * @fn ixAtmdAccStatsShow (void) - * - * @brief Show all IxAtmdAcc stats - * - * @param none - * - * @return none - * - * @note - Stats display use printf() and are redirected to stdout - */ -PUBLIC void -ixAtmdAccStatsShow (void); - -/** - * - * @ingroup IxAtmdAccAPI - * - * @fn ixAtmdAccStatsReset (void) - * - * @brief Reset all IxAtmdAcc stats - * - * @param none - * - * @return none - * - */ -PUBLIC void -ixAtmdAccStatsReset (void); - -/* ------------------------------------------------------ - Part of the IxAtmdAcc interface related to RX traffic - ------------------------------------------------------ */ - -/** - * - * @ingroup IxAtmdAccAPI - * - * @fn ixAtmdAccRxVcConnect (IxAtmLogicalPort port, - unsigned int vpi, - unsigned int vci, - IxAtmdAccAalType aalServiceType, - IxAtmRxQueueId rxQueueId, - IxAtmdAccUserId userCallbackId, - IxAtmdAccRxVcRxCallback rxCallback, - unsigned int minimumReplenishCount, - IxAtmConnId * connIdPtr, - IxAtmNpeRxVcId * npeVcIdPtr ) - * - * @brief Connect to a Aal Pdu receive service for a particular - * port/vpi/vci, and service type. - * - * This function allows a user to connect to an Aal5/Aal0/OAM Pdu receive service - * for a particular port/vpi/vci. It registers the callback and allocates - * internal resources and a Connection Id to be used in further API calls - * related to this VCC. - * - * The function will setup VC receive service on the specified rx queue. - * - * This function is blocking and makes use internal locks, and hence - * should not be called from an interrupt context. - * - * On return from @a ixAtmdAccRxVcConnect() with a failure status, the - * connection Id parameter is unspecified. Its value cannot be used. - * A connId is the reference by which IxAtmdAcc refers to a - * connected VC. This identifier is the result of a succesful call - * to a connect function. This identifier is invalid after a - * sucessful call to a disconnect function. - * - * Calling this function for the same combination of Vpi, Vci and more - * than once without calling @a ixAtmdAccRxVcTryDisconnect() will result in a - * failure status. - * - * If this function returns success the user should supply receive - * buffers by calling @a ixAtmdAccRxVcFreeReplenish() and then call - * @a ixAtmdAccRxVcEnable() to begin receiving pdus. - * - * There is a choice of two receive Qs on which the VC pdus could be - * receive. The user must associate the VC with one of these. Essentially - * having two qs allows more flexible system configuration such as have - * high prioriy traffic on one q (e.g. voice) and low priority traffic on - * the other (e.g. data). The high priority Q could be serviced in - * preference to the low priority Q. One queue may be configured to be - * serviced as soon as there is traffic, the other queue may be configured - * to be serviced by a polling mechanism running at idle time. - * - * Two AAL0 services supporting 48 or 52 byte cell data are provided. - * Received AAL0 PDUs will be be a multiple of the cell data size (48/52). - * AAL0_52 is a raw cell service and includes an ATM cell header - * (excluding HEC) at the start of each cell. - * - * A single "OAM Rx channel" for all ports may be enabled by - * establishing a dedicated OAM Rx connection. - * - * The OAM service allows buffers containing 52 byte OAM F4/F5 cells - * to be transmitted and received over the dedicated OAM channels. - * HEC is appended/removed, and CRC-10 performed by the NPE. The OAM - * service offered by AtmdAcc is a raw cell transport service. - * It is assumed that ITU I.610 procedures that make use of this - * service are implemented above AtmdAcc. - * - * Note that the dedicated OAM connections are established on - * reserved VPI,VCI, and (in the case of Rx) port values. - * These values are used purely to descriminate the dedicated OAM channels - * and do not identify a particular OAM F4/F5 flow. F4/F5 flows may be - * realised for particluar VPI/VCIs by manipulating the VPI,VCI - * fields of the ATM cell headers of cells in the buffers passed - * to AtmdAcc. - * - * Calling this function prior to enable the port will fail. - * - * @sa ixAtmdAccRxDispatch - * @sa ixAtmdAccRxVcEnable - * @sa ixAtmdAccRxVcDisable - * @sa ixAtmdAccRxVcTryDisconnect - * @sa ixAtmdAccPortEnable - * - * @param port @ref IxAtmLogicalPort [in] - VC identification : logical PHY port - * [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] - * @param vpi unsigned int [in] - VC identification : ATM Vpi [0..255] or IX_ATMDACC_OAM_VPI - * @param vci unsigned int [in] - VC identification : ATM Vci [0..65535] or IX_ATMDACC_OAM_VCI - * @param aalServiceType @ref IxAtmdAccAalType [in] - type of service: AAL5, AAL0_48, AAL0_52, or OAM - * @param rxQueueId @ref IxAtmRxQueueId [in] - this identifieds which of two Qs the VC - * should use.when icoming traffic is processed - * @param userCallbackId @ref IxAtmdAccUserId [in] - user Id used later as a parameter to - * the supplied rxCallback. - * @param rxCallback [in] @ref IxAtmdAccRxVxRxCallback - function called when mbufs are received. - * This parameter cannot be a null pointer. - * @param bufferFreeCallback [in] - function to be called to return - * ownership of buffers to IxAtmdAcc user. - * @param minimumReplenishCount unsigned int [in] - For AAL5/AAL0 the number of free mbufs - * to be used with this channel. Use a high number when the expected traffic - * rate on this channel is high, or when the user's mbufs are small, or when - * the RxVcFreeLow Notification has to be invoked less often. When this - * value is IX_ATMDACC_DEFAULT_REPLENISH_COUNT, the minimum of - * resources will be used. Depending on traffic rate, pdu - * size and mbuf size, rxfree queue size, polling/interrupt rate, this value may - * require to be replaced by a different value in the range 1-128 - * For OAM the rxFree queue size is fixed by atmdAcc and this parameter is ignored. - * @param connIdPtr @ref IxAtmConnId [out] - pointer to a connection Id - * This parameter cannot be a null pointer. - * @param npeVcIdPtr @ref IxAtmNpeRxVcId [out] - pointer to an npe Vc Id - * This parameter cannot be a null pointer. - * - * @return @li IX_SUCCESS successful call to IxAtmdAccRxVcConnect - * @return @li IX_ATMDACC_BUSY cannot process this request : - * no VC is available - * @return @li IX_FAIL - * parameter error, - * VC already in use, - * attempt to connect AAL service on reserved OAM VPI/VCI, - * attempt to connect OAM service on VPI/VCI other than the reserved OAM VPI/VCI, - * port is not initialised, - * or some other error occurs during processing. - * - */ -PUBLIC IX_STATUS ixAtmdAccRxVcConnect (IxAtmLogicalPort port, - unsigned int vpi, - unsigned int vci, - IxAtmdAccAalType aalServiceType, - IxAtmRxQueueId rxQueueId, - IxAtmdAccUserId userCallbackId, - IxAtmdAccRxVcRxCallback rxCallback, - unsigned int minimumReplenishCount, - IxAtmConnId * connIdPtr, - IxAtmNpeRxVcId * npeVcIdPtr ); - -/** - * - * @ingroup IxAtmdAccAPI - * - * @fn ixAtmdAccRxVcFreeReplenish (IxAtmConnId connId, - IX_OSAL_MBUF * mbufPtr) - * - * @brief Provide free mbufs for data reception on a connection. - * - * This function provides mbufs for data reception by the hardware. This - * function needs to be called by the user on a regular basis to ensure - * no packet loss. Providing free buffers is a connection-based feature; - * each connection can have different requirements in terms of buffer size - * number of buffers, recycling rate. This function could be invoked from - * within the context of a @a IxAtmdAccRxVcFreeLowCallback() callback - * for a particular VC - * - * Mbufs provided through this function call can be chained. They will be - * unchained internally. A call to this function with chained mbufs or - * multiple calls with unchained mbufs are equivalent, but calls with - * unchained mbufs are more efficients. - * - * Mbufs provided to this interface need to be able to hold at least one - * full cell payload (48/52 bytes, depending on service type). - * Chained buffers with a size less than the size supported by the hardware - * will be returned through the rx callback provided during the connect step. - * - * Failing to invoke this function prior to enabling the RX traffic - * can result in packet loss. - * - * This function is not reentrant for the same connId. - * - * This function does not use system resources and can be - * invoked from an interrupt context. - * - * @note - Over replenish is detected, and extra mbufs are returned through - * the rx callback provided during the connect step. - * - * @note - Mbuf provided to the replenish function should have a length greater or - * equal to 48/52 bytes according to service type. - * - * @note - The memory cache of mMbuf payload should be invalidated prior to Mbuf - * submission. Flushing the Mbuf headers is handled by IxAtmdAcc. - * - * @note - When a chained mbuf is provided, this function process the mbufs - * up to the hardware limit and invokes the user-supplied callback - * to release extra buffers. - * - * @sa ixAtmdAccRxVcFreeLowCallbackRegister - * @sa IxAtmdAccRxVcFreeLowCallback - * @sa ixAtmdAccRxVcConnect - * - * @param connId @ref IxAtmConnId [in] - connection Id as returned from a succesfull call to - * @a IxAtmdAccRxVcConnect() - * @param mbufPtr @ref IX_OSAL_MBUF [in] - pointer to a mbuf structure to be used for data - * reception. The mbuf pointed to by this parameter can be chained - * to an other mbuf. - * - * @return @li IX_SUCCESS successful call to @a ixAtmdAccRxVcFreeReplenish() - * and the mbuf is now ready to use for incoming traffic. - * @return @li IX_ATMDACC_BUSY cannot process this request because - * the max number of outstanding free buffers has been reached - * or the internal resources have exhausted for this VC. - * The user is responsible for retrying this request later. - * @return @li IX_FAIL cannot process this request because of parameter - * errors or some unspecified internal error has occurred. - * - * @note - It is not always guaranteed the replenish step to be as fast as the - * hardware is consuming Rx Free mbufs. There is nothing in IxAtmdAcc to - * guarantee that replenish reaches the rxFree threshold level. If the - * threshold level is not reached, the next rxFree low notification for - * this channel will not be triggered. - * The preferred ways to replenish can be as follows (depending on - * applications and implementations) : - * @li Replenish in a rxFree low notification until the function - * ixAtmdAccRxVcFreeReplenish() returns IX_ATMDACC_BUSY - * @li Query the queue level using @sa ixAtmdAccRxVcFreeEntriesQuery, then - * , replenish using @a ixAtmdAccRxVcFreeReplenish(), then query the queue - * level again, and replenish if the threshold is still not reached. - * @li Trigger replenish from an other event source and use rxFree starvation - * to throttle the Rx traffic. - * - */ -PUBLIC IX_STATUS ixAtmdAccRxVcFreeReplenish (IxAtmConnId connId, - IX_OSAL_MBUF * mbufPtr); - -/** - * - * @ingroup IxAtmdAccAPI - * - * @fn ixAtmdAccRxVcFreeLowCallbackRegister (IxAtmConnId connId, - unsigned int numberOfMbufs, - IxAtmdAccRxVcFreeLowCallback callback) - * - * @brief Configure the RX Free threshold value and register a callback - * to handle threshold notifications. - * - * The function ixAtmdAccRxVcFreeLowCallbackRegister sets the threshold value for - * a particular RX VC. When the number of buffers reaches this threshold - * the callback is invoked. - * - * This function should be called once per VC before RX traffic is - * enabled.This function will fail if the curent level of the free buffers - * is equal or less than the threshold value. - * - * @sa ixAtmdAccRxVcFreeLowCallbackRegister - * @sa IxAtmdAccRxVcFreeLowCallback - * @sa ixAtmdAccRxVcFreeReplenish - * @sa ixAtmdAccRxVcFreeEntriesQuery - * @sa ixAtmdAccRxVcConnect - * - * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call - * to @a IxAtmdAccRxVcConnect() - * @param numberOfMbufs unsigned int [in] - threshold number of buffers. This number - * has to be a power of 2, one of the values 0,1,2,4,8,16,32.... - * The maximum value cannot be more than half of the rxFree queue - * size (which can be retrieved using @a ixAtmdAccRxVcFreeEntriesQuery() - * before any use of the @a ixAtmdAccRxVcFreeReplenish() function) - * @param callback @ref IxAtmdAccRxVcFreeLowCallback [in] - function telling the user that the number of - * free buffers has reduced to the threshold value. - * - * @return @li IX_SUCCESS Threshold set successfully. - * @return @li IX_FAIL parameter error or the current number of free buffers - * is less than or equal to the threshold supplied or some - * unspecified error has occrred. - * - * @note - the callback will be called when the threshold level will drop from - * exactly (numberOfMbufs + 1) to (numberOfMbufs). - * - */ -PUBLIC IX_STATUS ixAtmdAccRxVcFreeLowCallbackRegister (IxAtmConnId connId, - unsigned int numberOfMbufs, - IxAtmdAccRxVcFreeLowCallback callback); - -/** - * - * @ingroup IxAtmdAccAPI - * - * @fn ixAtmdAccRxVcFreeEntriesQuery (IxAtmConnId connId, - unsigned int *numberOfMbufsPtr) - * - * @brief Get the number of rx mbufs the system can accept to replenish the - * the rx reception mechanism on a particular channel - * - * The ixAtmdAccRxVcFreeEntriesQuery function is used to retrieve the current - * number of available mbuf entries for reception, on a per-VC basis. This - * function can be used to know the number of mbufs which can be provided - * using @a ixAtmdAccRxVcFreeReplenish(). - * - * This function can be used from a timer context, or can be associated - * with a threshold event, or can be used inside an active polling - * mechanism which is under user control. - * - * This function is reentrant and does not use system resources and can - * be invoked from an interrupt context. - * - * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call - * to @a IxAtmdAccRxVcConnect() - * @param numberOfMbufsPtr unsigned int [out] - Pointer to the number of available entries. - * . This parameter cannot be a null pointer. - * - * @return @li IX_SUCCESS the current number of mbufs not yet used for incoming traffic - * @return @li IX_FAIL invalid parameter - * - * @sa ixAtmdAccRxVcFreeReplenish - * - */ -PUBLIC IX_STATUS ixAtmdAccRxVcFreeEntriesQuery (IxAtmConnId connId, - unsigned int *numberOfMbufsPtr); - -/** - * - * @ingroup IxAtmdAccAPI - * - * @fn ixAtmdAccRxVcEnable (IxAtmConnId connId) - * - * @brief Start the RX service on a VC. - * - * This functions kicks-off the traffic reception for a particular VC. - * Once invoked, incoming PDUs will be made available by the hardware - * and are eventually directed to the @a IxAtmdAccRxVcRxCallback() callback - * registered for the connection. - * - * If the traffic is already running, this function returns IX_SUCCESS. - * This function can be invoked many times. - * - * IxAtmdAccRxVcFreeLowCallback event will occur only after - * @a ixAtmdAccRxVcEnable() function is invoked. - * - * Before using this function, the @a ixAtmdAccRxVcFreeReplenish() function - * has to be used to replenish the RX Free queue. If not, incoming traffic - * may be discarded.and in the case of interrupt driven reception the - * @a IxAtmdAccRxVcFreeLowCallback() callback may be invoked as a side effect - * during a replenish action. - * - * This function is not reentrant and should not be used inside an - * interrupt context. - * - * For an VC connection this function can be called after a call to - * @a ixAtmdAccRxVcDisable() and should not be called after - * @a ixAtmdAccRxVcTryDisconnect() - * - * @sa ixAtmdAccRxVcDisable - * @sa ixAtmdAccRxVcConnect - * @sa ixAtmdAccRxVcFreeReplenish - * - * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call - * to @a IxAtmdAccRxVcConnect() - * - * @return @li IX_SUCCESS successful call to ixAtmdAccRxVcEnable - * @return @li IX_ATMDACC_WARNING the channel is already enabled - * @return @li IX_FAIL invalid parameters or some unspecified internal - * error occured. - * - */ -PUBLIC IX_STATUS ixAtmdAccRxVcEnable (IxAtmConnId connId); - -/** - * - * @ingroup IxAtmdAccAPI - * - * @fn ixAtmdAccRxVcDisable (IxAtmConnId connId) - * - * @brief Stop the RX service on a VC. - * - * This functions stops the traffic reception for a particular VC connection. - * - * Once invoked, incoming Pdus are discarded by the hardware. Any Pdus - * pending will be freed to the user - * - * Hence once this function returns no more receive callbacks will be - * called for that VC. However, buffer free callbacks will be invoked - * until such time as all buffers supplied by the user have been freed - * back to the user - * - * Calling this function doe not invalidate the connId. - * @a ixAtmdAccRxVcEnable() can be invoked to enable Pdu reception again. - * - * If the traffic is already stopped, this function returns IX_SUCCESS. - * - * This function is not reentrant and should not be used inside an - * interrupt context. - * - * @sa ixAtmdAccRxVcConnect - * @sa ixAtmdAccRxVcEnable - * @sa ixAtmdAccRxVcDisable - * - * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call to @a - * IxAtmdAccRxVcConnect() - * - * @return @li IX_SUCCESS successful call to @a ixAtmdAccRxVcDisable(). - * @return @li IX_ATMDACC_WARNING the channel is already disabled - * @return @li IX_FAIL invalid parameters or some unspecified internal error occured - * - */ -PUBLIC IX_STATUS ixAtmdAccRxVcDisable (IxAtmConnId connId); - -/** - * - * @ingroup IxAtmdAccAPI - * - * @fn ixAtmdAccRxVcTryDisconnect (IxAtmConnId connId) - * - * @brief Disconnect a VC from the RX service. - * - * This function deregisters the VC and guarantees that all resources - * associated with this VC are free. After its execution, the connection - * Id is not available. - * - * This function will fail until such time as all resources allocated to - * the VC connection have been freed. The user is responsible to delay and - * call again this function many times until a success status is returned. - * - * This function needs internal locks and should not be called from an - * interrupt context - * - * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call to - * @a IxAtmdAccRxVcConnect() - * - * @return @li IX_SUCCESS successful call to ixAtmdAccRxVcDisable - * @return @li IX_ATMDACC_RESOURCES_STILL_ALLOCATED not all resources - * associated with the connection have been freed. - * @return @li IX_FAIL cannot process this request because of a parameter - * error - * - */ -PUBLIC IX_STATUS ixAtmdAccRxVcTryDisconnect (IxAtmConnId connId); - -/* ------------------------------------------------------ - Part of the IxAtmdAcc interface related to TX traffic - ------------------------------------------------------ */ - -/** - * - * @ingroup IxAtmdAccAPI - * - * @fn ixAtmdAccTxVcConnect (IxAtmLogicalPort port, - unsigned int vpi, - unsigned int vci, - IxAtmdAccAalType aalServiceType, - IxAtmdAccUserId userId, - IxAtmdAccTxVcBufferReturnCallback bufferFreeCallback, - IxAtmConnId * connIdPtr) - * - * @brief Connect to a Aal Pdu transmit service for a particular - * port/vpi/vci and service type. - * - * This function allows a user to connect to an Aal5/Aal0/OAM Pdu transmit service - * for a particular port/vpi/vci. It registers the callback and allocates - * internal resources and a Connection Id to be used in further API calls - * related to this VC. - * - * The function will setup VC transmit service on the specified on the - * specified port. A connId is the reference by which IxAtmdAcc refers to a - * connected VC. This identifier is the result of a succesful call - * to a connect function. This identifier is invalid after a - * sucessful call to a disconnect function. - * - * This function needs internal locks, and hence should not be called - * from an interrupt context. - * - * On return from @a ixAtmdAccTxVcConnect() with a failure status, the - * connection Id parameter is unspecified. Its value cannot be used. - * - * Calling this function for the same combination of port, Vpi, Vci and - * more than once without calling @a ixAtmdAccTxVcTryDisconnect() will result - * in a failure status. - * - * Two AAL0 services supporting 48 or 52 byte cell data are provided. - * Submitted AAL0 PDUs must be a multiple of the cell data size (48/52). - * AAL0_52 is a raw cell service the client must format - * the PDU with an ATM cell header (excluding HEC) at the start of - * each cell, note that AtmdAcc does not validate the cell headers in - * a submitted PDU. - * - * For the OAM service an "OAM Tx channel" may be enabled for a port - * by establishing a single dedicated OAM Tx connection on that port. - * - * The OAM service allows buffers containing 52 byte OAM F4/F5 cells - * to be transmitted and received over the dedicated OAM channels. - * HEC is appended/removed, and CRC-10 performed by the NPE. The OAM - * service offered by AtmdAcc is a raw cell transport service. - * It is assumed that ITU I.610 procedures that make use of this - * service are implemented above AtmdAcc. - * - * Note that the dedicated OAM connections are established on - * reserved VPI,VCI, and (in the case of Rx) port values. - * These values are used purely to descriminate the dedicated OAM channels - * and do not identify a particular OAM F4/F5 flow. F4/F5 flows may be - * realised for particluar VPI/VCIs by manipulating the VPI,VCI - * fields of the ATM cell headers of cells in the buffers passed - * to AtmdAcc. - * - * Calling this function before enabling the port will fail. - * - * @sa ixAtmdAccTxVcTryDisconnect - * @sa ixAtmdAccPortTxScheduledModeEnable - * @sa ixAtmdAccPortEnable - * - * @param port @ref IxAtmLogicalPort [in] - VC identification : logical PHY port - * [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] - * @param vpi unsigned int [in] - VC identification : ATM Vpi [0..255] or IX_ATMDACC_OAM_VPI - * @param vci unsigned int [in] - VC identification : ATM Vci [0..65535] or IX_ATMDACC_OAM_VCI - * @param aalServiceType @ref IxAtmdAccAalType [in] - type of service AAL5, AAL0_48, AAL0_52, or OAM - * @param userId @ref IxAtmdAccUserId [in] - user id to be used later during callbacks related - * to this channel - * @param bufferFreeCallback @ref IxAtmdAccTxVcBufferReturnCallback [in] - function called when mbufs - * transmission is complete. This parameter cannot be a null - * pointer. - * @param connIdPtr @ref IxAtmConnId [out] - Pointer to a connection Id. - * This parameter cannot be a null pointer. - * - * @return @li IX_SUCCESS successful call to @a IxAtmdAccRxVcConnect(). - * @return @li IX_ATMDACC_BUSY cannot process this request - * because no VC is available - * @return @li IX_FAIL - * parameter error, - * VC already in use, - * attempt to connect AAL service on reserved OAM VPI/VCI, - * attempt to connect OAM service on VPI/VCI other than the reserved OAM VPI/VCI, - * port is not initialised, - * or some other error occurs during processing. - * - * @note - Unscheduled mode is not supported in ixp425 1.0. Therefore, the - * function @a ixAtmdAccPortTxScheduledModeEnable() need to be called - * for this port before any establishing a Tx Connection - */ -PUBLIC IX_STATUS ixAtmdAccTxVcConnect (IxAtmLogicalPort port, - unsigned int vpi, - unsigned int vci, - IxAtmdAccAalType aalServiceType, - IxAtmdAccUserId userId, - IxAtmdAccTxVcBufferReturnCallback bufferFreeCallback, - IxAtmConnId * connIdPtr); - -/** - * - * @ingroup IxAtmdAccAPI - * - * @fn ixAtmdAccTxVcPduSubmit (IxAtmConnId connId, - IX_OSAL_MBUF * mbufPtr, - IxAtmdAccClpStatus clp, - unsigned int numberOfCells) - * - * @brief Submit a Pdu for transmission on connection. - * - * A data user calls this function to submit an mbufs containing a Pdu - * to be transmitted. The buffer supplied can be chained and the Pdu it - * contains must be complete. - * - * The transmission behavior of this call depends on the operational mode - * of the port on which the connection is made. - * - * In unscheduled mode the mbuf will be submitted to the hardware - * immediately if sufficent resource is available. Otherwise the function - * will return failure. - * - * In scheduled mode the buffer is queued internally in IxAtmdAcc. The cell - * demand is made known to the traffic shaping entity. Cells from the - * buffers are MUXed onto the port some time later as dictated by the - * traffic shaping entity. The traffic shaping entity does this by sending - * transmit schedules to IxAtmdAcc via @a ixAtmdAccPortTxProcess() function call. - * - * Note that the dedicated OAM channel is scheduled just like any - * other channel. This means that any OAM traffic relating to an - * active AAL0/AAL5 connection will be scheduled independantly of the - * AAL0/AAL5 traffic for that connection. - * - * When transmission is complete, the TX Done mechanism will give the - * owmnership of these buffers back to the customer. The tx done mechanism - * must be in operation before transmission is attempted. - * - * For AAL0/OAM submitted AAL0 PDUs must be a multiple of the cell data - * size (48/52). AAL0_52 and OAM are raw cell services, and the client - * must format the PDU with an ATM cell header (excluding HEC) at the - * start of each cell, note that AtmdAcc does not validate the cell headers in - * a submitted PDU. - * - * - * @sa IxAtmdAccTxVcBufferReturnCallback - * @sa ixAtmdAccTxDoneDispatch - * - * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call to - * @a ixAtmdAccTxVcConnect() - * @param mbufPtr @ref IX_OSAL_MBUF [in] - pointer to a chained structure of mbufs to transmit. - * This parameter cannot be a null pointer. - * @param clp @ref IxAtmdAccClpStatus [in] - clp indication for this PDU. All cells of this pdu - * will be sent with the clp bit set - * @param numberOfCells unsigned int [in] - number of cells in the PDU. - * - * @return @li IX_SUCCESS successful call to @a ixAtmdAccTxVcPduSubmit() - * The pdu pointed by the mbufPtr parameter will be - * transmitted - * @return @li IX_ATMDACC_BUSY unable to process this request because - * internal resources are all used. The caller is responsible - * for retrying this request later. - * @return @li IX_FAIL unable to process this request because of error - * in the parameters (wrong connId supplied, - * or wrong mbuf pointer supplied), the total length of all buffers - * in the chain should be a multiple of the cell size - * ( 48/52 depending on the service type ), - * or unspecified error during processing - * - * @note - This function in not re-entrant for the same VC (e.g. : two - * thread cannot send PDUs for the same VC). But two threads can - * safely call this function with a different connection Id - * - * @note - In unscheduled mode, this function is not re-entrant on a per - * port basis. The size of pdus is limited to 8Kb. - * - * @note - 0-length mbufs should be removed from the chain before submission. - * The total length of the pdu (sdu + padding +trailer) has to be - * updated in the header of the first mbuf of a chain of mbufs. - * - * @note - Aal5 trailer information (UUI, CPI, SDU length) has to be supplied - * before submission. - * - * @note - The payload memory cache should be flushed, if needed, prior to - * transmission. Mbuf headers are flushed by IxAtmdAcc - * - * @note - This function does not use system resources and can be used - * inside an interrupt context - */ -PUBLIC IX_STATUS ixAtmdAccTxVcPduSubmit (IxAtmConnId connId, - IX_OSAL_MBUF * mbufPtr, - IxAtmdAccClpStatus clp, - unsigned int numberOfCells); - -/** - * - * @ingroup IxAtmdAccAPI - * - * @fn ixAtmdAccTxVcTryDisconnect (IxAtmConnId connId) - * - * @brief Disconnect from a Aal Pdu transmit service for a particular - * port/vpi/vci. - * - * This function deregisters the VC and guarantees that all resources - * associated with this VC are free. After its execution, the connection - * Id is not available. - * - * This function will fail until such time as all resources allocated to - * the VC connection have been freed. The user is responsible to delay - * and call again this function many times until a success status is - * returned. - * - * After its execution, the connection Id is not available. - * - * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call to - * @a ixAtmdAccTxVcConnect() - * - * @return @li IX_SUCCESS successful call to @a ixAtmdAccTxVcTryDisconnect() - * @return @li IX_ATMDACC_RESOURCES_STILL_ALLOCATED not all resources - * associated with the connection have been freed. This condition will - * disappear after Tx and TxDone is complete for this channel. - * @return @li IX_FAIL unable to process this request because of errors - * in the parameters (wrong connId supplied) - * - * @note - This function needs internal locks and should not be called - * from an interrupt context - * - * @note - If the @a IX_ATMDACC_RESOURCES_STILL_ALLOCATED error does not - * clear after a while, this may be linked to a previous problem - * of cell overscheduling. Diabling the port and retry a disconnect - * will free the resources associated with this channel. - * - * @sa ixAtmdAccPortTxProcess - * - */ -PUBLIC IX_STATUS ixAtmdAccTxVcTryDisconnect (IxAtmConnId connId); - -#endif /* IXATMDACC_H */ - -/** - * @} defgroup IxAtmdAccAPI - */ - - diff --git a/cpu/ixp/npe/include/IxAtmdAccCtrl.h b/cpu/ixp/npe/include/IxAtmdAccCtrl.h deleted file mode 100644 index e2230493f2..0000000000 --- a/cpu/ixp/npe/include/IxAtmdAccCtrl.h +++ /dev/null @@ -1,1958 +0,0 @@ - -/** - * @file IxAtmdAccCtrl.h - * - * @date 20-Mar-2002 - * - * @brief IxAtmdAcc Public API - * - * This file contains the public API of IxAtmdAcc, related to the - * control functions of the component. - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -/* ------------------------------------------------------ - Doxygen group definitions - ------------------------------------------------------ */ - -/** - * - * @defgroup IxAtmdAccCtrlAPI IXP400 ATM Driver Access (IxAtmdAcc) Control API - * - * @brief The public API for the IXP400 Atm Driver Control component - * - * IxAtmdAcc is the low level interface by which AAL PDU get transmitted - * to,and received from the Utopia bus - * - * This part is related to the Control configuration - * - * @{ - */ - -#ifndef IXATMDACCCTRL_H -#define IXATMDACCCTRL_H - -#include "IxAtmdAcc.h" - -/* ------------------------------------------------------ - AtmdAccCtrl Data Types definition - ------------------------------------------------------ */ - -/** -* -* @ingroup IxAtmdAccCtrlAPI -* -* @def IX_ATMDACC_PORT_DISABLE_IN_PROGRESS -* -* @brief Port enable return code -* -* This constant is used to tell IxAtmDAcc user that the port disable -* functions are not complete. The user can call ixAtmdAccPortDisableComplete() -* to find out when the disable has finished. The port enable can then proceed. -* -*/ -#define IX_ATMDACC_PORT_DISABLE_IN_PROGRESS 5 - -/** -* -* @ingroup IxAtmdAccCtrlAPI -* -* @def IX_ATMDACC_ALLPDUS -* -* @brief All PDUs -* -* This constant is used to tell IxAtmDAcc to process all PDUs from -* the RX queue or the TX Done -* -* @sa IxAtmdAccRxDispatcher -* @sa IxAtmdAccTxDoneDispatcher -* -*/ -#define IX_ATMDACC_ALLPDUS 0xffffffff - -/* ------------------------------------------------------ - Part of the IxAtmdAcc interface related to RX traffic - ------------------------------------------------------ */ - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @brief Callback prototype for notification of available PDUs for - * an Rx Q. - * - * This a protoype for a function which is called when there is at - * least one Pdu available for processing on a particular Rx Q. - * - * This function should call @a ixAtmdAccRxDispatch() with - * the aprropriate number of parameters to read and process the Rx Q. - * - * @sa ixAtmdAccRxDispatch - * @sa ixAtmdAccRxVcConnect - * @sa ixAtmdAccRxDispatcherRegister - * - * @param rxQueueId @ref IxAtmRxQueueId [in] indicates which RX queue to has Pdus to process. - * @param numberOfPdusToProcess unsigned int [in] indicates the minimum number of - * PDUs available to process all PDUs from the queue. - * @param reservedPtr unsigned int* [out] pointer to a int location which can - * be written to, but does not retain written values. This is - * provided to make this prototype compatible - * with @a ixAtmdAccRxDispatch() - * - * @return @li int - ignored. - * - */ -typedef IX_STATUS (*IxAtmdAccRxDispatcher) (IxAtmRxQueueId rxQueueId, - unsigned int numberOfPdusToProcess, - unsigned int *reservedPtr); - -/* ------------------------------------------------------ - Part of the IxAtmdAcc interface related to TX traffic - ------------------------------------------------------ */ - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @brief Callback prototype for transmitted mbuf when threshold level is - * crossed. - * - * IxAtmdAccTxDoneDispatcher is the prototype of the user function - * which get called when pdus are completely transmitted. This function - * is likely to call the @a ixAtmdAccTxDoneDispatch() function. - * - * This function is called when the number of available pdus for - * reception is crossing the threshold level as defined - * in @a ixAtmdAccTxDoneDispatcherRegister() - * - * This function is called inside an Qmgr dispatch context. No system - * resource or interrupt-unsafe feature should be used inside this - * callback. - * - * Transmitted buffers recycling implementation is a sytem-wide mechanism - * and needs to be set before any traffic is started. If this threshold - * mechanism is not used, the user is responsible for polling the - * transmitted buffers with @a ixAtmdAccTxDoneDispatch() - * and @a ixAtmdAccTxDoneLevelQuery() functions. - * - * @sa ixAtmdAccTxDoneDispatcherRegister - * @sa ixAtmdAccTxDoneDispatch - * @sa ixAtmdAccTxDoneLevelQuery - * - * @param numberOfPdusToProcess unsigned int [in] - The current number of pdus currently - * available for recycling - * @param *reservedPtr unsigned int [out] - pointer to a int location which can be - * written to but does not retain written values. This is provided - * to make this prototype compatible - * with @a ixAtmdAccTxDoneDispatch() - * - * @return @li IX_SUCCESS This is provided to make - * this prototype compatible with @a ixAtmdAccTxDoneDispatch() - * @return @li IX_FAIL invalid parameters or some unspecified internal - * error occured. This is provided to make - * this prototype compatible with @a ixAtmdAccTxDoneDispatch() - * - */ -typedef IX_STATUS (*IxAtmdAccTxDoneDispatcher) (unsigned int numberOfPdusToProcess, - unsigned int *reservedPtr); - -/** -* -* @ingroup IxAtmdAccCtrlAPI -* -* @brief Notification that the threshold number of scheduled cells -* remains in a port's transmit Q. -* -* The is the prototype for of the user notification function which -* gets called on a per-port basis, when the number of remaining -* scheduled cells to be transmitted decreases to the threshold level. -* The number of cells passed as a parameter can be used for scheduling -* purposes as the maximum number of cells that can be passed in a -* schedule table to the @a ixAtmdAccPortTxProcess() function. -* -* @sa ixAtmdAccPortTxCallbackRegister -* @sa ixAtmdAccPortTxProcess -* @sa ixAtmdAccPortTxFreeEntriesQuery -* -* @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] -* @param numberOfAvailableCells unsigned int [in] - number of available -* cell entries.for the port -* -* @note - This functions shall not use system resources when used -* inside an interrupt context. -* -*/ -typedef void (*IxAtmdAccPortTxLowCallback) (IxAtmLogicalPort port, - unsigned int numberOfAvailableCells); - -/** -* -* @ingroup IxAtmdAccCtrlAPI -* -* @brief Prototype to submit cells for transmission -* -* IxAtmdAccTxVcDemandUpdateCallback is the prototype of the callback -* function used by AtmD to notify an ATM Scheduler that the user of -* a VC has submitted cells for transmission. -* -* @sa IxAtmdAccTxVcDemandUpdateCallback -* @sa IxAtmdAccTxVcDemandClearCallback -* @sa IxAtmdAccTxSchVcIdGetCallback -* @sa ixAtmdAccPortTxScheduledModeEnable -* -* @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the VC to be updated -* is established -* @param vcId int [in] - Identifies the VC to be updated. This is the value -* returned by the @a IxAtmdAccTxSchVcIdGetCallback() call . -* @param numberOfCells unsigned int [in] - Indicates how many ATM cells should be added -* to the queue for this VC. -* -* @return @li IX_SUCCESS the function is registering the cell demand for -* this VC. -* @return @li IX_FAIL the function cannot register cell for this VC : the -* scheduler maybe overloaded or misconfigured -* -*/ -typedef IX_STATUS (*IxAtmdAccTxVcDemandUpdateCallback) (IxAtmLogicalPort port, - int vcId, - unsigned int numberOfCells); - -/** -* -* @ingroup IxAtmdAccCtrlAPI -* -* @brief prototype to remove all currently queued cells from a -* registered VC -* -* IxAtmdAccTxVcDemandClearCallback is the prototype of the function -* to remove all currently queued cells from a registered VC. The -* pending cell count for the specified VC is reset to zero. After the -* use of this callback, the scheduler shall not schedule more cells -* for this VC. -* -* This callback function is called during a VC disconnection -* @a ixAtmdAccTxVcTryDisconnect() -* -* @sa IxAtmdAccTxVcDemandUpdateCallback -* @sa IxAtmdAccTxVcDemandClearCallback -* @sa IxAtmdAccTxSchVcIdGetCallback -* @sa ixAtmdAccPortTxScheduledModeEnable -* @sa ixAtmdAccTxVcTryDisconnect -* -* @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the VC to be cleared -* is established -* @param vcId int [in] - Identifies the VC to be cleared. This is the value -* returned by the @a IxAtmdAccTxSchVcIdGetCallback() call . -* -* @return none -* -*/ -typedef void (*IxAtmdAccTxVcDemandClearCallback) (IxAtmLogicalPort port, - int vcId); - -/** -* -* @ingroup IxAtmdAccCtrlAPI -* -* @brief prototype to get a scheduler vc id -* -* IxAtmdAccTxSchVcIdGetCallback is the prototype of the function to get -* a scheduler vcId -* -* @sa IxAtmdAccTxVcDemandUpdateCallback -* @sa IxAtmdAccTxVcDemandClearCallback -* @sa IxAtmdAccTxSchVcIdGetCallback -* @sa ixAtmdAccPortTxScheduledModeEnable -* -* @param port @ref IxAtmLogicalPort [in] - Specifies the ATM logical port on which the VC is -* established -* @param vpi unsigned int [in] - For AAL0/AAL5 specifies the ATM vpi on which the -* VC is established. -* For OAM specifies the dedicated "OAM Tx channel" VPI. -* @param vci unsigned int [in] - For AAL0/AAL5 specifies the ATM vci on which the -* VC is established. -* For OAM specifies the dedicated "OAM Tx channel" VCI. -* @param connId @ref IxAtmConnId [in] - specifies the IxAtmdAcc connection Id already -* associated with this VC -* @param vcId int* [out] - pointer to a vcId -* -* @return @li IX_SUCCESS the function is returning a Scheduler vcId for this -* VC -* @return @li IX_FAIL the function cannot process scheduling for this VC. -* the contents of vcId is unspecified -* -*/ -typedef IX_STATUS (*IxAtmdAccTxSchVcIdGetCallback) (IxAtmLogicalPort port, - unsigned int vpi, - unsigned int vci, - IxAtmConnId connId, - int *vcId); - -/* ------------------------------------------------------ - Part of the IxAtmdAcc interface related to RX traffic - ------------------------------------------------------ */ - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @fn ixAtmdAccRxDispatcherRegister ( - IxAtmRxQueueId queueId, - IxAtmdAccRxDispatcher callback) - * - * @brief Register a notification callback to be invoked when there is - * at least one entry on a particular Rx queue. - * - * This function registers a callback to be invoked when there is at - * least one entry in a particular queue. The registered callback is - * called every time when the hardware adds one or more pdus to the - * specified Rx queue. - * - * This function cannot be used when a Rx Vc using this queue is - * already existing. - * - * @note -The callback function can be the API function - * @a ixAtmdAccRxDispatch() : every time the threhold level - * of the queue is reached, the ixAtmdAccRxDispatch() is - * invoked to remove all entries from the queue. - * - * @sa ixAtmdAccRxDispatch - * @sa IxAtmdAccRxDispatcher - * - * @param queueId @ref IxAtmRxQueueId [in] RX queue identification - * @param callback @ref IxAtmdAccRxDispatcher [in] function triggering the delivery of incoming - * traffic. This parameter cannot be a null pointer. - * - * @return @li IX_SUCCESS Successful call to @a ixAtmdAccRxDispatcherRegister() - * @return @li IX_FAIL error in the parameters, or there is an - * already active RX VC for this queue or some unspecified - * internal error occurred. - * - */ -PUBLIC IX_STATUS ixAtmdAccRxDispatcherRegister ( - IxAtmRxQueueId queueId, - IxAtmdAccRxDispatcher callback); - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @fn ixAtmdAccRxDispatch (IxAtmRxQueueId rxQueueId, - unsigned int numberOfPdusToProcess, - unsigned int *numberOfPdusProcessedPtr) - * - * - * @brief Control function which executes Rx processing for a particular - * Rx stream. - * - * The @a IxAtmdAccRxDispatch() function is used to process received Pdus - * available from one of the two incoming RX streams. When this function - * is invoked, the incoming traffic (up to the number of PDUs passed as - * a parameter) will be transferred to the IxAtmdAcc users through the - * callback @a IxAtmdAccRxVcRxCallback(), as registered during the - * @a ixAtmdAccRxVcConnect() call. - * - * The user receive callbacks will be executed in the context of this - * function. - * - * Failing to use this function on a regular basis when there is traffic - * will block incoming traffic and can result in Pdus being dropped by - * the hardware. - * - * This should be used to control when received pdus are handed off from - * the hardware to Aal users from a particluar stream. The function can - * be used from a timer context, or can be registered as a callback in - * response to an rx stream threshold event, or can be used inside an - * active polling mechanism which is under user control. - * - * @note - The signature of this function is directly compatible with the - * callback prototype which can be register with @a ixAtmdAccRxDispatcherRegister(). - * - * @sa ixAtmdAccRxDispatcherRegister - * @sa IxAtmdAccRxVcRxCallback - * @sa ixAtmdAccRxVcFreeEntriesQuery - * - * @param rxQueueId @ref IxAtmRxQueueId [in] - indicates which RX queue to process. - * @param numberOfPdusToProcess unsigned int [in] - indicates the maxiumum number of PDU to - * remove from the RX queue. A value of IX_ATMDACC_ALLPDUS indicates - * to process all PDUs from the queue. This includes at least the PDUs - * in the queue when the fuction is invoked. Because of real-time - * constraints, there is no guarantee thatthe queue will be empty - * when the function exits. If this parameter is greater than the - * number of entries of the queues, the function will succeed - * and the parameter numberOfPdusProcessedPtr will reflect the exact - * number of PDUs processed. - * @param *numberOfPdusProcessedPtr unsigned int [out] - indicates the actual number of PDU - * processed during this call. This parameter cannot be a null - * pointer. - * - * @return @li IX_SUCCESS the number of PDUs as indicated in - * numberOfPdusProcessedPtr are removed from the RX queue and the VC callback - * are called. - * @return @li IX_FAIL invalid parameters or some unspecified internal - * error occured. - * - */ -PUBLIC IX_STATUS ixAtmdAccRxDispatch (IxAtmRxQueueId rxQueueId, - unsigned int numberOfPdusToProcess, - unsigned int *numberOfPdusProcessedPtr); - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @fn ixAtmdAccRxLevelQuery (IxAtmRxQueueId rxQueueId, - unsigned int *numberOfPdusPtr) - * - * @brief Query the number of entries in a particular RX queue. - * - * This function is used to retrieve the number of pdus received by - * the hardware and ready for distribution to users. - * - * @param rxQueueId @ref IxAtmRxQueueId [in] - indicates which of two RX queues to query. - * @param numberOfPdusPtr unsigned int* [out] - Pointer to store the number of available - * PDUs in the RX queue. This parameter cannot be a null pointer. - * - * @return @li IX_SUCCESS the value in numberOfPdusPtr specifies the - * number of incoming pdus waiting in this queue - * @return @li IX_FAIL an error occurs during processing. - * The value in numberOfPdusPtr is unspecified. - * - * @note - This function is reentrant, doesn't use system resources - * and can be used from an interrupt context. - * - */ -PUBLIC IX_STATUS ixAtmdAccRxLevelQuery (IxAtmRxQueueId rxQueueId, - unsigned int *numberOfPdusPtr); - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @fn ixAtmdAccRxQueueSizeQuery (IxAtmRxQueueId rxQueueId, - unsigned int *numberOfPdusPtr) - * - * @brief Query the size of a particular RX queue. - * - * This function is used to retrieve the number of pdus the system is - * able to queue when reception is complete. - * - * @param rxQueueId @ref IxAtmRxQueueId [in] - indicates which of two RX queues to query. - * @param numberOfPdusPtr unsigned int* [out] - Pointer to store the number of pdus - * the system is able to queue in the RX queue. This parameter - * cannot be a null pointer. - * - * @return @li IX_SUCCESS the value in numberOfPdusPtr specifies the - * number of pdus the system is able to queue. - * @return @li IX_FAIL an error occurs during processing. - * The value in numberOfPdusPtr is unspecified. - * - * @note - This function is reentrant, doesn't use system resources - * and can be used from an interrupt context. - * - */ -PUBLIC IX_STATUS ixAtmdAccRxQueueSizeQuery (IxAtmRxQueueId rxQueueId, - unsigned int *numberOfPdusPtr); - -/* ------------------------------------------------------ - Part of the IxAtmdAcc interface related to TX traffic - ------------------------------------------------------ */ - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @fn ixAtmdAccPortTxFreeEntriesQuery (IxAtmLogicalPort port, - unsigned int *numberOfCellsPtr) - * - * @brief Get the number of available cells the system can accept for - * transmission. - * - * The function is used to retrieve the number of cells that can be - * queued for transmission to the hardware. - * - * This number is based on the worst schedule table where one cell - * is stored in one schedule table entry, depending on the pdus size - * and mbuf size and fragmentation. - * - * This function doesn't use system resources and can be used from a - * timer context, or can be associated with a threshold event, or can - * be used inside an active polling mechanism - * - * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] - * @param numberOfCellsPtr unsigned int* [out] - number of available cells. - * This parameter cannot be a null pointer. - * - * @sa ixAtmdAccPortTxProcess - * - * @return @li IX_SUCCESS numberOfCellsPtr contains the number of cells that can be scheduled - * for this port. - * @return @li IX_FAIL error in the parameters, or some processing error - * occured. - * - */ -PUBLIC IX_STATUS ixAtmdAccPortTxFreeEntriesQuery (IxAtmLogicalPort port, - unsigned int *numberOfCellsPtr); - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @fn ixAtmdAccPortTxCallbackRegister (IxAtmLogicalPort port, - unsigned int numberOfCells, - IxAtmdAccPortTxLowCallback callback) - * - * @brief Configure the Tx port threshold value and register a callback to handle - * threshold notifications. - * - * This function sets the threshold in cells - * - * @sa ixAtmdAccPortTxCallbackRegister - * @sa ixAtmdAccPortTxProcess - * @sa ixAtmdAccPortTxFreeEntriesQuery - * - * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] - * @param numberOfCells unsigned int [in] - threshold value which triggers the callback - * invocation, This number has to be one of the - * values 0,1,2,4,8,16,32 .... - * The maximum value cannot be more than half of the txVc queue - * size (which can be retrieved using @a ixAtmdAccPortTxFreeEntriesQuery() - * before any Tx traffic is sent for this port) - * @param callback @ref IxAtmdAccPortTxLowCallback [in] - callback function to invoke when the threshold - * level is reached. - * This parameter cannot be a null pointer. - * - * @return @li IX_SUCCESS Successful call to @a ixAtmdAccPortTxCallbackRegister() - * @return @li IX_FAIL error in the parameters, Tx channel already set for this port - * threshold level is not correct or within the range regarding the - * queue size:or unspecified error during processing: - * - * @note - This callback function get called when the threshold level drops from - * (numberOfCells+1) cells to (numberOfCells) cells - * - * @note - This function should be called during system initialisation, - * outside an interrupt context - * - */ -PUBLIC IX_STATUS ixAtmdAccPortTxCallbackRegister (IxAtmLogicalPort port, - unsigned int numberOfCells, - IxAtmdAccPortTxLowCallback callback); - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @fn ixAtmdAccPortTxScheduledModeEnable (IxAtmLogicalPort port, - IxAtmdAccTxVcDemandUpdateCallback vcDemandUpdateCallback, - IxAtmdAccTxVcDemandClearCallback vcDemandClearCallback, - IxAtmdAccTxSchVcIdGetCallback vcIdGetCallback) - * - * @brief Put the port into Scheduled Mode - * - * This function puts the specified port into scheduled mode of - * transmission which means an external s/w entity controls the - * transmission of cells on this port. This faciltates traffic shaping on - * the port. - * - * Any buffers submitted on a VC for this port will be queued in IxAtmdAcc. - * The transmission of these buffers to and by the hardware will be driven - * by a transmit schedule submitted regulary in calls to - * @a ixAtmdAccPortTxProcess() by traffic shaping entity. - * - * The transmit schedule is expected to be dynamic in nature based on - * the demand in cells for each VC on the port. Hence the callback - * parameters provided to this function allow IxAtmdAcc to inform the - * shaping entity of demand changes for each VC on the port. - * - * By default a port is in Unscheduled Mode so if this function is not - * called, transmission of data is done without sheduling rules, on a - * first-come, first-out basis. - * - * Once a port is put in scheduled mode it cannot be reverted to - * un-scheduled mode. Note that unscheduled mode is not supported - * in ixp425 1.0 - * - * @note - This function should be called before any VCs have be - * connected on a port. Otherwise this function call will return failure. - * - * @note - This function uses internal locks and should not be called from - * an interrupt context - * - * @sa IxAtmdAccTxVcDemandUpdateCallback - * @sa IxAtmdAccTxVcDemandClearCallback - * @sa IxAtmdAccTxSchVcIdGetCallback - * @sa ixAtmdAccPortTxProcess - * - * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] - * @param vcDemandUpdateCallback @ref IxAtmdAccTxVcDemandUpdateCallback [in] - callback function used to update - * the number of outstanding cells for transmission. This parameter - * cannot be a null pointer. - * @param vcDemandClearCallback @ref IxAtmdAccTxVcDemandClearCallback [in] - callback function used to remove all - * clear the number of outstanding cells for a VC. This parameter - * cannot be a null pointer. - * @param vcIdGetCallback @ref IxAtmdAccTxSchVcIdGetCallback [in] - callback function used to exchange vc - * Identifiers between IxAtmdAcc and the entity supplying the - * transmit schedule. This parameter cannot be a null pointer. - * - * @return @li IX_SUCCESS scheduler registration is complete and the port - * is now in scheduled mode. - * @return @li IX_FAIL failed (wrong parameters, or traffic is already - * enabled on this port, possibly without ATM shaping) - * - */ -PUBLIC IX_STATUS ixAtmdAccPortTxScheduledModeEnable (IxAtmLogicalPort port, - IxAtmdAccTxVcDemandUpdateCallback vcDemandUpdateCallback, - IxAtmdAccTxVcDemandClearCallback vcDemandClearCallback, - IxAtmdAccTxSchVcIdGetCallback vcIdGetCallback); - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @fn ixAtmdAccPortTxProcess (IxAtmLogicalPort port, - IxAtmScheduleTable* scheduleTablePtr) - * - * @brief Transmit queue cells to the H/W based on the supplied schedule - * table. - * - * This function @a ixAtmdAccPortTxProcess() process the schedule - * table provided as a parameter to the function. As a result cells are - * sent to the underlaying hardware for transmission. - * - * The schedule table is executed in its entirety or not at all. So the - * onus is on the caller not to submit a table containing more cells than - * can be transmitted at that point. The maximum numbers that can be - * transmitted is guaranteed to be the number of cells as returned by the - * function @a ixAtmdAccPortTxFreeEntriesQuery(). - * - * When the scheduler is invoked on a threshold level, IxAtmdAcc gives the - * minimum number of cells (to ensure the callback will fire again later) - * and the maximum number of cells that @a ixAtmdAccPortTxProcess() - * will be able to process (assuming the ATM scheduler is able - * to produce the worst-case schedule table, i.e. one entry per cell). - * - * When invoked ouside a threshold level, the overall number of cells of - * the schedule table should be less than the number of cells returned - * by the @a ixAtmdAccPortTxFreeEntriesQuery() function. - * - * After invoking the @a ixAtmdAccPortTxProcess() function, it is the - * user choice to query again the queue level with the function - * @a ixAtmdAccPortTxFreeEntriesQuery() and, depending on a new cell - * number, submit an other schedule table. - * - * IxAtmdAcc will check that the number of cells in the schedule table - * is compatible with the current transmit level. If the - * - * Obsolete or invalid connection Id will be silently discarded. - * - * This function is not reentrant for the same port. - * - * This functions doesn't use system resources and can be used inside an - * interrupt context. - * - * This function is used as a response to the hardware requesting more - * cells to transmit. - * - * @sa ixAtmdAccPortTxScheduledModeEnable - * @sa ixAtmdAccPortTxFreeEntriesQuery - * @sa ixAtmdAccPortTxCallbackRegister - * @sa ixAtmdAccPortEnable - * - * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] - * @param scheduleTablePtr @ref IxAtmScheduleTable* [in] - pointer to a scheduler update table. The - * content of this table is not modified by this function. This - * parameter cannot be a null pointer. - * - * @return @li IX_SUCCESS the schedule table process is complete - * and cells are transmitted to the hardware - * @return @li IX_ATMDACC_WARNING : Traffic will be dropped: the schedule table exceed - * the hardware capacity If this error is ignored, further traffic - * and schedule will work correctly. - * Overscheduling does not occur when the schedule table does - * not contain more entries that the number of free entries returned - * by @a ixAtmdAccPortTxFreeEntriesQuery(). - * However, Disconnect attempts just after this error will fail permanently - * with the error code @a IX_ATMDACC_RESOURCES_STILL_ALLOCATED, and it is - * necessary to disable the port to make @a ixAtmdAccTxVcTryDisconnect() - * successful. - * @return @li IX_FAIL a wrong parameter is supplied, or the format of - * the schedule table is invalid, or the port is not Enabled, or - * an internal severe error occured. No cells is transmitted to the hardware - * - * @note - If the failure is linked to an overschedule of data cells - * the result is an inconsistency in the output traffic (one or many - * cells may be missing and the traffic contract is not respected). - * - */ -PUBLIC IX_STATUS ixAtmdAccPortTxProcess (IxAtmLogicalPort port, - IxAtmScheduleTable* scheduleTablePtr); - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @fn ixAtmdAccTxDoneDispatch (unsigned int numberOfPdusToProcess, - unsigned int *numberOfPdusProcessedPtr) - * - * @brief Process a number of pending transmit done pdus from the hardware. - * - * As a by-product of Atm transmit operation buffers which transmission - * is complete need to be recycled to users. This function is invoked - * to service the oustanding list of transmitted buffers and pass them - * to VC users. - * - * Users are handed back pdus by invoking the free callback registered - * during the @a ixAtmdAccTxVcConnect() call. - * - * There is a single Tx done stream servicing all active Atm Tx ports - * which can contain a maximum of 64 entries. If this stream fills port - * transmission will stop so this function must be call sufficently - * frequently to ensure no disruption to the transmit operation. - * - * This function can be used from a timer context, or can be associated - * with a TxDone level threshold event (see @a ixAtmdAccTxDoneDispatcherRegister() ), - * or can be used inside an active polling mechanism under user control. - * - * For ease of use the signature of this function is compatible with the - * TxDone threshold event callback prototype. - * - * This functions can be used inside an interrupt context. - * - * @sa ixAtmdAccTxDoneDispatcherRegister - * @sa IxAtmdAccTxVcBufferReturnCallback - * @sa ixAtmdAccTxDoneLevelQuery - * - * @param numberOfPdusToProcess unsigned int [in] - maxiumum number of pdus to remove - * from the TX Done queue - * @param *numberOfPdusProcessedPtr unsigned int [out] - number of pdus removed from - * the TX Done queue. This parameter cannot be a null pointer. - * - * @return @li IX_SUCCESS the number of pdus as indicated in - * numberOfPdusToProcess are removed from the TX Done hardware - * and passed to the user through the Tx Done callback registered - * during a call to @a ixAtmdAccTxVcConnect() - * @return @li IX_FAIL invalid parameters or numberOfPdusProcessedPtr is - * a null pointer or some unspecified internal error occured. - * - */ -PUBLIC IX_STATUS -ixAtmdAccTxDoneDispatch (unsigned int numberOfPdusToProcess, - unsigned int *numberOfPdusProcessedPtr); - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @fn ixAtmdAccTxDoneLevelQuery (unsigned int *numberOfPdusPtr) - * - * @brief Query the current number of transmit pdus ready for - * recycling. - * - * This function is used to get the number of transmitted pdus which - * the hardware is ready to hand back to user. - * - * This function can be used from a timer context, or can be associated - * with a threshold event, on can be used inside an active polling - * mechanism - * - * @sa ixAtmdAccTxDoneDispatch - * - * @param *numberOfPdusPtr unsigned int [out] - Pointer to the number of pdus transmitted - * at the time of this function call, and ready for recycling - * This parameter cannot be a null pointer. - * - * @return @li IX_SUCCESS numberOfPdusPtr contains the number of pdus - * ready for recycling at the time of this function call - * - * @return @li IX_FAIL wrong parameter (null pointer as parameter).or - * unspecified rocessing error occurs..The value in numberOfPdusPtr - * is unspecified. - * - */ -PUBLIC IX_STATUS -ixAtmdAccTxDoneLevelQuery (unsigned int *numberOfPdusPtr); - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @fn ixAtmdAccTxDoneQueueSizeQuery (unsigned int *numberOfPdusPtr) - * - * @brief Query the TxDone queue size. - * - * This function is used to get the number of pdus which - * the hardware is able to store after transmission is complete - * - * The returned value can be used to set a threshold and enable - * a callback to be notified when the number of pdus is going over - * the threshold. - * - * @sa ixAtmdAccTxDoneDispatcherRegister - * - * @param *numberOfPdusPtr unsigned int [out] - Pointer to the number of pdus the system - * is able to queue after transmission - * - * @return @li IX_SUCCESS numberOfPdusPtr contains the the number of - * pdus the system is able to queue after transmission - * @return @li IX_FAIL wrong parameter (null pointer as parameter).or - * unspecified rocessing error occurs..The value in numberOfPdusPtr - * is unspecified. - * - * @note - This function is reentrant, doesn't use system resources - * and can be used from an interrupt context. - */ -PUBLIC IX_STATUS -ixAtmdAccTxDoneQueueSizeQuery (unsigned int *numberOfPdusPtr); - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @fn ixAtmdAccTxDoneDispatcherRegister (unsigned int numberOfPdus, - IxAtmdAccTxDoneDispatcher notificationCallback) - * - * @brief Configure the Tx Done stream threshold value and register a - * callback to handle threshold notifications. - * - * This function sets the threshold level in term of number of pdus at - * which the supplied notification function should be called. - * - * The higher the threshold value is, the less events will be necessary - * to process transmitted buffers. - * - * Transmitted buffers recycling implementation is a sytem-wide mechanism - * and needs to be set prior any traffic is started. If this threshold - * mechanism is not used, the user is responsible for polling the - * transmitted buffers thanks to @a ixAtmdAccTxDoneDispatch() and - * @a ixAtmdAccTxDoneLevelQuery() functions. - * - * This function should be called during system initialisation outside - * an interrupt context - * - * @sa ixAtmdAccTxDoneDispatcherRegister - * @sa ixAtmdAccTxDoneDispatch - * @sa ixAtmdAccTxDoneLevelQuery - * - * @param numberOfPdus unsigned int [in] - The number of TxDone pdus which triggers the - * callback invocation This number has to be a power of 2, one of the - * values 0,1,2,4,8,16,32 ... - * The maximum value cannot be more than half of the txDone queue - * size (which can be retrieved using @a ixAtmdAccTxDoneQueueSizeQuery()) - * @param notificationCallback @ref IxAtmdAccTxDoneDispatcher [in] - The function to invoke. (This - * parameter can be @a ixAtmdAccTxDoneDispatch()).This - * parameter ust not be a null pointer. - * - * @return @li IX_SUCCESS Successful call to ixAtmdAccTxDoneDispatcherRegister - * @return @li IX_FAIL error in the parameters: - * - * @note - The notificationCallback will be called exactly when the threshold level - * will increase from (numberOfPdus) to (numberOfPdus+1) - * - * @note - If there is no Tx traffic, there is no guarantee that TxDone Pdus will - * be released to the user (when txDone level is permanently under the threshold - * level. One of the preffered way to return resources to the user is to use - * a mix of txDone notifications, used together with a slow - * rate timer and an exclusion mechanism protecting from re-entrancy - * - * @note - The TxDone threshold will only hand back buffers when the threshold level is - * crossed. Setting this threshold to a great number reduce the interrupt rate - * and the cpu load, but also increase the number of outstanding mbufs and has - * a system wide impact when these mbufs are needed by other components. - * - */ -PUBLIC IX_STATUS ixAtmdAccTxDoneDispatcherRegister (unsigned int numberOfPdus, - IxAtmdAccTxDoneDispatcher notificationCallback); - -/* ------------------------------------------------------ - Part of the IxAtmdAcc interface related to Utopia config - ------------------------------------------------------ */ - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @defgroup IxAtmdAccUtopiaCtrlAPI IXP400 ATM Driver Access (IxAtmdAcc) Utopia Control API - * - * @brief The public API for the IXP400 Atm Driver Control component - * - * IxAtmdAcc is the low level interface by which AAL PDU get - * transmitted to,and received from the Utopia bus - * - * This part is related to the UTOPIA configuration. - * - * @{ - */ - -/** - * - * @brief Utopia configuration - * - * This structure is used to set the Utopia parameters - * @li contains the values of Utopia registers, to be set during initialisation - * @li contains debug commands for NPE, to be used during development steps - * - * @note - the exact description of all parameters is done in the Utopia reference - * documents. - * - */ -typedef struct -{ - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtTxConfig_ - * @brief Utopia Tx Config Register - */ - struct UtTxConfig_ - { - - unsigned int reserved_1:1; /**< [31] These bits are always 0.*/ - unsigned int txInterface:1; /**< [30] Utopia Transmit Interface. The following encoding - * is used to set the Utopia Transmit interface as ATM master - * or PHY slave: - * @li 1 - PHY - * @li 0 - ATM - */ - unsigned int txMode:1; /**< [29] Utopia Transmit Mode. The following encoding is used - * to set the Utopia Transmit mode to SPHY or MPHY: - * @li 1 - SPHY - * @li 0 - MPHY - */ - unsigned int txOctet:1; /**< [28] Utopia Transmit cell transfer protocol. Used to set - * the Utopia cell transfer protocol to Octet-level handshaking. - * Note this is only applicable in SPHY mode. - * @li 1 - Octet-handshaking enabled - * @li 0 - Cell-handshaking enabled - */ - unsigned int txParity:1; /**< [27] Utopia Transmit parity enabled when set. TxEvenParity - * defines the parity format odd/even. - * @li 1 - Enable Parity generation. - * @li 0 - ut_op_prty held low. - */ - unsigned int txEvenParity:1; /**< [26] Utopia Transmit Parity Mode - * @li 1 - Even Parity Generated. - * @li 0 - Odd Parity Generated. - */ - unsigned int txHEC:1; /**< [25] Header Error Check Insertion Mode. Specifies if the transmit - * cell header check byte is calculated and inserted when set. - * @li 1 - Generate HEC. - * @li 0 - Disable HEC generation. - */ - unsigned int txCOSET:1; /**< [24] If enabled the HEC is Exclusive-ORÆed with the value 0x55 before - * being presented on the Utopia bus. - * @li 1 - Enable HEC ExOR with value 0x55 - * @li 0 - Use generated HEC value. - */ - - unsigned int reserved_2:1; /**< [23] These bits are always 0 - */ - unsigned int txCellSize:7; /**< [22:16] Transmit expected cell size. Configures the cell size - * for the transmit module: Values between 52-64 are valid. - */ - unsigned int reserved_3:3; /**< [15:13] These bits are always 0 */ - unsigned int txAddrRange:5; /**< [12:8] When configured as an ATM master in MPHY mode this - * register specifies the upper limit of the PHY polling logical - * range. The number of active PHYs are TxAddrRange + 1. - */ - unsigned int reserved_4:3; /**< [7:5] These bits are always 0 */ - unsigned int txPHYAddr:5; /**< [4:0] When configured as a slave in an MPHY system this register - * specifies the physical address of the PHY. - */ - } - - utTxConfig; /**< Tx config Utopia register */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtTxStatsConfig_ - * @brief Utopia Tx stats Register - */ - struct UtTxStatsConfig_ - { - - unsigned int vpi:12; /**< [31:20] ATM VPI [11:0] OR GFC [3:0] and VPI [7:0] - @li Note: if VCStatsTxGFC is set to 0 the GFC field is ignored in test. */ - - unsigned int vci:16; /**< [19:4] ATM VCI [15:0] or PHY Address[4] */ - - unsigned int pti:3; /**< [3:1] ATM PTI [2:0] or PHY Address[3:1] - @li Note: if VCStatsTxPTI is set to 0 the PTI field is ignored in test. - @li Note: if VCStatsTxEnb is set to 0 only the transmit PHY port - address as defined by this register is used for ATM statistics [4:0]. */ - - unsigned int clp:1; /**< [0] ATM CLP or PHY Address [0] - @li Note: if VCStatsTxCLP is set to 0 the CLP field is ignored in test. - @li Note: if VCStatsTxEnb is set to 0 only the transmit PHY port - address as defined by this register is used for ATM statistics [4:0]. */ - } - - utTxStatsConfig; /**< Tx stats config Utopia register */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtTxDefineIdle_ - * @brief Utopia Tx idle cells Register - */ - struct UtTxDefineIdle_ - { - - unsigned int vpi:12; /**< [31:20] ATM VPI [11:0] OR GFC [3:0] and VPI [7:0] - @li Note: if VCIdleTxGFC is set to 0 the GFC field is ignored in test. */ - - unsigned int vci:16; /**< [19:4] ATM VCI [15:0] */ - - unsigned int pti:3; /**< [3:1] ATM PTI PTI [2:0] - @li Note: if VCIdleTxPTI is set to 0 the PTI field is ignored in test.*/ - - unsigned int clp:1; /**< [0] ATM CLP [0] - @li Note: if VCIdleTxCLP is set to 0 the CLP field is ignored in test.*/ - } - - utTxDefineIdle; /**< Tx idle cell config Utopia register */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtTxEnableFields_ - * @brief Utopia Tx ienable fields Register - */ - struct UtTxEnableFields_ - { - - unsigned int defineTxIdleGFC:1; /**< [31] This register is used to include or exclude the GFC - field of the ATM header when testing for Idle cells. - @li 1 - GFC field is valid. - @li 0 - GFC field ignored.*/ - - unsigned int defineTxIdlePTI:1; /**< [30] This register is used to include or exclude the PTI - field of the ATM header when testing for Idle cells. - @li 1 - PTI field is valid - @li 0 - PTI field ignored.*/ - - unsigned int defineTxIdleCLP:1; /**< [29] This register is used to include or - exclude the CLP field of the ATM header when testing for Idle cells. - @li 1 - CLP field is valid. - @li 0 - CLP field ignored. */ - - unsigned int phyStatsTxEnb:1; /**< [28] This register is used to enable or disable ATM - statistics gathering based on the specified PHY address as defined - in TxStatsConfig register. - @li 1 - Enable statistics for specified transmit PHY address. - @li 0 - Disable statistics for specified transmit PHY address. */ - - unsigned int vcStatsTxEnb:1; /**< [27] This register is used to change the ATM - statistics-gathering mode from the specified logical PHY address - to a specific VPI/VCI address. - @li 1 - Enable statistics for specified VPI/VCI address. - @li 0 - Disable statistics for specified VPI/VCI address */ - - unsigned int vcStatsTxGFC:1; /**< [26] This register is used to include or exclude the GFC - field of the ATM header when ATM VPI/VCI statistics are enabled. - GFC is only available at the UNI and uses the first 4-bits of - the VPI field. - @li 1 - GFC field is valid - @li 0 - GFC field ignored.*/ - - unsigned int vcStatsTxPTI:1; /**< [25] This register is used to include or exclude the PTI - field of the ATM header when ATM VPI/VCI statistics are enabled. - @li 1 - PTI field is valid - @li 0 - PTI field ignored.*/ - - unsigned int vcStatsTxCLP:1; /**< [24] This register is used to include or exclude the CLP - field of the ATM header when ATM VPI/VCI statistics are enabled. - @li 1 - CLP field is valid - @li 0 - CLP field ignored. */ - - unsigned int reserved_1:3; /**< [23-21] These bits are always 0 */ - - unsigned int txPollStsInt:1; /**< [20] Enable the assertion of the ucp_tx_poll_sts condition - where there is a change in polling status. - @li 1 - ucp_tx_poll_sts asserted whenever there is a change in status - @li 0 - ucp_tx_poll_sts asserted if ANY transmit PHY is available - */ - unsigned int txCellOvrInt:1; /**< [19] Enable TxCellCount overflow CBI Transmit Status condition - assertion. - @li 1 - If TxCellCountOvr is set assert the Transmit Status Condition. - @li 0 - No CBI Transmit Status condition assertion */ - - unsigned int txIdleCellOvrInt:1; /**< [18] Enable TxIdleCellCount overflow Transmit Status Condition - @li 1 - If TxIdleCellCountOvr is set assert the Transmit Status Condition - @li 0 - No CBI Transmit Status condition assertion..*/ - - unsigned int enbIdleCellCnt:1; /**< [17] Enable Transmit Idle Cell Count. - @li 1 - Enable count of Idle cells transmitted. - @li 0 - No count is maintained. */ - - unsigned int enbTxCellCnt:1; /**< [16] Enable Transmit Valid Cell Count of non-idle/non-error cells - @li 1 - Enable count of valid cells transmitted- non-idle/non-error - @li 0 - No count is maintained.*/ - - unsigned int reserved_2:16; /**< [15:0] These bits are always 0 */ - } utTxEnableFields; /**< Tx enable Utopia register */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtTxTransTable0_ - * @brief Utopia Tx translation table Register - */ - struct UtTxTransTable0_ - { - - unsigned int phy0:5; /**< [31-27] Tx Mapping value of logical phy 0 */ - - unsigned int phy1:5; /**< [26-22] Tx Mapping value of logical phy 1 */ - - unsigned int phy2:5; /**< [21-17] Tx Mapping value of logical phy 2 */ - - unsigned int reserved_1:1; /**< [16] These bits are always 0.*/ - - unsigned int phy3:5; /**< [15-11] Tx Mapping value of logical phy 3 */ - - unsigned int phy4:5; /**< [10-6] Tx Mapping value of logical phy 4 */ - - unsigned int phy5:5; /**< [5-1] Tx Mapping value of logical phy 5 */ - - unsigned int reserved_2:1; /**< [0] These bits are always 0 */ - } utTxTransTable0; /**< Tx translation table */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtTxTransTable1_ - * @brief Utopia Tx translation table Register - */ - struct UtTxTransTable1_ - { - - unsigned int phy6:5; /**< [31-27] Tx Mapping value of logical phy 6 */ - - unsigned int phy7:5; /**< [26-22] Tx Mapping value of logical phy 7 */ - - unsigned int phy8:5; /**< [21-17] Tx Mapping value of logical phy 8 */ - - unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */ - - unsigned int phy9:5; /**< [15-11] Tx Mapping value of logical phy 3 */ - - unsigned int phy10:5; /**< [10-6] Tx Mapping value of logical phy 4 */ - - unsigned int phy11:5; /**< [5-1] Tx Mapping value of logical phy 5 */ - - unsigned int reserved_2:1; /**< [0] These bits are always 0 */ - } utTxTransTable1; /**< Tx translation table */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtTxTransTable2_ - * @brief Utopia Tx translation table Register - */ - struct UtTxTransTable2_ - { - - unsigned int phy12:5; /**< [31-27] Tx Mapping value of logical phy 6 */ - - unsigned int phy13:5; /**< [26-22] Tx Mapping value of logical phy 7 */ - - unsigned int phy14:5; /**< [21-17] Tx Mapping value of logical phy 8 */ - - unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */ - - unsigned int phy15:5; /**< [15-11] Tx Mapping value of logical phy 3 */ - - unsigned int phy16:5; /**< [10-6] Tx Mapping value of logical phy 4 */ - - unsigned int phy17:5; /**< [5-1] Tx Mapping value of logical phy 5 */ - - unsigned int reserved_2:1; /**< [0] These bits are always 0 */ - } utTxTransTable2; /**< Tx translation table */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtTxTransTable3_ - * @brief Utopia Tx translation table Register - */ - struct UtTxTransTable3_ - { - - unsigned int phy18:5; /**< [31-27] Tx Mapping value of logical phy 6 */ - - unsigned int phy19:5; /**< [26-22] Tx Mapping value of logical phy 7 */ - - unsigned int phy20:5; /**< [21-17] Tx Mapping value of logical phy 8 */ - - unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */ - - unsigned int phy21:5; /**< [15-11] Tx Mapping value of logical phy 3 */ - - unsigned int phy22:5; /**< [10-6] Tx Mapping value of logical phy 4 */ - - unsigned int phy23:5; /**< [5-1] Tx Mapping value of logical phy 5 */ - - unsigned int reserved_2:1; /**< [0] These bits are always 0 */ - } utTxTransTable3; /**< Tx translation table */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtTxTransTable4_ - * @brief Utopia Tx translation table Register - */ - struct UtTxTransTable4_ - { - - unsigned int phy24:5; /**< [31-27] Tx Mapping value of logical phy 6 */ - - unsigned int phy25:5; /**< [26-22] Tx Mapping value of logical phy 7 */ - - unsigned int phy26:5; /**< [21-17] Tx Mapping value of logical phy 8 */ - - unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */ - - unsigned int phy27:5; /**< [15-11] Tx Mapping value of logical phy 3 */ - - unsigned int phy28:5; /**< [10-6] Tx Mapping value of logical phy 4 */ - - unsigned int phy29:5; /**< [5-1] Tx Mapping value of logical phy 5 */ - - unsigned int reserved_2:1; /**< [0] These bits are always 0 */ - } utTxTransTable4; /**< Tx translation table */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtTxTransTable5_ - * @brief Utopia Tx translation table Register - */ - struct UtTxTransTable5_ - { - - unsigned int phy30:5; /**< [31-27] Tx Mapping value of logical phy 6 */ - - unsigned int reserved_1:27; /**< [26-0] These bits are always 0 */ - - } utTxTransTable5; /**< Tx translation table */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtRxConfig_ - * @brief Utopia Rx config Register - */ - struct UtRxConfig_ - { - - unsigned int rxInterface:1; /**< [31] Utopia Receive Interface. The following encoding is used - to set the Utopia Receive interface as ATM master or PHY slave: - @li 1 - PHY - @li 0 - ATM */ - - unsigned int rxMode:1; /**< [30] Utopia Receive Mode. The following encoding is used to set - the Utopia Receive mode to SPHY or MPHY: - @li 1 - SPHY - @li 0 - MPHY */ - - unsigned int rxOctet:1; /**< [29] Utopia Receive cell transfer protocol. Used to set the Utopia - cell transfer protocol to Octet-level handshaking. Note this is only - applicable in SPHY mode. - @li 1 - Octet-handshaking enabled - @li 0 - Cell-handshaking enabled */ - - unsigned int rxParity:1; /**< [28] Utopia Receive Parity Checking enable. - @li 1 - Parity checking enabled - @li 0 - Parity checking disabled */ - - unsigned int rxEvenParity:1;/**< [27] Utopia Receive Parity Mode - @li 1 - Check for Even Parity - @li 0 - Check for Odd Parity.*/ - - unsigned int rxHEC:1; /**< [26] RxHEC Header Error Check Mode. Enables/disables cell header - error checking on the received cell header. - @li 1 - HEC checking enabled - @li 0 - HEC checking disabled */ - - unsigned int rxCOSET:1; /**< [25] If enabled the HEC is Exclusive-ORÆed with the value 0x55 - before being tested with the received HEC. - @li 1 - Enable HEC ExOR with value 0x55. - @li 0 - Use generated HEC value.*/ - - unsigned int rxHECpass:1; /**< [24] Specifies if the incoming cell HEC byte should be transferred - after optional processing to the NPE2 Coprocessor Bus Interface or - if it should be discarded. - @li 1 - HEC maintained 53-byte/UDC cell sent to NPE2. - @li 0 - HEC discarded 52-byte/UDC cell sent to NPE2 coprocessor.*/ - - unsigned int reserved_1:1; /**< [23] These bits are always 0 */ - - unsigned int rxCellSize:7; /**< [22:16] Receive cell size. Configures the receive cell size. - Values between 52-64 are valid */ - - unsigned int rxHashEnbGFC:1; /**< [15] Specifies if the VPI field [11:8]/GFC field should be - included in the Hash data input or if the bits should be padded - with 1Æb0. - @li 1 - VPI [11:8]/GFC field valid and used in Hash residue calculation. - @li 0 - VPI [11:8]/GFC field padded with 1Æb0 */ - - unsigned int rxPreHash:1; /**< [14] Enable Pre-hash value generation. Specifies if the - incoming cell data should be pre-hashed to allow VPI/VCI header look-up - in a hash table. - @li 1 - Pre-hashing enabled - @li 0 - Pre-hashing disabled */ - - unsigned int reserved_2:1; /**< [13] These bits are always 0 */ - - unsigned int rxAddrRange:5; /**< [12:8] In ATM master, MPHY mode, - * this register specifies the upper - * limit of the PHY polling logical range. The number of active PHYs are - * RxAddrRange + 1. - */ - unsigned int reserved_3:3; /**< [7-5] These bits are always 0 .*/ - unsigned int rxPHYAddr:5; /**< [4:0] When configured as a slave in an MPHY system this register - * specifies the physical address of the PHY. - */ - } utRxConfig; /**< Rx config Utopia register */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtRxStatsConfig_ - * @brief Utopia Rx stats config Register - */ - struct UtRxStatsConfig_ - { - - unsigned int vpi:12; /**< [31:20] ATM VPI VPI [11:0] OR GFC [3:0] and VPI [7:0] - @li Note: if VCStatsRxGFC is set to 0 the GFC field is ignored in test. */ - - unsigned int vci:16; /**< [19:4] VCI [15:0] or PHY Address [4] */ - - unsigned int pti:3; /**< [3:1] PTI [2:0] or or PHY Address [3:1] - @li Note: if VCStatsRxPTI is set to 0 the PTI field is ignored in test. - @li Note: if VCStatsRxEnb is set to 0 only the PHY port address is used - for statistics gathering.. */ - - unsigned int clp:1; /**< [0] CLP [0] or PHY Address [0] - @li Note: if VCStatsRxCLP is set to 0 the CLP field is ignored in test. - @li Note: if VCStatsRxEnb is set to 0 only the PHY port address is used - for statistics gathering.. */ - } utRxStatsConfig; /**< Rx stats config Utopia register */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtRxDefineIdle_ - * @brief Utopia Rx idle cells config Register - */ - struct UtRxDefineIdle_ - { - - unsigned int vpi:12; /**< [31:20] ATM VPI [11:0] OR GFC [3:0] and VPI [7:0] - @li Note: if VCIdleRxGFC is set to 0 the GFC field is ignored in test. */ - - unsigned int vci:16; /**< [19:4] ATM VCI [15:0] */ - - unsigned int pti:3; /**< [3:1] ATM PTI PTI [2:0] - @li Note: if VCIdleRxPTI is set to 0 the PTI field is ignored in test.*/ - - unsigned int clp:1; /**< [0] ATM CLP [0] - @li Note: if VCIdleRxCLP is set to 0 the CLP field is ignored in test.*/ - } utRxDefineIdle; /**< Rx idle cell config Utopia register */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtRxEnableFields_ - * @brief Utopia Rx enable Register - */ - struct UtRxEnableFields_ - { - - unsigned int defineRxIdleGFC:1;/**< [31] This register is used to include or exclude the GFC - field of the ATM header when testing for Idle cells. - @li 1 - GFC field is valid. - @li 0 - GFC field ignored.*/ - - unsigned int defineRxIdlePTI:1;/**< [30] This register is used to include or exclude the PTI - field of the ATM header when testing for Idle cells. - @li 1 - PTI field is valid. - @li 0 - PTI field ignored.*/ - - unsigned int defineRxIdleCLP:1;/**< [29] This register is used to include or exclude the CLP - field of the ATM header when testing for Idle cells. - @li 1 - CLP field is valid. - @li 0 - CLP field ignored.*/ - - unsigned int phyStatsRxEnb:1;/**< [28] This register is used to enable or disable ATM statistics - gathering based on the specified PHY address as defined in RxStatsConfig - register. - @li 1 - Enable statistics for specified receive PHY address. - @li 0 - Disable statistics for specified receive PHY address.*/ - - unsigned int vcStatsRxEnb:1;/**< [27] This register is used to enable or disable ATM statistics - gathering based on a specific VPI/VCI address. - @li 1 - Enable statistics for specified VPI/VCI address. - @li 0 - Disable statistics for specified VPI/VCI address.*/ - - unsigned int vcStatsRxGFC:1;/**< [26] This register is used to include or exclude the GFC field - of the ATM header when ATM VPI/VCI statistics are enabled. GFC is only - available at the UNI and uses the first 4-bits of the VPI field. - @li 1 - GFC field is valid. - @li 0 - GFC field ignored. */ - - unsigned int vcStatsRxPTI:1;/**< [25] This register is used to include or exclude the PTI field - of the ATM header when ATM VPI/VCI statistics are enabled. - @li 1 - PTI field is valid. - @li 0 - PTI field ignored.*/ - - unsigned int vcStatsRxCLP:1;/**< [24] This register is used to include or exclude the CLP field - of the ATM header when ATM VPI/VCI statistics are enabled. - @li 1 - CLP field is valid. - @li 0 - CLP field ignored. */ - - unsigned int discardHecErr:1;/**< [23] Discard cells with an invalid HEC. - @li 1 - Discard cells with HEC errors - @li 0 - Cells with HEC errors are passed */ - - unsigned int discardParErr:1;/**< [22] Discard cells containing parity errors. - @li 1 - Discard cells with parity errors - @li 0 - Cells with parity errors are passed */ - - unsigned int discardIdle:1; /**< [21] Discard Idle Cells based on DefineIdle register values - @li 1 - Discard IDLE cells - @li 0 - IDLE cells passed */ - - unsigned int enbHecErrCnt:1;/**< [20] Enable Receive HEC Error Count. - @li 1 - Enable count of received cells containing HEC errors - @li 0 - No count is maintained. */ - - unsigned int enbParErrCnt:1;/**< [19] Enable Parity Error Count - @li 1 - Enable count of received cells containing Parity errors - @li 0 - No count is maintained. */ - - unsigned int enbIdleCellCnt:1;/**< [18] Enable Receive Idle Cell Count. - @li 1 - Enable count of Idle cells received. - @li 0 - No count is maintained.*/ - - unsigned int enbSizeErrCnt:1;/**< [17] Enable Receive Size Error Count. - @li 1 - Enable count of received cells of incorrect size - @li 0 - No count is maintained. */ - - unsigned int enbRxCellCnt:1;/**< [16] Enable Receive Valid Cell Count of non-idle/non-error cells. - @li 1 - Enable count of valid cells received - non-idle/non-error - @li 0 - No count is maintained. */ - - unsigned int reserved_1:3; /**< [15:13] These bits are always 0 */ - - unsigned int rxCellOvrInt:1; /**< [12] Enable CBI Utopia Receive Status Condition if the RxCellCount - register overflows. - @li 1 - CBI Receive Status asserted. - @li 0 - No CBI Receive Status asserted.*/ - - unsigned int invalidHecOvrInt:1; /**< [11] Enable CBI Receive Status Condition if the InvalidHecCount - register overflows. - @li 1 - CBI Receive Condition asserted. - @li 0 - No CBI Receive Condition asserted */ - - unsigned int invalidParOvrInt:1; /**< [10] Enable CBI Receive Status Condition if the InvalidParCount - register overflows - @li 1 - CBI Receive Condition asserted. - @li 0 - No CBI Receive Condition asserted */ - - unsigned int invalidSizeOvrInt:1; /**< [9] Enable CBI Receive Status Condition if the InvalidSizeCount - register overflows. - @li 1 - CBI Receive Status Condition asserted. - @li¸0 - No CBI Receive Status asserted */ - - unsigned int rxIdleOvrInt:1; /**< [8] Enable CBI Receive Status Condition if the RxIdleCount overflows. - @li 1 - CBI Receive Condition asserted. - @li 0 - No CBI Receive Condition asserted */ - - unsigned int reserved_2:3; /**< [7:5] These bits are always 0 */ - - unsigned int rxAddrMask:5; /**< [4:0] This register is used as a mask to allow the user to increase - the PHY receive address range. The register should be programmed with - the address-range limit, i.e. if set to 0x3 the address range increases - to a maximum of 4 addresses. */ - } utRxEnableFields; /**< Rx enable Utopia register */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtRxTransTable0_ - * @brief Utopia Rx translation table Register - */ - struct UtRxTransTable0_ - { - - unsigned int phy0:5; /**< [31-27] Rx Mapping value of logical phy 0 */ - - unsigned int phy1:5; /**< [26-22] Rx Mapping value of logical phy 1 */ - - unsigned int phy2:5; /**< [21-17] Rx Mapping value of logical phy 2 */ - - unsigned int reserved_1:1; /**< [16] These bits are always 0 */ - - unsigned int phy3:5; /**< [15-11] Rx Mapping value of logical phy 3 */ - - unsigned int phy4:5; /**< [10-6] Rx Mapping value of logical phy 4 */ - - unsigned int phy5:5; /**< [5-1] Rx Mapping value of logical phy 5 */ - - unsigned int reserved_2:1; /**< [0] These bits are always 0 */ - } - - utRxTransTable0; /**< Rx translation table */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtRxTransTable1_ - * @brief Utopia Rx translation table Register - */ - struct UtRxTransTable1_ - { - - unsigned int phy6:5; /**< [31-27] Rx Mapping value of logical phy 6 */ - - unsigned int phy7:5; /**< [26-22] Rx Mapping value of logical phy 7 */ - - unsigned int phy8:5; /**< [21-17] Rx Mapping value of logical phy 8 */ - - unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */ - - unsigned int phy9:5; /**< [15-11] Rx Mapping value of logical phy 3 */ - - unsigned int phy10:5; /**< [10-6] Rx Mapping value of logical phy 4 */ - - unsigned int phy11:5; /**< [5-1] Rx Mapping value of logical phy 5 */ - - unsigned int reserved_2:1; /**< [0] These bits are always 0 */ - } - - utRxTransTable1; /**< Rx translation table */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtRxTransTable2_ - * @brief Utopia Rx translation table Register - */ - struct UtRxTransTable2_ - { - - unsigned int phy12:5; /**< [31-27] Rx Mapping value of logical phy 6 */ - - unsigned int phy13:5; /**< [26-22] Rx Mapping value of logical phy 7 */ - - unsigned int phy14:5; /**< [21-17] Rx Mapping value of logical phy 8 */ - - unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */ - - unsigned int phy15:5; /**< [15-11] Rx Mapping value of logical phy 3 */ - - unsigned int phy16:5; /**< [10-6] Rx Mapping value of logical phy 4 */ - - unsigned int phy17:5; /**< [5-1] Rx Mapping value of logical phy 5 */ - - unsigned int reserved_2:1; /**< [0] These bits are always 0 */ - } utRxTransTable2; /**< Rx translation table */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtRxTransTable3_ - * @brief Utopia Rx translation table Register - */ - struct UtRxTransTable3_ - { - - unsigned int phy18:5; /**< [31-27] Rx Mapping value of logical phy 6 */ - - unsigned int phy19:5; /**< [26-22] Rx Mapping value of logical phy 7 */ - - unsigned int phy20:5; /**< [21-17] Rx Mapping value of logical phy 8 */ - - unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */ - - unsigned int phy21:5; /**< [15-11] Rx Mapping value of logical phy 3 */ - - unsigned int phy22:5; /**< [10-6] Rx Mapping value of logical phy 4 */ - - unsigned int phy23:5; /**< [5-1] Rx Mapping value of logical phy 5 */ - - unsigned int reserved_2:1; /**< [0] These bits are always 0 */ - } utRxTransTable3; /**< Rx translation table */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtRxTransTable4_ - * @brief Utopia Rx translation table Register - */ - struct UtRxTransTable4_ - { - - unsigned int phy24:5; /**< [31-27] Rx Mapping value of logical phy 6 */ - - unsigned int phy25:5; /**< [26-22] Rx Mapping value of logical phy 7 */ - - unsigned int phy26:5; /**< [21-17] Rx Mapping value of logical phy 8 */ - - unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */ - - unsigned int phy27:5; /**< [15-11] Rx Mapping value of logical phy 3 */ - - unsigned int phy28:5; /**< [10-6] Rx Mapping value of logical phy 4 */ - - unsigned int phy29:5; /**< [5-1] Rx Mapping value of logical phy 5 */ - - unsigned int reserved_2:1; /**< [0] These bits are always 0 */ - } utRxTransTable4; /**< Rx translation table */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtRxTransTable5_ - * @brief Utopia Rx translation table Register - */ - struct UtRxTransTable5_ - { - - unsigned int phy30:5; /**< [31-27] Rx Mapping value of logical phy 6 */ - - unsigned int reserved_1:27; /**< [26-0] These bits are always 0 */ - - } utRxTransTable5; /**< Rx translation table */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtSysConfig_ - * @brief NPE setup Register - */ - struct UtSysConfig_ - { - - unsigned int reserved_1:2; /**< [31-30] These bits are always 0 */ - unsigned int txEnbFSM:1; /**< [29] Enables the operation ofthe Utopia Transmit FSM - * @li 1 - FSM enabled - * @li 0 - FSM inactive - */ - unsigned int rxEnbFSM:1; /**< [28] Enables the operation ofthe Utopia Revieve FSM - * @li 1 - FSM enabled - * @li 0 - FSM inactive - */ - unsigned int disablePins:1; /**< [27] Disable Utopia interface I/O pins forcing the signals to an - * inactive state. Note that this bit is set on reset and must be - * de-asserted - * @li 0 - Normal data transfer - * @li 1 - Utopia interface pins are forced inactive - */ - unsigned int tstLoop:1; /**< [26] Test Loop Back Enable. - * @li Note: For loop back to function RxMode and Tx Mode must both be set - * to single PHY mode. - * @li 0 - Loop back - * @li 1 - Normal operating mode - */ - - unsigned int txReset:1; /**< [25] Resets the Utopia Coprocessor transmit module to a known state. - * @li Note: All transmit configuration and status registers will be reset - * to their reset values. - * @li 0 - Normal operating mode¸ - * @li 1 - Reset transmit modules - */ - - unsigned int rxReset:1; /**< [24] Resets the Utopia Coprocessor receive module to a known state. - * @li Note: All receive configuration and status registers will be reset - * to their reset values. - * @li 0 - Normal operating mode - * @li 1 - Reset receive modules - */ - - unsigned int reserved_2:24; /**< [23-0] These bits are always 0 */ - } utSysConfig; /**< NPE debug config */ - -} -IxAtmdAccUtopiaConfig; - -/** -* -* @brief Utopia status -* -* This structure is used to set/get the Utopia status parameters -* @li contains debug cell counters, to be accessed during a read operation -* -* @note - the exact description of all parameters is done in the Utopia reference -* documents. -* -*/ -typedef struct -{ - - unsigned int utTxCellCount; /**< count of cells transmitted */ - - unsigned int utTxIdleCellCount; /**< count of idle cells transmitted */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtTxCellConditionStatus_ - * @brief Utopia Tx Status Register - */ - struct UtTxCellConditionStatus_ - { - - unsigned int reserved_1:2; /**< [31:30] These bits are always 0 */ - unsigned int txFIFO2Underflow:1; /**< [29] This bit is set if 64-byte - * Transmit FIFO2 indicates a FIFO underflow - * error condition. - */ - unsigned int txFIFO1Underflow:1; /**< [28] This bit is set if - * 64-byte Transmit FIFO1 indicates a FIFO - * underflow error condition. - */ - unsigned int txFIFO2Overflow:1; /**< [27] This bit is set if 64-byte - * Transmit FIFO2 indicates a FIFO overflow - * error condition. - */ - unsigned int txFIFO1Overflow:1; /**< [26] This bit is set if 64-byte - * Transmit FIFO1 indicates a FIFO overflow - * error condition. - */ - unsigned int txIdleCellCountOvr:1; /**< [25] This bit is set if the - * TxIdleCellCount register overflows. - */ - unsigned int txCellCountOvr:1; /**< [24] This bit is set if the - * TxCellCount register overflows - */ - unsigned int reserved_2:24; /**< [23:0] These bits are always 0 */ - } utTxCellConditionStatus; /**< Tx cells condition status */ - - unsigned int utRxCellCount; /**< count of cell received */ - unsigned int utRxIdleCellCount; /**< count of idle cell received */ - unsigned int utRxInvalidHECount; /**< count of invalid cell - * received because of HEC errors - */ - unsigned int utRxInvalidParCount; /**< count of invalid cell received - * because of parity errors - */ - unsigned int utRxInvalidSizeCount; /**< count of invalid cell - * received because of cell - * size errors - */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtRxCellConditionStatus_ - * @brief Utopia Rx Status Register - */ - struct UtRxCellConditionStatus_ - { - - unsigned int reserved_1:3; /**< [31:29] These bits are always 0.*/ - unsigned int rxCellCountOvr:1; /**< [28] This bit is set if the RxCellCount register overflows. */ - unsigned int invalidHecCountOvr:1; /**< [27] This bit is set if the InvalidHecCount register overflows.*/ - unsigned int invalidParCountOvr:1; /**< [26] This bit is set if the InvalidParCount register overflows.*/ - unsigned int invalidSizeCountOvr:1; /**< [25] This bit is set if the InvalidSizeCount register overflows.*/ - unsigned int rxIdleCountOvr:1; /**< [24] This bit is set if the RxIdleCount register overflows.*/ - unsigned int reserved_2:4; /**< [23:20] These bits are always 0 */ - unsigned int rxFIFO2Underflow:1; /**< [19] This bit is set if 64-byte Receive FIFO2 - * indicates a FIFO underflow error condition. - */ - unsigned int rxFIFO1Underflow:1; /**< [18] This bit is set if 64-byte Receive - * FIFO1 indicates a FIFO underflow error condition - . */ - unsigned int rxFIFO2Overflow:1; /**< [17] This bit is set if 64-byte Receive FIFO2 - * indicates a FIFO overflow error condition. - */ - unsigned int rxFIFO1Overflow:1; /**< [16] This bit is set if 64-byte Receive FIFO1 - * indicates a FIFO overflow error condition. - */ - unsigned int reserved_3:16; /**< [15:0] These bits are always 0. */ - } utRxCellConditionStatus; /**< Rx cells condition status */ - -} IxAtmdAccUtopiaStatus; - -/** - * @} defgroup IxAtmdAccUtopiaCtrlAPI - */ - - /** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @fn ixAtmdAccUtopiaConfigSet (const IxAtmdAccUtopiaConfig * - ixAtmdAccUtopiaConfigPtr) - * - * @brief Send the configuration structure to the Utopia interface - * - * This function downloads the @a IxAtmdAccUtopiaConfig structure to - * the Utopia and has the following effects - * @li setup the Utopia interface - * @li initialise the NPE - * @li reset the Utopia cell counters and status registers to known values - * - * This action has to be done once at initialisation. A lock is preventing - * the concurrent use of @a ixAtmdAccUtopiaStatusGet() and - * @A ixAtmdAccUtopiaConfigSet() - * - * @param *ixAtmdAccNPEConfigPtr @ref IxAtmdAccUtopiaConfig [in] - pointer to a structure to download to - * Utopia. This parameter cannot be a null pointer. - * - * @return @li IX_SUCCESS successful download - * @return @li IX_FAIL error in the parameters, or configuration is not - * complete or failed - * - * @sa ixAtmdAccUtopiaStatusGet - * - */ -PUBLIC IX_STATUS ixAtmdAccUtopiaConfigSet (const IxAtmdAccUtopiaConfig * - ixAtmdAccUtopiaConfigPtr); - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @fn ixAtmdAccUtopiaStatusGet (IxAtmdAccUtopiaStatus * - ixAtmdAccUtopiaStatus) - * - * @brief Get the Utopia interface configuration. - * - * This function reads the Utopia registers and the Cell counts - * and fills the @a IxAtmdAccUtopiaStatus structure - * - * A lock is preventing the concurrent - * use of @a ixAtmdAccUtopiaStatusGet() and @A ixAtmdAccUtopiaConfigSet() - * - * @param ixAtmdAccUtopiaStatus @ref IxAtmdAccUtopiaStatus [out] - pointer to structure to be updated from internal - * hardware counters. This parameter cannot be a NULL pointer. - * - * @return @li IX_SUCCESS successful read - * @return @li IX_FAIL error in the parameters null pointer, or - * configuration read is not complete or failed - * - * @sa ixAtmdAccUtopiaConfigSet - * - */ -PUBLIC IX_STATUS ixAtmdAccUtopiaStatusGet (IxAtmdAccUtopiaStatus * - ixAtmdAccUtopiaStatus); - -/** - * - * @ingroup IxAtmdAcc - * - * @fn ixAtmdAccPortEnable (IxAtmLogicalPort port) - * - * @brief enable a PHY logical port - * - * This function enables the transmission over one port. It should be - * called before accessing any resource from this port and before the - * establishment of a VC. - * - * When a port is enabled, the cell transmission to the Utopia interface - * is started. If there is no traffic already running, idle cells are - * sent over the interface. - * - * This function can be called multiple times. - * - * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] - * - * @return @li IX_SUCCESS enable is complete - * @return @li IX_ATMDACC_WARNING port already enabled - * @return @li IX_FAIL enable failed, wrong parameter, or cannot - * initialise this port (the port is maybe already in use, - * or there is a hardware issue) - * - * @note - This function needs internal locks and should not be - * called from an interrupt context - * - * @sa ixAtmdAccPortDisable - * - */ -PUBLIC IX_STATUS ixAtmdAccPortEnable (IxAtmLogicalPort port); - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @fn ixAtmdAccPortDisable (IxAtmLogicalPort port) - * - * @brief disable a PHY logical port - * - * This function disable the transmission over one port. - * - * When a port is disabled, the cell transmission to the Utopia interface - * is stopped. - * - * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] - * - * @return @li IX_SUCCESS disable is complete - * @return @li IX_ATMDACC_WARNING port already disabled - * @return @li IX_FAIL disable failed, wrong parameter . - * - * @note - This function needs internal locks and should not be called - * from an interrupt context - * - * @note - The response from hardware is done through the txDone mechanism - * to ensure the synchrnisation with tx resources. Therefore, the - * txDone mechanism needs to be serviced to make a PortDisable complete. - * - * @sa ixAtmdAccPortEnable - * @sa ixAtmdAccPortDisableComplete - * @sa ixAtmdAccTxDoneDispatch - * - */ -PUBLIC IX_STATUS ixAtmdAccPortDisable (IxAtmLogicalPort port); - -/** -* -* @ingroup IxAtmdAccCtrlAPI -* -* @fn ixAtmdAccPortDisableComplete (IxAtmLogicalPort port) -* -* @brief disable a PHY logical port -* -* This function indicates if the port disable for a port has completed. This -* function will return TRUE if the port has never been enabled. -* -* @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] -* -* @return @li TRUE disable is complete -* @return @li FALSE disable failed, wrong parameter . -* -* @note - This function needs internal locks and should not be called -* from an interrupt context -* -* @sa ixAtmdAccPortEnable -* @sa ixAtmdAccPortDisable -* -*/ -PUBLIC BOOL ixAtmdAccPortDisableComplete (IxAtmLogicalPort port); - -#endif /* IXATMDACCCTRL_H */ - -/** - * @} defgroup IxAtmdAccCtrlAPI - */ - - diff --git a/cpu/ixp/npe/include/IxAtmm.h b/cpu/ixp/npe/include/IxAtmm.h deleted file mode 100644 index fcf523fca4..0000000000 --- a/cpu/ixp/npe/include/IxAtmm.h +++ /dev/null @@ -1,795 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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 */ - -/** @} */ diff --git a/cpu/ixp/npe/include/IxDmaAcc.h b/cpu/ixp/npe/include/IxDmaAcc.h deleted file mode 100644 index 45c7527de9..0000000000 --- a/cpu/ixp/npe/include/IxDmaAcc.h +++ /dev/null @@ -1,260 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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 */ - diff --git a/cpu/ixp/npe/include/IxEthAcc.h b/cpu/ixp/npe/include/IxEthAcc.h deleted file mode 100644 index ff706c451d..0000000000 --- a/cpu/ixp/npe/include/IxEthAcc.h +++ /dev/null @@ -1,2512 +0,0 @@ -/** @file IxEthAcc.h - * - * @brief this file contains the public API of @ref IxEthAcc component - * - * Design notes: - * The IX_OSAL_MBUF address is to be specified on bits [31-5] and must - * be cache aligned (bits[4-0] cleared) - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - * - */ - -#ifndef IxEthAcc_H -#define IxEthAcc_H - -#include -#include - -/** - * @defgroup IxEthAcc IXP400 Ethernet Access (IxEthAcc) API - * - * @brief ethAcc is a library that does provides access to the internal IXP400 10/100Bt Ethernet MACs. - * - *@{ - */ - -/** - * @ingroup IxEthAcc - * @brief Definition of the Ethernet Access status - */ -typedef enum /* IxEthAccStatus */ -{ - IX_ETH_ACC_SUCCESS = IX_SUCCESS, /**< return success*/ - IX_ETH_ACC_FAIL = IX_FAIL, /**< return fail*/ - IX_ETH_ACC_INVALID_PORT, /**< return invalid port*/ - IX_ETH_ACC_PORT_UNINITIALIZED, /**< return uninitialized*/ - IX_ETH_ACC_MAC_UNINITIALIZED, /**< return MAC uninitialized*/ - IX_ETH_ACC_INVALID_ARG, /**< return invalid arg*/ - IX_ETH_TX_Q_FULL, /**< return tx queue is full*/ - IX_ETH_ACC_NO_SUCH_ADDR /**< return no such address*/ -} IxEthAccStatus; - -/** - * @ingroup IxEthAcc - * @enum IxEthAccPortId - * @brief Definition of the IXP400 Mac Ethernet device. - */ -typedef enum -{ - IX_ETH_PORT_1 = 0, /**< Ethernet Port 1 */ - IX_ETH_PORT_2 = 1 /**< Ethernet port 2 */ - ,IX_ETH_PORT_3 = 2 /**< Ethernet port 3 */ -} IxEthAccPortId; - -/** - * @ingroup IxEthAcc - * - * @def IX_ETH_ACC_NUMBER_OF_PORTS - * - * @brief Definition of the number of ports - * - */ -#ifdef __ixp46X -#define IX_ETH_ACC_NUMBER_OF_PORTS (3) -#else -#define IX_ETH_ACC_NUMBER_OF_PORTS (2) -#endif - -/** - * @ingroup IxEthAcc - * - * @def IX_IEEE803_MAC_ADDRESS_SIZE - * - * @brief Definition of the size of the MAC address - * - */ -#define IX_IEEE803_MAC_ADDRESS_SIZE (6) - - -/** - * - * @brief Definition of the IEEE 802.3 Ethernet MAC address structure. - * - * The data should be packed with bytes xx:xx:xx:xx:xx:xx - * @note - * The data must be packed in network byte order. - */ -typedef struct -{ - UINT8 macAddress[IX_IEEE803_MAC_ADDRESS_SIZE]; /**< MAC address */ -} IxEthAccMacAddr; - -/** - * @ingroup IxEthAcc - * @def IX_ETH_ACC_NUM_TX_PRIORITIES - * @brief Definition of the number of transmit priorities - * - */ -#define IX_ETH_ACC_NUM_TX_PRIORITIES (8) - -/** - * @ingroup IxEthAcc - * @enum IxEthAccTxPriority - * @brief Definition of the relative priority used to transmit a frame - * - */ -typedef enum -{ - IX_ETH_ACC_TX_PRIORITY_0 = 0, /** STA */ - IX_ETHACC_RX_APTYPE = 0x30 /**< 802.11, AP <=> AP */ -} IxEthAccRxFrameType; - -/** - * @ingroup IxEthAcc - * @enum IxEthAccDuplexMode - * @brief Definition to provision the duplex mode of the MAC. - * - */ -typedef enum -{ - IX_ETH_ACC_FULL_DUPLEX, /**< Full duplex operation of the MAC */ - IX_ETH_ACC_HALF_DUPLEX /**< Half duplex operation of the MAC */ -} IxEthAccDuplexMode; - - -/** - * @ingroup IxEthAcc - * @struct IxEthAccNe - * @brief Definition of service-specific informations. - * - * This structure defines the Ethernet service-specific informations - * and enable QoS and VLAN features. - */ -typedef struct -{ - UINT32 ixReserved_next; /**< reserved for chaining */ - UINT32 ixReserved_lengths; /**< reserved for buffer lengths */ - UINT32 ixReserved_data; /**< reserved for buffer pointer */ - UINT8 ixDestinationPortId; /**< Destination portId for this packet, if known by NPE */ - UINT8 ixSourcePortId; /**< Source portId for this packet */ - UINT16 ixFlags; /**< BitField of option for this frame */ - UINT8 ixQoS; /**< QoS class of the frame */ - UINT8 ixReserved; /**< reserved */ - UINT16 ixVlanTCI; /**< Vlan TCI */ - UINT8 ixDestMac[IX_IEEE803_MAC_ADDRESS_SIZE]; /**< Destination MAC address */ - UINT8 ixSourceMac[IX_IEEE803_MAC_ADDRESS_SIZE]; /**< Source MAC address */ -} IxEthAccNe; - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_PORT_UNKNOWN - * - * @brief Contents of the field @a IX_ETHACC_NE_DESTPORTID when no - * destination port can be found by the NPE for this frame. - * - */ -#define IX_ETHACC_NE_PORT_UNKNOWN (0xff) - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_DESTMAC - * - * @brief The location of the destination MAC address in the Mbuf header. - * - */ -#define IX_ETHACC_NE_DESTMAC(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixDestMac - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_SOURCEMAC - * - * @brief The location of the source MAC address in the Mbuf header. - * - */ -#define IX_ETHACC_NE_SOURCEMAC(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixSourceMac - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_VLANTCI - * - * @brief The VLAN Tag Control Information associated with this frame - * - * The VLAN Tag Control Information associated with this frame. On Rx - * path, this field is extracted from the packet header. - * On Tx path, the value of this field is inserted in the frame when - * the port is configured to insert or replace vlan tags in the - * egress frames. - * - * @sa IX_ETHACC_NE_FLAGS - */ -#define IX_ETHACC_NE_VLANTCI(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixVlanTCI - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_SOURCEPORTID - * - * @brief The port where this frame came from. - * - * The port where this frame came from. This field is set on receive - * with the port information. This field is ignored on Transmit path. - */ -#define IX_ETHACC_NE_SOURCEPORTID(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixSourcePortId - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_DESTPORTID - * - * @brief The destination port where this frame should be sent. - * - * The destination port where this frame should be sent. - * - * @li In the transmit direction, this field contains the destination port - * and is ignored unless @a IX_ETHACC_NE_FLAG_DST is set. - * - * @li In the receive direction, this field contains the port where the - * destination MAC addresses has been learned. If the destination - * MAC address is unknown, then this value is set to the reserved value - * @a IX_ETHACC_NE_PORT_UNKNOWN - * - */ -#define IX_ETHACC_NE_DESTPORTID(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixDestinationPortId - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_QOS - * - * @brief QualityOfService class (QoS) for this received frame. - * - */ -#define IX_ETHACC_NE_QOS(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixQoS - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_FLAGS - * - * @brief Bit Mask of the different flags associated with a frame - * - * The flags are the bit-oring combination - * of the following different fields : - * - * @li IP flag (Rx @a IX_ETHACC_NE_IPMASK) - * @li Spanning Tree flag (Rx @a IX_ETHACC_NE_STMASK) - * @li Link layer type (Rx and Tx @a IX_ETHACC_NE_LINKMASK) - * @li VLAN Tagged Frame (Rx @a IX_ETHACC_NE_VLANMASK) - * @li New source MAC address (Rx @a IX_ETHACC_NE_NEWSRCMASK) - * @li Multicast flag (Rx @a IX_ETHACC_NE_MCASTMASK) - * @li Broadcast flag (Rx @a IX_ETHACC_NE_BCASTMASK) - * @li Destination port flag (Tx @a IX_ETHACC_NE_PORTMASK) - * @li Tag/Untag Tx frame (Tx @a IX_ETHACC_NE_TAGMODEMASK) - * @li Overwrite destination port (Tx @a IX_ETHACC_NE_PORTOVERMASK) - * @li Filtered frame (Rx @a IX_ETHACC_NE_STMASK) - * @li VLAN Enabled (Rx and Tx @a IX_ETHACC_NE_VLANENABLEMASK) - */ -#define IX_ETHACC_NE_FLAGS(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixFlags - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_BCASTMASK - * - * @brief This mask defines if a received frame is a broadcast frame. - * - * This mask defines if a received frame is a broadcast frame. - * The BCAST flag is set when the destination MAC address of - * a frame is broadcast. - * - * @sa IX_ETHACC_NE_FLAGS - * - */ -#define IX_ETHACC_NE_BCASTMASK (0x1) - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_MCASTMASK - * - * @brief This mask defines if a received frame is a multicast frame. - * - * This mask defines if a received frame is a multicast frame. - * The MCAST flag is set when the destination MAC address of - * a frame is multicast. - * - * @sa IX_ETHACC_NE_FLAGS - * - */ -#define IX_ETHACC_NE_MCASTMASK (0x1 << 1) - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_IPMASK - * - * @brief This mask defines if a received frame is a IP frame. - * - * This mask applies to @a IX_ETHACC_NE_FLAGS and defines if a received - * frame is a IP frame. The IP flag is set on Rx direction, depending on - * the frame contents. The flag is set when the length/type field of a - * received frame is 0x8000. - * - * @sa IX_ETHACC_NE_FLAGS - * - */ -#define IX_ETHACC_NE_IPMASK (0x1 << 2) - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_VLANMASK - * - * @brief This mask defines if a received frame is VLAN tagged. - * - * This mask defines if a received frame is VLAN tagged. - * When set, the Rx frame is VLAN-tagged and the tag value - * is available thru @a IX_ETHACC_NE_VLANID. - * Note that when sending frames which are already tagged - * this flag should be set, to avoid inserting another VLAN tag. - * - * @sa IX_ETHACC_NE_FLAGS - * @sa IX_ETHACC_NE_VLANID - * - */ -#define IX_ETHACC_NE_VLANMASK (0x1 << 3) - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_LINKMASK - * - * @brief This mask is the link layer protocol indicator - * - * This mask applies to @a IX_ETHACC_NE_FLAGS. - * It reflects the state of a frame as it exits an NPE on the Rx path - * or enters an NPE on the Tx path. Its values are as follows: - * @li 0x00 - IEEE802.3 - 8802 (Rx) / IEEE802.3 - 8802 (Tx) - * @li 0x01 - IEEE802.3 - Ethernet (Rx) / IEEE802.3 - Ethernet (Tx) - * @li 0x02 - IEEE802.11 AP -> STA (Rx) / IEEE802.11 STA -> AP (Tx) - * @li 0x03 - IEEE802.11 AP -> AP (Rx) / IEEE802.11 AP->AP (Tx) - * - * @sa IX_ETHACC_NE_FLAGS - * - */ -#define IX_ETHACC_NE_LINKMASK (0x3 << 4) - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_STMASK - * - * @brief This mask defines if a received frame is a Spanning Tree frame. - * - * This mask applies to @a IX_ETHACC_NE_FLAGS. - * On rx direction, it defines if a received if frame is a Spanning Tree frame. - * Setting this fkag on transmit direction overrides the port settings - * regarding the VLAN options and - * - * @sa IX_ETHACC_NE_FLAGS - * - */ -#define IX_ETHACC_NE_STMASK (0x1 << 6) - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_FILTERMASK - * - * @brief This bit indicates whether a frame has been filtered by the Rx service. - * - * This mask applies to @a IX_ETHACC_NE_FLAGS. - * Certain frames, which should normally be fully filtered by the NPE to due - * the destination MAC address being on the same segment as the Rx port are - * still forwarded to the XScale (although the payload is invalid) in order - * to learn the MAC address of the transmitting station, if this is unknown. - * Normally EthAcc will filter and recycle these framess internally and no - * frames with the FILTER bit set will be received by the client. - * - * @sa IX_ETHACC_NE_FLAGS - * - */ -#define IX_ETHACC_NE_FILTERMASK (0x1 << 7) - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_PORTMASK - * - * @brief This mask defines the rule to transmit a frame - * - * This mask defines the rule to transmit a frame. When set, a frame - * is transmitted to the destination port as set by the macro - * @a IX_ETHACC_NE_DESTPORTID. If not set, the destination port - * is searched using the destination MAC address. - * - * @note This flag is meaningful only for multiport Network Engines. - * - * @sa IX_ETHACC_NE_FLAGS - * @sa IX_ETHACC_NE_DESTPORTID - * - */ -#define IX_ETHACC_NE_PORTOVERMASK (0x1 << 8) - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_TAGMODEMASK - * - * @brief This mask defines the tagging rules to apply to a transmit frame. - * - * This mask defines the tagging rules to apply to a transmit frame - * regardless of the default setting for a port. When used together - * with @a IX_ETHACC_NE_TAGOVERMASK and when set, the - * frame will be tagged prior to transmission. When not set, - * the frame will be untagged prior to transmission. This is accomplished - * irrespective of the Egress tagging rules, constituting a per-frame override. - * - * @sa IX_ETHACC_NE_FLAGS - * @sa IX_ETHACC_NE_TAGOVERMASK - * - */ -#define IX_ETHACC_NE_TAGMODEMASK (0x1 << 9) - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_TAGOVERMASK - * - * @brief This mask defines the rule to transmit a frame - * - * This mask defines the rule to transmit a frame. When set, the - * default transmit rules of a port are overriden. - * When not set, the default rules as set by @ref IxEthDB should apply. - * - * @sa IX_ETHACC_NE_FLAGS - * @sa IX_ETHACC_NE_TAGMODEMASK - * - */ -#define IX_ETHACC_NE_TAGOVERMASK (0x1 << 10) - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_VLANENABLEMASK - * - * @brief This mask defines if a frame is a VLAN frame or not - * - * When set, frames undergo normal VLAN processing on the Tx path - * (membership filtering, tagging, tag removal etc). If this flag is - * not set, the frame is considered to be a regular non-VLAN frame - * and no VLAN processing will be performed. - * - * Note that VLAN-enabled NPE images will always set this flag in all - * Rx frames, and images which are not VLAN enabled will clear this - * flag for all received frames. - * - * @sa IX_ETHACC_NE_FLAGS - * - */ -#define IX_ETHACC_NE_VLANENABLEMASK (0x1 << 14) - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_NEWSRCMASK - * - * @brief This mask defines if a received frame has been learned. - * - * This mask defines if the source MAC address of a frame is - * already known. If the bit is set, the source MAC address was - * unknown to the NPE at the time the frame was received. - * - * @sa IX_ETHACC_NE_FLAGS - * - */ -#define IX_ETHACC_NE_NEWSRCMASK (0x1 << 15) - -/** - * @ingroup IxEthAcc - * - * @brief This defines the recommanded minimum size of MBUF's submitted - * to the frame receive service. - * - */ -#define IX_ETHACC_RX_MBUF_MIN_SIZE (2048) - -/** - * @ingroup IxEthAcc - * - * @brief This defines the highest MII address of any attached PHYs - * - * The maximum number for PHY address is 31, add on for range checking. - * - */ -#define IXP425_ETH_ACC_MII_MAX_ADDR 32 - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccInit(void) - * - * @brief Initializes the IXP400 Ethernet Access Service. - * - * @li Reentrant - no - * @li ISR Callable - no - * - * This should be called once per module initialization. - * @pre - * The NPE must first be downloaded with the required microcode which supports all - * required features. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_FAIL : Service has failed to initialize. - * - *
- */ -PUBLIC IxEthAccStatus ixEthAccInit(void); - - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccUnload(void) - * - * @brief Unload the Ethernet Access Service. - * - * @li Reentrant - no - * @li ISR Callable - no - * - * @return void - * - *
- */ -PUBLIC void ixEthAccUnload(void); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortInit( IxEthAccPortId portId) - * - * @brief Initializes an NPE/Ethernet MAC Port. - * - * The NPE/Ethernet port initialisation includes the following steps - * @li Initialize the NPE/Ethernet MAC hardware. - * @li Verify NPE downloaded and operational. - * @li The NPE shall be available for usage once this API returns. - * @li Verify that the Ethernet port is present before initializing - * - * @li Reentrant - no - * @li ISR Callable - no - * - * This should be called once per mac device. - * The NPE/MAC shall be in disabled state after init. - * - * @pre - * The component must be initialized via @a ixEthAccInit - * The NPE must first be downloaded with the required microcode which supports all - * required features. - * - * Dependant on Services: (Must be initialized before using this service may be initialized) - * ixNPEmh - NPE Message handling service. - * ixQmgr - Queue Manager component. - * - * @param portId @ref IxEthAccPortId [in] - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS: if the ethernet port is not present, a warning is issued. - * @li @a IX_ETH_ACC_FAIL : The NPE processor has failed to initialize. - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * - *
- */ -PUBLIC IxEthAccStatus ixEthAccPortInit(IxEthAccPortId portId); - - -/************************************************************************* - - ##### ## ##### ## ##### ## ##### # # - # # # # # # # # # # # # # # - # # # # # # # # # # # # ###### - # # ###### # ###### ##### ###### # # # - # # # # # # # # # # # # # - ##### # # # # # # # # # # # - -*************************************************************************/ - - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortTxFrameSubmit( - IxEthAccPortId portId, - IX_OSAL_MBUF *buffer, - IxEthAccTxPriority priority) - * - * @brief This function shall be used to submit MBUFs buffers for transmission on a particular MAC device. - * - * When the frame is transmitted, the buffer shall be returned thru the - * callback @a IxEthAccPortTxDoneCallback. - * - * In case of over-submitting, the order of the frames on the - * network may be modified. - * - * Buffers shall be not queued for transmission if the port is disabled. - * The port can be enabled using @a ixEthAccPortEnable - * - * - * @li Reentrant - yes - * @li ISR Callable - yes - * - * - * @pre - * @a ixEthAccPortTxDoneCallbackRegister must be called to register a function to allow this service to - * return the buffer to the calling service. - * - * @note - * If the buffer submit fails for any reason the user has retained ownership of the buffer. - * - * @param portId @ref IxEthAccPortId [in] - MAC port ID to transmit Ethernet frame on. - * @param buffer @ref IX_OSAL_MBUF [in] - pointer to an MBUF formatted buffer. Chained buffers are supported for transmission. - * Chained packets are not supported and the field IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR is ignored. - * @param priority @ref IxEthAccTxPriority [in] - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_FAIL : Failed to queue frame for transmission. - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ - -PUBLIC IxEthAccStatus ixEthAccPortTxFrameSubmit( - IxEthAccPortId portId, - IX_OSAL_MBUF *buffer, - IxEthAccTxPriority priority); - -/** - * @ingroup IxEthAcc - * - * @brief Function prototype for Ethernet Tx Buffer Done callback. Registered - * via @a ixEthAccTxBufferDoneCallbackRegister - * - * This function is called once the previously submitted buffer is no longer required by this service. - * It may be returned upon successful transmission of the frame or during the shutdown of - * the port prior to the transmission of a queued frame. - * The calling of this registered function is not a guarantee of successful transmission of the buffer. - * - * - * @li Reentrant - yes , The user provided function should be reentrant. - * @li ISR Callable - yes , The user provided function must be callable from an ISR. - * - * - * Calling Context : - * @par - * This callback is called in the context of the queue manager dispatch loop @a ixQmgrgrDispatcherLoopRun - * within the @ref IxQMgrAPI component. The calling context may be from interrupt or high priority thread. - * The decision is system specific. - * - * @param callbackTag UINT32 [in] - This tag is that provided when the callback was registered for a particular MAC - * via @a ixEthAccPortTxDoneCallbackRegister. It allows the same callback to be used for multiple MACs. - * @param mbuf @ref IX_OSAL_MBUF [in] - Pointer to the Tx mbuf descriptor. - * - * @return void - * - * @note - * The field IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR is modified by the access layer and reset to NULL. - * - *
- */ -typedef void (*IxEthAccPortTxDoneCallback) ( UINT32 callbackTag, IX_OSAL_MBUF *buffer ); - - - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortTxDoneCallbackRegister( IxEthAccPortId portId, - IxEthAccPortTxDoneCallback txCallbackFn, - UINT32 callbackTag) - * - * @brief Register a callback function to allow - * the transmitted buffers to return to the user. - * - * This function registers the transmit buffer done function callback for a particular port. - * - * The registered callback function is called once the previously submitted buffer is no longer required by this service. - * It may be returned upon successful transmission of the frame or shutdown of port prior to submission. - * The calling of this registered function is not a guarantee of successful transmission of the buffer. - * - * If called several times the latest callback shall be registered for a particular port. - * - * @li Reentrant - yes - * @li ISR Callable - yes - * - * @pre - * The port must be initialized via @a ixEthAccPortInit - * - * - * @param portId @ref IxEthAccPortId [in] - Register callback for a particular MAC device. - * @param txCallbackFn @ref IxEthAccPortTxDoneCallback [in] - Function to be called to return transmit buffers to the user. - * @param callbackTag UINT32 [in] - This tag shall be provided to the callback function. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * @li @a IX_ETH_ACC_INVALID_ARG : An argument other than portId is invalid. - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortTxDoneCallbackRegister(IxEthAccPortId portId, - IxEthAccPortTxDoneCallback txCallbackFn, - UINT32 callbackTag); - - - -/** - * @ingroup IxEthAcc - * - * @brief Function prototype for Ethernet Frame Rx callback. Registered via @a ixEthAccPortRxCallbackRegister - * - * It is the responsibility of the user function to free any MBUF's which it receives. - * - * @li Reentrant - yes , The user provided function should be reentrant. - * @li ISR Callable - yes , The user provided function must be callable from an ISR. - * @par - * - * This function dispatches frames to the user level - * via the provided function. The invocation shall be made for each - * frame dequeued from the Ethernet QM queue. The user is required to free any MBUF's - * supplied via this callback. In addition the registered callback must free up MBUF's - * from the receive free queue when the port is disabled - * - * If called several times the latest callback shall be registered for a particular port. - * - * Calling Context : - * @par - * This callback is called in the context of the queue manager dispatch loop @a ixQmgrgrDispatcherLoopRun - * within the @ref IxQMgrAPI component. The calling context may be from interrupt or high priority thread. - * The decision is system specific. - * - * - * @param callbackTag UINT32 [in] - This tag is that provided when the callback was registered for a particular MAC - * via @a ixEthAccPortRxCallbackRegister. It allows the same callback to be used for multiple MACs. - * @param mbuf @ref IX_OSAL_MBUF [in] - Pointer to the Rx mbuf header. Mbufs may be chained if - * the frame length is greater than the supplied mbuf length. - * @param reserved [in] - deprecated parameter The information is passed - * thru the IxEthAccNe header destination port ID field - * (@sa IX_ETHACC_NE_DESTPORTID). For backward - * compatibility,the value is equal to IX_ETH_DB_UNKNOWN_PORT (0xff). - * - * @return void - * - * @note - * Buffers may not be filled up to the length supplied in - * @a ixEthAccPortRxFreeReplenish(). The firmware fills - * them to the previous 64 bytes boundary. The user has to be aware - * that the length of the received mbufs may be smaller than the length - * of the supplied mbufs. - * The mbuf header contains the following modified field - * @li @a IX_OSAL_MBUF_PKT_LEN is set in the header of the first mbuf and indicates - * the total frame size - * @li @a IX_OSAL_MBUF_MLEN is set each mbuf header and indicates the payload length - * @li @a IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR contains a pointer to the next - * mbuf, or NULL at the end of a chain. - * @li @a IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR is modified. Its value is reset to NULL - * @li @a IX_OSAL_MBUF_FLAGS contains the bit 4 set for a broadcast packet and the bit 5 - * set for a multicast packet. Other bits are unmodified. - * - *
- */ -typedef void (*IxEthAccPortRxCallback) (UINT32 callbackTag, IX_OSAL_MBUF *buffer, UINT32 reserved); - -/** - * @ingroup IxEthAcc - * - * @brief Function prototype for Ethernet Frame Rx callback. Registered via @a ixEthAccPortMultiBufferRxCallbackRegister - * - * It is the responsibility of the user function to free any MBUF's which it receives. - * - * @li Reentrant - yes , The user provided function should be reentrant. - * @li ISR Callable - yes , The user provided function must be callable from an ISR. - * @par - * - * This function dispatches many frames to the user level - * via the provided function. The invocation shall be made for multiple frames - * dequeued from the Ethernet QM queue. The user is required to free any MBUF's - * supplied via this callback. In addition the registered callback must free up MBUF's - * from the receive free queue when the port is disabled - * - * If called several times the latest callback shall be registered for a particular port. - * - * Calling Context : - * @par - * This callback is called in the context of the queue manager dispatch loop @a ixQmgrDispatcherLoopRun - * within the @ref IxQMgrAPI component. The calling context may be from interrupt or high priority thread. - * The decision is system specific. - * - * - * @param callbackTag - This tag is that provided when the callback was registered for a particular MAC - * via @a ixEthAccPortMultiBufferRxCallbackRegister. It allows the same callback to be used for multiple MACs. - * @param mbuf - Pointer to an array of Rx mbuf headers. Mbufs - * may be chained if - * the frame length is greater than the supplied mbuf length. - * The end of the array contains a zeroed entry (NULL pointer). - * - * @return void - * - * @note The mbufs passed to this callback have the same structure than the - * buffers passed to @a IxEthAccPortRxCallback interfac. - * - * @note The usage of this callback is exclusive with the usage of - * @a ixEthAccPortRxCallbackRegister and @a IxEthAccPortRxCallback - * - * @sa ixEthAccPortMultiBufferRxCallbackRegister - * @sa IxEthAccPortMultiBufferRxCallback - * @sa ixEthAccPortRxCallbackRegister - * @sa IxEthAccPortRxCallback - *
- */ - -typedef void (*IxEthAccPortMultiBufferRxCallback) (UINT32 callbackTag, IX_OSAL_MBUF **buffer); - - - - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortRxCallbackRegister( IxEthAccPortId portId, IxEthAccPortRxCallback rxCallbackFn, UINT32 callbackTag) - * - * @brief Register a callback function to allow - * the reception of frames. - * - * The registered callback function is called once a frame is received by this service. - * - * If called several times the latest callback shall be registered for a particular port. - * - * - * @li Reentrant - yes - * @li ISR Callable - yes - * - * - * @param portId @ref IxEthAccPortId [in] - Register callback for a particular MAC device. - * @param rxCallbackFn @ref IxEthAccPortRxCallback [in] - Function to be called when Ethernet frames are availble. - * @param callbackTag UINT32 [in] - This tag shall be provided to the callback function. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * @li @a IX_ETH_ACC_INVALID_ARG : An argument other than portId is invalid. - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortRxCallbackRegister(IxEthAccPortId portId, - IxEthAccPortRxCallback rxCallbackFn, - UINT32 callbackTag); - - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortMultiBufferRxCallbackRegister( IxEthAccPortId portId, IxEthAccPortMultiBufferRxCallback rxCallbackFn, UINT32 callbackTag) - * - * @brief Register a callback function to allow - * the reception of frames. - * - * The registered callback function is called once a frame is - * received by this service. If many frames are already received, - * the function is called once. - * - * If called several times the latest callback shall be registered for a particular port. - * - * @li Reentrant - yes - * @li ISR Callable - yes - * - * - * @param portId - Register callback for a particular MAC device. - * @param rxCallbackFn - @a IxEthAccMultiBufferRxCallbackFn - Function to be called when Ethernet frames are availble. - * @param callbackTag - This tag shall be provided to the callback function. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * @li @a IX_ETH_ACC_INVALID_ARG : An argument other than portId is invalid. - * - * @sa ixEthAccPortMultiBufferRxCallbackRegister - * @sa IxEthAccPortMultiBufferRxCallback - * @sa ixEthAccPortRxCallbackRegister - * @sa IxEthAccPortRxCallback - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortMultiBufferRxCallbackRegister(IxEthAccPortId portId, - IxEthAccPortMultiBufferRxCallback rxCallbackFn, - UINT32 callbackTag); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortRxFreeReplenish( IxEthAccPortId portId, IX_OSAL_MBUF *buffer) - * - * @brief This function provides buffers for the Ethernet receive path. - * - * This component does not have a buffer management mechanisms built in. All Rx buffers must be supplied to it - * via this interface. - * - * @li Reentrant - yes - * @li ISR Callable - yes - * - * @param portId @ref IxEthAccPortId [in] - Provide buffers only to specific Rx MAC. - * @param buffer @ref IX_OSAL_MBUF [in] - Provide an MBUF to the Ethernet receive mechanism. - * Buffers size smaller than IX_ETHACC_RX_MBUF_MIN_SIZE may result in poor - * performances and excessive buffer chaining. Buffers - * larger than this size may be suitable for jumbo frames. - * Chained packets are not supported and the field IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR must be NULL. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_FAIL : Buffer has was not able to queue the - * buffer in the receive service. - * @li @a IX_ETH_ACC_FAIL : Buffer size is less than IX_ETHACC_RX_MBUF_MIN_SIZE - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - * @note - * If the buffer replenish operation fails it is the responsibility - * of the user to free the buffer. - * - * @note - * Sufficient buffers must be supplied to the component to maintain - * receive throughput and avoid rx buffer underflow conditions. - * To meet this goal, It is expected that the user preload the - * component with a sufficent number of buffers prior to enabling the - * NPE Ethernet receive path. The recommended minimum number of - * buffers is 8. - * - * @note - * For maximum performances, the mbuf size should be greater - * than the maximum frame size (Ethernet header, payload and FCS) + 64. - * Supplying smaller mbufs to the service results in mbuf - * chaining and degraded performances. The recommended size - * is @a IX_ETHACC_RX_MBUF_MIN_SIZE, which is - * enough to take care of 802.3 frames and "baby jumbo" frames without - * chaining, and "jumbo" frame within chaining. - * - * @note - * Buffers may not be filled up to their length. The firware fills - * them up to the previous 64 bytes boundary. The user has to be aware - * that the length of the received mbufs may be smaller than the length - * of the supplied mbufs. - * - * @warning This function checks the parameters if the NDEBUG - * flag is not defined. Turning on the argument checking (disabled by - * default) results in a lower EthAcc performance as this function - * is part of the data path. - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortRxFreeReplenish( IxEthAccPortId portId, IX_OSAL_MBUF *buffer); - - - -/*************************************************************** - - #### #### # # ##### ##### #### # - # # # # ## # # # # # # # - # # # # # # # # # # # # - # # # # # # # ##### # # # - # # # # # ## # # # # # # - #### #### # # # # # #### ###### - - - ##### # ## # # ###### - # # # # # ## # # - # # # # # # # # ##### - ##### # ###### # # # # - # # # # # ## # - # ###### # # # # ###### - -***************************************************************/ - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortEnable(IxEthAccPortId portId) - * - * @brief This enables an Ethernet port for both Tx and Rx. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @pre The port must first be initialized via @a ixEthAccPortInit and the MAC address - * must be set using @a ixEthAccUnicastMacAddressSet before enabling it - * The rx and Tx Done callbacks registration via @a - * ixEthAccPortTxDoneCallbackRegister amd @a ixEthAccPortRxCallbackRegister - * has to be done before enabling the traffic. - * - * @param portId @ref IxEthAccPortId [in] - Port id to act upon. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is not initialized - * @li @a IX_ETH_ACC_MAC_UNINITIALIZED : port MAC address is not initialized - * - *
- */ -PUBLIC IxEthAccStatus ixEthAccPortEnable(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortDisable(IxEthAccPortId portId) - * - * @brief This disables an Ethernet port for both Tx and Rx. - * - * Free MBufs are returned to the user via the registered callback when the port is disabled - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @pre The port must be enabled with @a ixEthAccPortEnable, otherwise this - * function has no effect - * - * @param portId @ref IxEthAccPortId [in] - Port id to act upon. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is not initialized - * @li @a IX_ETH_ACC_MAC_UNINITIALIZED : port MAC address is not initialized - * - *
- */ -PUBLIC IxEthAccStatus ixEthAccPortDisable(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortEnabledQuery(IxEthAccPortId portId, BOOL *enabled) - * - * @brief Get the enabled state of a port. - * - * @li Reentrant - yes - * @li ISR Callable - yes - * - * @pre The port must first be initialized via @a ixEthAccPortInit - * - * @param portId @ref IxEthAccPortId [in] - Port id to act upon. - * @param enabled BOOL [out] - location to store the state of the port - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortEnabledQuery(IxEthAccPortId portId, BOOL *enabled); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortPromiscuousModeClear(IxEthAccPortId portId) - * - * @brief Put the Ethernet MAC device in non-promiscuous mode. - * - * In non-promiscuous mode the MAC filters all frames other than - * destination MAC address which matches the following criteria: - * @li Unicast address provisioned via @a ixEthAccUnicastMacAddressSet - * @li All broadcast frames. - * @li Multicast addresses provisioned via @a ixEthAccMulticastAddressJoin - * - * Other functions modify the MAC filtering - * - * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast - * frames are forwarded to the application - * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the - * effects of @a ixEthAccPortMulticastAddressJoinAll() - * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new - * filtering address - * @li @a ixEthAccPortMulticastAddressJoin() - provision a new - * filtering address - * @li @a ixEthAccPortPromiscuousModeSet() - all frames are - * forwarded to the application regardless of the multicast - * address provisioned - * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded - * to the application following the multicast address provisioned - * - * In all cases, unicast and broadcast addresses are forwarded to - * the application. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @sa ixEthAccPortPromiscuousModeSet - * - * @param portId @ref IxEthAccPortId [in] - Ethernet port id. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus ixEthAccPortPromiscuousModeClear(IxEthAccPortId portId); - - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortPromiscuousModeSet(IxEthAccPortId portId) - * - * @brief Put the MAC device in promiscuous mode. - * - * If the device is in promiscuous mode then all all received frames shall be forwared - * to the NPE for processing. - * - * Other functions modify the MAC filtering - * - * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast - * frames are forwarded to the application - * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the - * effects of @a ixEthAccPortMulticastAddressJoinAll() - * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new - * filtering address - * @li @a ixEthAccPortMulticastAddressJoin() - provision a new - * filtering address - * @li @a ixEthAccPortPromiscuousModeSet() - all frames are - * forwarded to the application regardless of the multicast - * address provisioned - * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded - * to the application following the multicast address provisioned - * - * In all cases, unicast and broadcast addresses are forwarded to - * the application. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @sa ixEthAccPortPromiscuousModeClear - * - * @param portId @ref IxEthAccPortId [in] - Ethernet port id. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus ixEthAccPortPromiscuousModeSet(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortUnicastMacAddressSet( IxEthAccPortId portId, - IxEthAccMacAddr *macAddr) - * - * @brief Configure unicast MAC address for a particular port - * - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @param portId @ref IxEthAccPortId [in] - Ethernet port id. - * @param *macAddr @ref IxEthAccMacAddr [in] - Ethernet Mac address. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus ixEthAccPortUnicastMacAddressSet(IxEthAccPortId portId, - IxEthAccMacAddr *macAddr); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortUnicastMacAddressGet( IxEthAccPortId portId, - IxEthAccMacAddr *macAddr) - * - * @brief Get unicast MAC address for a particular MAC port - * - * @pre - * The MAC address must first be set via @a ixEthAccMacPromiscuousModeSet - * If the MAC address has not been set, the function returns a - * IX_ETH_ACC_MAC_UNINITIALIZED status - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @param portId @ref IxEthAccPortId [in] - Ethernet port id. - * @param *macAddr @ref IxEthAccMacAddr [out] - Ethernet MAC address. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_MAC_UNINITIALIZED : port MAC address is not initialized. - * @li @a IX_ETH_ACC_FAIL : macAddr is invalid. - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortUnicastMacAddressGet(IxEthAccPortId portId, - IxEthAccMacAddr *macAddr); - - - - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortMulticastAddressJoin( IxEthAccPortId portId, - IxEthAccMacAddr *macAddr) - * - * @brief Add a multicast address to the MAC address table. - * - * @note - * Due to the operation of the Ethernet MAC multicast filtering mechanism, frames which do not - * have a multicast destination address which were provisioned via this API may be forwarded - * to the NPE's. This is a result of the hardware comparison algorithm used in the destination mac address logic - * within the Ethernet MAC. - * - * See Also: IXP425 hardware development manual. - * - * Other functions modify the MAC filtering - * - * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast - * frames are forwarded to the application - * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the - * effects of @a ixEthAccPortMulticastAddressJoinAll() - * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new - * filtering address - * @li @a ixEthAccPortMulticastAddressJoin() - provision a new - * filtering address - * @li @a ixEthAccPortPromiscuousModeSet() - all frames are - * forwarded to the application regardless of the multicast - * address provisioned - * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded - * to the application following the multicast address provisioned - * - * In all cases, unicast and broadcast addresses are forwarded to - * the application. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @param portId @ref IxEthAccPortId [in] - Ethernet port id. - * @param *macAddr @ref IxEthAccMacAddr [in] - Ethernet Mac address. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_FAIL : Error writing to the MAC registers - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortMulticastAddressJoin(IxEthAccPortId portId, - IxEthAccMacAddr *macAddr); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortMulticastAddressJoinAll( IxEthAccPortId portId) - * - * @brief Filter all frames with multicast dest. - * - * This function clears the MAC address table, and then sets - * the MAC to forward ALL multicast frames to the NPE. - * Specifically, it forwards all frames whose destination address - * has the LSB of the highest byte set (01:00:00:00:00:00). This - * bit is commonly referred to as the "multicast bit". - * Broadcast frames will still be forwarded. - * - * Other functions modify the MAC filtering - * - * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast - * frames are forwarded to the application - * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the - * effects of @a ixEthAccPortMulticastAddressJoinAll() - * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new - * filtering address - * @li @a ixEthAccPortMulticastAddressJoin() - provision a new - * filtering address - * @li @a ixEthAccPortPromiscuousModeSet() - all frames are - * forwarded to the application regardless of the multicast - * address provisioned - * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded - * to the application following the multicast address provisioned - * - * In all cases, unicast and broadcast addresses are forwarded to - * the application. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @param portId @ref IxEthAccPortId [in] - Ethernet port id. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortMulticastAddressJoinAll(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortMulticastAddressLeave( IxEthAccPortId portId, - IxEthAccMacAddr *macAddr) - * - * @brief Remove a multicast address from the MAC address table. - * - * Other functions modify the MAC filtering - * - * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast - * frames are forwarded to the application - * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the - * effects of @a ixEthAccPortMulticastAddressJoinAll() - * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new - * filtering address - * @li @a ixEthAccPortMulticastAddressJoin() - provision a new - * filtering address - * @li @a ixEthAccPortPromiscuousModeSet() - all frames are - * forwarded to the application regardless of the multicast - * address provisioned - * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded - * to the application following the multicast address provisioned - * - * In all cases, unicast and broadcast addresses are forwarded to - * the application. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @param portId @ref IxEthAccPortId [in] - Ethernet port id. - * @param *macAddr @ref IxEthAccMacAddr [in] - Ethernet Mac address. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_NO_SUCH_ADDR : Failed if MAC address was not in the table. - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortMulticastAddressLeave(IxEthAccPortId portId, - IxEthAccMacAddr *macAddr); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortMulticastAddressLeaveAll( IxEthAccPortId portId) - * - * @brief This function unconfigures the multicast filtering settings - * - * This function first clears the MAC address table, and then sets - * the MAC as configured by the promiscuous mode current settings. - * - * Other functions modify the MAC filtering - * - * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast - * frames are forwarded to the application - * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the - * effects of @a ixEthAccPortMulticastAddressJoinAll() - * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new - * filtering address - * @li @a ixEthAccPortMulticastAddressJoin() - provision a new - * filtering address - * @li @a ixEthAccPortPromiscuousModeSet() - all frames are - * forwarded to the application regardless of the multicast - * address provisioned - * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded - * to the application following the multicast address provisioned - * - * In all cases, unicast and broadcast addresses are forwarded to - * the application. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @param portId @ref IxEthAccPortId [in] - Ethernet port id. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortMulticastAddressLeaveAll(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortUnicastAddressShow(IxEthAccPortId portId) - * - * @brief Displays unicast MAC address - * - * Displays unicast address which is configured using - * @a ixEthAccUnicastMacAddressSet. This function also displays the MAC filter used - * to filter multicast frames. - * - * Other functions modify the MAC filtering - * - * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast - * frames are forwarded to the application - * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the - * effects of @a ixEthAccPortMulticastAddressJoinAll() - * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new - * filtering address - * @li @a ixEthAccPortMulticastAddressJoin() - provision a new - * filtering address - * @li @a ixEthAccPortPromiscuousModeSet() - all frames are - * forwarded to the application regardless of the multicast - * address provisioned - * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded - * to the application following the multicast address provisioned - * - * In all cases, unicast and broadcast addresses are forwarded to - * the application. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @param portId @ref IxEthAccPortId [in] - Ethernet port id. - * - * @return void - * - *
- */ -PUBLIC IxEthAccStatus ixEthAccPortUnicastAddressShow(IxEthAccPortId portId); - - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortMulticastAddressShow( IxEthAccPortId portId) - * - * @brief Displays multicast MAC address - * - * Displays multicast address which have been configured using @a ixEthAccMulticastAddressJoin - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @param portId @ref IxEthAccPortId [in] - Ethernet port id. - * - * @return void - * - *
- */ -PUBLIC void ixEthAccPortMulticastAddressShow( IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortDuplexModeSet( IxEthAccPortId portId, IxEthAccDuplexMode mode ) - * - * @brief Set the duplex mode for the MAC. - * - * Configure the IXP400 MAC to either full or half duplex. - * - * @note - * The configuration should match that provisioned on the PHY. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @param portId @ref IxEthAccPortId [in] - * @param mode @ref IxEthAccDuplexMode [in] - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortDuplexModeSet(IxEthAccPortId portId,IxEthAccDuplexMode mode); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortDuplexModeGet( IxEthAccPortId portId, IxEthAccDuplexMode *mode ) - * - * @brief Get the duplex mode for the MAC. - * - * return the duplex configuration of the IXP400 MAC. - * - * @note - * The configuration should match that provisioned on the PHY. - * See @a ixEthAccDuplexModeSet - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @param portId @ref IxEthAccPortId [in] - * @param *mode @ref IxEthAccDuplexMode [out] - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- * - */ -PUBLIC IxEthAccStatus -ixEthAccPortDuplexModeGet(IxEthAccPortId portId,IxEthAccDuplexMode *mode ); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortTxFrameAppendPaddingEnable( IxEthAccPortId portId) - * - * @brief Enable padding bytes to be appended to runt frames submitted to - * this port - * - * Enable up to 60 null-bytes padding bytes to be appended to runt frames - * submitted to this port. This is the default behavior of the access - * component. - * - * @warning Do not change this behaviour while the port is enabled. - * - * @note When Tx padding is enabled, Tx FCS generation is turned on - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @sa ixEthAccPortTxFrameAppendFCSDusable - * - * @param portId @ref IxEthAccPortId [in] - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortTxFrameAppendPaddingEnable(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortTxFrameAppendPaddingDisable( IxEthAccPortId portId) - * - * @brief Disable padding bytes to be appended to runt frames submitted to - * this port - * - * Disable padding bytes to be appended to runt frames - * submitted to this port. This is not the default behavior of the access - * component. - * - * @warning Do not change this behaviour while the port is enabled. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @param portId @ref IxEthAccPortId [in] - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortTxFrameAppendPaddingDisable(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortTxFrameAppendFCSEnable( IxEthAccPortId portId) - * - * @brief Enable the appending of Ethernet FCS to all frames submitted to this port - * - * When enabled, the FCS is added to the submitted frames. This is the default - * behavior of the access component. - * Do not change this behaviour while the port is enabled. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @param portId @ref IxEthAccPortId [in] - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortTxFrameAppendFCSEnable(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortTxFrameAppendFCSDisable( IxEthAccPortId portId) - * - * @brief Disable the appending of Ethernet FCS to all frames submitted to this port. - * - * When disabled, the Ethernet FCS is not added to the submitted frames. - * This is not the default - * behavior of the access component. - * - * @note Since the FCS is not appended to the frame it is expected that the frame submitted to the - * component includes a valid FCS at the end of the data, although this will not be validated. - * - * The component shall forward the frame to the Ethernet MAC WITHOUT modification. - * - * Do not change this behaviour while the port is enabled. - * - * @note Tx FCS append is not disabled while Tx padding is enabled. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @sa ixEthAccPortTxFrameAppendPaddingEnable - * - * @param portId @ref IxEthAccPortId [in] - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortTxFrameAppendFCSDisable(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortRxFrameAppendFCSEnable( IxEthAccPortId portId) - * - * @brief Forward frames with FCS included in the receive buffer. - * - * The FCS is not striped from the receive buffer. - * The received frame length includes the FCS size (4 bytes). ie. - * A minimum sized ethernet frame shall have a length of 64bytes. - * - * Frame FCS validity checks are still carried out on all received frames. - * - * This is not the default - * behavior of the access component. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @param portId @ref IxEthAccPortId [in] - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortRxFrameAppendFCSEnable(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortRxFrameAppendFCSDisable( IxEthAccPortId portId) - * - * @brief Do not forward the FCS portion of the received Ethernet frame to the user. - * The FCS is striped from the receive buffer. - * The received frame length does not include the FCS size (4 bytes). - * Frame FCS validity checks are still carried out on all received frames. - * - * This is the default behavior of the component. - * Do not change this behaviour while the port is enabled. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @param portId @ref IxEthAccPortId [in] - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortRxFrameAppendFCSDisable(IxEthAccPortId portId); - - - - -/** - * @ingroup IxEthAcc - * - * @enum IxEthAccSchedulerDiscipline - * - * @brief Definition for the port scheduling discipline - * - * Select the port scheduling discipline on receive and transmit path - * @li FIFO : No Priority : In this configuration all frames are processed - * in the access component in the strict order in which - * the component received them. - * @li FIFO : Priority : This shall be a very simple priority mechanism. - * Higher prior-ity frames shall be forwarded - * before lower priority frames. There shall be no - * fairness mechanisms applied across different - * priorities. Higher priority frames could starve - * lower priority frames indefinitely. - */ -typedef enum -{ - FIFO_NO_PRIORITY, /** - */ -PUBLIC IxEthAccStatus -ixEthAccTxSchedulingDisciplineSet(IxEthAccPortId portId, - IxEthAccSchedulerDiscipline sched); - - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccRxSchedulingDisciplineSet(IxEthAccSchedulerDiscipline sched) - * - * @brief Set the Rx scheduling to one of @a IxEthAccSchedulerDiscipline - * - * The default behavior of the component is @a FIFO_NO_PRIORITY. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @pre - * - * @param sched : @a IxEthAccSchedulerDiscipline - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS : Set appropriate discipline. - * @li @a IX_ETH_ACC_FAIL : Invalid/unsupported discipline. - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccRxSchedulingDisciplineSet(IxEthAccSchedulerDiscipline sched); - -/** - * @ingroup IxEthAcc - * - * @fn IxEthAccStatus ixEthAccNpeLoopbackEnable(IxEthAccPortId portId) - * - * @brief Enable NPE loopback - * - * When this loopback mode is enabled all the transmitted frames are - * received on the same port, without payload. - * - * This function is recommended for power-up diagnostic checks and - * should never be used under normal Ethernet traffic operations. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @pre - * - * @param portId : ID of the port - * - * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is - * guaranteed to restore correct Ethernet Tx/Rx operation. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS : NPE loopback mode enabled - * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortNpeLoopbackEnable(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn IxEthAccStatus ixEthAccPortNpeLoopbackDisable(IxEthAccPortId portId) - * - * @brief Disable NPE loopback - * - * This function is used to disable the NPE loopback if previously - * enabled using ixEthAccNpeLoopbackEnable. - * - * This function is recommended for power-up diagnostic checks and - * should never be used under normal Ethernet traffic operations. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @pre - * - * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is - * guaranteed to restore correct Ethernet Tx/Rx operation. - * - * @param portId : ID of the port - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS : NPE loopback successfully disabled - * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortNpeLoopbackDisable(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn IxEthAccStatus ixEthAccPortTxEnable(IxEthAccPortId portId) - * - * @brief Enable Tx on the port - * - * This function is the complement of ixEthAccPortTxDisable and should - * be used only after Tx was disabled. A MAC core reset is required before - * this function is called (see @a ixEthAccPortMacReset). - * - * This function is the recommended usage scenario for emergency security - * shutdown and hardware failure recovery and should never be used for throttling - * traffic. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @pre - * - * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is - * guaranteed to restore correct Ethernet Tx/Rx operation. - * - * @param portId : ID of the port - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS : Tx successfully enabled - * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortTxEnable(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn IxEthAccStatus ixEthAccPortTxDisable(IxEthAccPortId portId) - * - * @brief Disable Tx on the port - * - * This function can be used to disable Tx in the MAC core. - * Tx can be re-enabled, although this is not guaranteed, by performing - * a MAC core reset (@a ixEthAccPortMacReset) and calling ixEthAccPortTxEnable. - * Note that using this function is not recommended, except for shutting - * down Tx for emergency reasons. For proper port shutdown and re-enabling - * see ixEthAccPortEnable and ixEthAccPortDisable. - * - * This function is the recommended usage scenario for emergency security - * shutdown and hardware failure recovery and should never be used for throttling - * traffic. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is - * guaranteed to restore correct Ethernet Tx/Rx operation. - * - * @pre - * - * @param portId : ID of the port - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS : Tx successfully disabled - * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortTxDisable(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn IxEthAccStatus ixEthAccPortRxEnable(IxEthAccPortId portId) - * - * @brief Enable Rx on the port - * - * This function is the complement of ixEthAccPortRxDisable and should - * be used only after Rx was disabled. - * - * This function is the recommended usage scenario for emergency security - * shutdown and hardware failure recovery and should never be used for throttling - * traffic. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is - * guaranteed to restore correct Ethernet Tx/Rx operation. - * - * @pre - * - * @param portId : ID of the port - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS : Rx successfully enabled - * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortRxEnable(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn IxEthAccStatus ixEthAccPortRxDisable(IxEthAccPortId portId) - * - * @brief Disable Rx on the port - * - * This function can be used to disable Rx in the MAC core. - * Rx can be re-enabled, although this is not guaranteed, by performing - * a MAC core reset (@a ixEthAccPortMacReset) and calling ixEthAccPortRxEnable. - * Note that using this function is not recommended, except for shutting - * down Rx for emergency reasons. For proper port shutdown and re-enabling - * see ixEthAccPortEnable and ixEthAccPortDisable. - * - * This function is the recommended usage scenario for emergency security - * shutdown and hardware failure recovery and should never be used for throttling - * traffic. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @pre - * - * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is - * guaranteed to restore correct Ethernet Tx/Rx operation. - * - * @param portId : ID of the port - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS : Rx successfully disabled - * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortRxDisable(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn IxEthAccStatus ixEthAccPortMacReset(IxEthAccPortId portId) - * - * @brief Reset MAC core on the port - * - * This function will perform a MAC core reset (NPE Ethernet coprocessor). - * This function is inherently unsafe and the NPE recovery is not guaranteed - * after this function is called. The proper manner of performing port disable - * and enable (which will reset the MAC as well) is ixEthAccPortEnable/ixEthAccPortDisable. - * - * This function is the recommended usage scenario for hardware failure recovery - * and should never be used for throttling traffic. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @pre - * - * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is - * guaranteed to restore correct Ethernet Tx/Rx operation. - * - * @param portId : ID of the port - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS : MAC core reset - * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortMacReset(IxEthAccPortId portId); - -/********************************************************************************* - #### ##### ## ##### # #### ##### # #### #### - # # # # # # # # # # # # - #### # # # # # #### # # # #### - # # ###### # # # # # # # - # # # # # # # # # # # # # # # - #### # # # # # #### # # #### #### -**********************************************************************************/ - - -/** - * - * @brief This struct defines the statistics returned by this component. - * - * The component returns MIB2 EthObj variables which are obtained from the - * hardware or maintained by this component. - * - * - */ -typedef struct -{ - UINT32 dot3StatsAlignmentErrors; /**< link error count (rx) */ - UINT32 dot3StatsFCSErrors; /**< link error count (rx) */ - UINT32 dot3StatsInternalMacReceiveErrors; /**< link error count (rx) */ - UINT32 RxOverrunDiscards; /**< NPE: discarded frames count (rx) */ - UINT32 RxLearnedEntryDiscards; /**< NPE: discarded frames count(rx) */ - UINT32 RxLargeFramesDiscards; /**< NPE: discarded frames count(rx) */ - UINT32 RxSTPBlockedDiscards; /**< NPE: discarded frames count(rx) */ - UINT32 RxVLANTypeFilterDiscards; /**< NPE: discarded frames count (rx) */ - UINT32 RxVLANIdFilterDiscards; /**< NPE: discarded frames count (rx) */ - UINT32 RxInvalidSourceDiscards; /**< NPE: discarded frames count (rx) */ - UINT32 RxBlackListDiscards; /**< NPE: discarded frames count (rx) */ - UINT32 RxWhiteListDiscards; /**< NPE: discarded frames count (rx) */ - UINT32 RxUnderflowEntryDiscards; /**< NPE: discarded frames count (rx) */ - UINT32 dot3StatsSingleCollisionFrames; /**< link error count (tx) */ - UINT32 dot3StatsMultipleCollisionFrames; /**< link error count (tx) */ - UINT32 dot3StatsDeferredTransmissions; /**< link error count (tx) */ - UINT32 dot3StatsLateCollisions; /**< link error count (tx) */ - UINT32 dot3StatsExcessiveCollsions; /**< link error count (tx) */ - UINT32 dot3StatsInternalMacTransmitErrors; /**< link error count (tx) */ - UINT32 dot3StatsCarrierSenseErrors; /**< link error count (tx) */ - UINT32 TxLargeFrameDiscards; /**< NPE: discarded frames count (tx) */ - UINT32 TxVLANIdFilterDiscards; /**< NPE: discarded frames count (tx) */ - -}IxEthEthObjStats; - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccMibIIStatsGet(IxEthAccPortId portId ,IxEthEthObjStats *retStats ) - * - * @brief Returns the statistics maintained for a port. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @pre - * - * - * @param portId @ref IxEthAccPortId [in] - * @param retStats @ref IxEthEthObjStats [out] - * @note Please note the user is responsible for cache coheriency of the retStat - * buffer. The data is actually populated via the NPE's. As such cache safe - * memory should be used in the retStats argument. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_FAIL : Invalid arguments. - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccMibIIStatsGet(IxEthAccPortId portId, IxEthEthObjStats *retStats ); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccMibIIStatsGetClear(IxEthAccPortId portId, IxEthEthObjStats *retStats) - * - * @brief Returns and clears the statistics maintained for a port. - * - * @li Reentrant - yes - * @li ISR Callable - yes - * - * @pre - * - * @param portId @ref IxEthAccPortId [in] - * @param retStats @ref IxEthEthObjStats [out] - * @note Please note the user is responsible for cache coheriency of the retStats - * buffer. The data is actually populated via the NPE's. As such cache safe - * memory should be used in the retStats argument. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_FAIL : invalid arguments. - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccMibIIStatsGetClear(IxEthAccPortId portId, IxEthEthObjStats *retStats); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccMibIIStatsClear(IxEthAccPortId portId) - * - * @brief Clears the statistics maintained for a port. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @pre - * - * @param portId @ref IxEthAccPortId [in] - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_FAIL : Invalid arguments. - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus ixEthAccMibIIStatsClear(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccMacInit(IxEthAccPortId portId) - * - * @brief Initializes the ethernet MAC settings - * - * @li Reentrant - no - * @li ISR Callable - no - * - * @param portId @ref IxEthAccPortId [in] - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * - *
- */ -PUBLIC IxEthAccStatus ixEthAccMacInit(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccStatsShow(IxEthAccPortId portId) - * - * - * @brief Displays a ports statistics on the standard io console using printf. - * - * @li Reentrant - no - * @li ISR Callable - no - * - * @pre - * - * @param portId @ref IxEthAccPortId [in] - * - * @return void - * - *
- */ -PUBLIC void ixEthAccStatsShow(IxEthAccPortId portId); - -/************************************************************************* - - # # # # # # ##### # #### - ## ## # # ## ## # # # # # - # ## # # # # ## # # # # # # - # # # # # # # # # # # - # # # # # # # # # # # - # # # # # # ##### # #### - -*************************************************************************/ - - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccMiiReadRtn (UINT8 phyAddr, - UINT8 phyReg, - UINT16 *value) - * - * - * @brief Reads a 16 bit value from a PHY - * - * Reads a 16-bit word from a register of a MII-compliant PHY. Reading - * is performed through the MII management interface. This function returns - * when the read operation has successfully completed, or when a timeout has elapsed. - * - * @li Reentrant - no - * @li ISR Callable - no - * - * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock. - * - * @param phyAddr UINT8 [in] - the address of the Ethernet PHY (0-31) - * @param phyReg UINT8 [in] - the number of the MII register to read (0-31) - * @param value UINT16 [in] - the value read from the register - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_FAIL : failed to read the register. - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccMiiReadRtn (UINT8 phyAddr, UINT8 phyReg, UINT16 *value); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccMiiWriteRtn (UINT8 phyAddr, - UINT8 phyReg, - UINT16 value) - * - * - * @brief Writes a 16 bit value to a PHY - * - * Writes a 16-bit word from a register of a MII-compliant PHY. Writing - * is performed through the MII management interface. This function returns - * when the write operation has successfully completed, or when a timeout has elapsed. - * - * @li Reentrant - no - * @li ISR Callable - no - * - * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock. - * - * @param phyAddr UINT8 [in] - the address of the Ethernet PHY (0-31) - * @param phyReg UINT8 [in] - the number of the MII register to write (0-31) - * @param value UINT16 [out] - the value to write to the register - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_FAIL : failed to write register. - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccMiiWriteRtn (UINT8 phyAddr, UINT8 phyReg, UINT16 value); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccMiiAccessTimeoutSet(UINT32 timeout) - * - * @brief Overrides the default timeout value and retry count when reading or - * writing MII registers using ixEthAccMiiWriteRtn or ixEthAccMiiReadRtn - * - * The default behavior of the component is to use a IX_ETH_ACC_MII_10TH_SEC_IN_MILLIS ms - * timeout (declared as 100 in IxEthAccMii_p.h) and a retry count of IX_ETH_ACC_MII_TIMEOUT_10TH_SECS - * (declared as 5 in IxEthAccMii_p.h). - * - * The MII read and write functions will attempt to read the status of the register up - * to the retry count times, delaying between each attempt with the timeout value. - * - * @li Reentrant - no - * @li ISR Callable - no - * - * @pre - * - * @param timeout UINT32 [in] - new timeout value, in milliseconds - * @param timeout UINT32 [in] - new retry count (a minimum value of 1 must be used) - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_FAIL : invalid parameter(s) - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccMiiAccessTimeoutSet(UINT32 timeout, UINT32 retryCount); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccMiiStatsShow (UINT32 phyAddr) - * - * - * @brief Displays detailed information on a specified PHY - * - * Displays the current values of the first eigth MII registers for a PHY, - * - * @li Reentrant - no - * @li ISR Callable - no - * - * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and - * generating the MDIO clock. - * - * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31) - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_FAIL : invalid arguments. - * - *
- */ -PUBLIC IxEthAccStatus ixEthAccMiiStatsShow (UINT32 phyAddr); - - - -/******* BOARD SPECIFIC DEPRECATED API *********/ - -/* The following functions are high level functions which rely - * on the properties and interface of some Ethernet PHYs. The - * implementation is hardware specific and has been moved to - * the hardware-specific component IxEthMii. - */ - - #include "IxEthMii.h" - -/** - * @ingroup IxEthAcc - * - * @def ixEthAccMiiPhyScan - * - * @brief : deprecated API entry point. This definition - * ensures backward compatibility - * - * See @ref ixEthMiiPhyScan - * - * @note this feature is board specific - * - */ -#define ixEthAccMiiPhyScan(phyPresent) ixEthMiiPhyScan(phyPresent,IXP425_ETH_ACC_MII_MAX_ADDR) - -/** - * @ingroup IxEthAcc - * - * @def ixEthAccMiiPhyConfig - * - * @brief : deprecated API entry point. This definition - * ensures backward compatibility - * - * See @ref ixEthMiiPhyConfig - * - * @note this feature is board specific - */ -#define ixEthAccMiiPhyConfig(phyAddr,speed100,fullDuplex,autonegotiate) \ - ixEthMiiPhyConfig(phyAddr,speed100,fullDuplex,autonegotiate) - -/** - * @ingroup IxEthAcc - * - * @def ixEthAccMiiPhyReset - * - * @brief : deprecated API entry point. This definition - * ensures backward compatibility - * - * See @ref ixEthMiiPhyReset - * - * @note this feature is board specific - */ -#define ixEthAccMiiPhyReset(phyAddr) \ - ixEthMiiPhyReset(phyAddr) - -/** - * @ingroup IxEthAcc - * - * @def ixEthAccMiiLinkStatus - * - * @brief : deprecated API entry point. This definition - * ensures backward compatibility - * - * See @ref ixEthMiiLinkStatus - * - * @note this feature is board specific - */ -#define ixEthAccMiiLinkStatus(phyAddr,linkUp,speed100,fullDuplex,autoneg) \ - ixEthMiiLinkStatus(phyAddr,linkUp,speed100,fullDuplex,autoneg) - - - -/** - * @ingroup IxEthAcc - * - * @def ixEthAccMiiShow - * - * @brief : deprecated API entry point. This definition - * ensures backward compatibility - * - * See @ref ixEthMiiPhyShow - * - * @note this feature is board specific - */ -#define ixEthAccMiiShow(phyAddr) \ - ixEthMiiPhyShow(phyAddr) - -#endif /* ndef IxEthAcc_H */ -/** - *@} - */ diff --git a/cpu/ixp/npe/include/IxEthAccDataPlane_p.h b/cpu/ixp/npe/include/IxEthAccDataPlane_p.h deleted file mode 100644 index 8b8e6b256c..0000000000 --- a/cpu/ixp/npe/include/IxEthAccDataPlane_p.h +++ /dev/null @@ -1,245 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - - - -#ifndef IxEthAccDataPlane_p_H -#define IxEthAccDataPlane_p_H - -#include -#include - -/** - * @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 */ - - -/** - *@} - */ - diff --git a/cpu/ixp/npe/include/IxEthAccMac_p.h b/cpu/ixp/npe/include/IxEthAccMac_p.h deleted file mode 100644 index 93e9d98e76..0000000000 --- a/cpu/ixp/npe/include/IxEthAccMac_p.h +++ /dev/null @@ -1,248 +0,0 @@ -/* - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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*/ - diff --git a/cpu/ixp/npe/include/IxEthAccMii_p.h b/cpu/ixp/npe/include/IxEthAccMii_p.h deleted file mode 100644 index 568d4a0fa4..0000000000 --- a/cpu/ixp/npe/include/IxEthAccMii_p.h +++ /dev/null @@ -1,97 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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*/ diff --git a/cpu/ixp/npe/include/IxEthAccQueueAssign_p.h b/cpu/ixp/npe/include/IxEthAccQueueAssign_p.h deleted file mode 100644 index e5fd16e2fb..0000000000 --- a/cpu/ixp/npe/include/IxEthAccQueueAssign_p.h +++ /dev/null @@ -1,137 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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 ) diff --git a/cpu/ixp/npe/include/IxEthAcc_p.h b/cpu/ixp/npe/include/IxEthAcc_p.h deleted file mode 100644 index 0ee4123557..0000000000 --- a/cpu/ixp/npe/include/IxEthAcc_p.h +++ /dev/null @@ -1,325 +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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @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; /**< Recieve 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 */ - - - diff --git a/cpu/ixp/npe/include/IxEthDB.h b/cpu/ixp/npe/include/IxEthDB.h deleted file mode 100644 index 1189c9a140..0000000000 --- a/cpu/ixp/npe/include/IxEthDB.h +++ /dev/null @@ -1,2373 +0,0 @@ -/** @file IxEthDB.h - * - * @brief this file contains the public API of @ref IxEthDB component - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - * - */ - -#ifndef IxEthDB_H -#define IxEthDB_H - -#include -#include - -/** - * @defgroup IxEthDB IXP400 Ethernet Database (IxEthDB) API - * - * @brief ethDB is a library that does provides a MAC address database learning/filtering capability - * - *@{ - */ - -#define INLINE __inline__ - -#define IX_ETH_DB_PRIVATE PRIVATE /* imported from IxTypes.h */ - -#define IX_ETH_DB_PUBLIC PUBLIC - -/** - * @brief port ID => message handler NPE id conversion (0 => NPE_B, 1 => NPE_C) - */ -#define IX_ETH_DB_PORT_ID_TO_NPE(id) (id == 0 ? 1 : (id == 1 ? 2 : (id == 2 ? 0 : -1))) - -/** - * @def IX_ETH_DB_NPE_TO_PORT_ID(npe) - * @brief message handler NPE id => port ID conversion (NPE_B => 0, NPE_C => 1) - */ -#define IX_ETH_DB_NPE_TO_PORT_ID(npe) (npe == 0 ? 2 : (npe == 1 ? 0 : (npe == 2 ? 1 : -1))) - -/* temporary define - won't work for Azusa */ -#define IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(id) (IX_ETH_DB_PORT_ID_TO_NPE(id) << 4) -#define IX_ETH_DB_NPE_LOGICAL_ID_TO_PORT_ID(id) (IX_ETH_DB_NPE_TO_PORT_ID(id >> 4)) - -/** - * @def IX_IEEE803_MAC_ADDRESS_SIZE - * @brief The size of the MAC address - */ -#define IX_IEEE803_MAC_ADDRESS_SIZE (6) - -/** - * @def IX_IEEE802_1Q_QOS_PRIORITY_COUNT - * @brief Number of QoS priorities defined by IEEE802.1Q - */ -#define IX_IEEE802_1Q_QOS_PRIORITY_COUNT (8) - -/** - * @enum IxEthDBStatus - * @brief Ethernet Database API return values - */ -typedef enum /* IxEthDBStatus */ -{ - IX_ETH_DB_SUCCESS = IX_SUCCESS, /**< Success */ - IX_ETH_DB_FAIL = IX_FAIL, /**< Failure */ - IX_ETH_DB_INVALID_PORT, /**< Invalid port */ - IX_ETH_DB_PORT_UNINITIALIZED, /**< Port not initialized */ - IX_ETH_DB_MAC_UNINITIALIZED, /**< MAC not initialized */ - IX_ETH_DB_INVALID_ARG, /**< Invalid argument */ - IX_ETH_DB_NO_SUCH_ADDR, /**< Address not found for search or delete operations */ - IX_ETH_DB_NOMEM, /**< Learning database memory full */ - IX_ETH_DB_BUSY, /**< Learning database cannot complete operation, access temporarily blocked */ - IX_ETH_DB_END, /**< Database browser passed the end of the record set */ - IX_ETH_DB_INVALID_VLAN, /**< Invalid VLAN ID (valid range is 0..4094, 0 signifies no VLAN membership, used for priority tagged frames) */ - IX_ETH_DB_INVALID_PRIORITY, /**< Invalid QoS priority/traffic class (valid range for QoS priority is 0..7, valid range for traffic class depends on run-time configuration) */ - IX_ETH_DB_NO_PERMISSION, /**< No permission for attempted operation */ - IX_ETH_DB_FEATURE_UNAVAILABLE, /**< Feature not available (or not enabled) */ - IX_ETH_DB_INVALID_KEY, /**< Invalid search key */ - IX_ETH_DB_INVALID_RECORD_TYPE /**< Invalid record type */ -} IxEthDBStatus; - -/** @brief VLAN ID type, valid range is 0..4094, 0 signifying no VLAN membership */ -typedef UINT32 IxEthDBVlanId; - -/** @brief 802.1Q VLAN tag, contains 3 bits user priority, 1 bit CFI, 12 bits VLAN ID */ -typedef UINT32 IxEthDBVlanTag; - -/** @brief QoS priority/traffic class type, valid range is 0..7, 0 being the lowest */ -typedef UINT32 IxEthDBPriority; - -/** @brief Priority mapping table; 0..7 QoS priorities used to index, table contains traffic classes */ -typedef UINT8 IxEthDBPriorityTable[8]; - -/** @brief A 4096 bit array used to map the complete VLAN ID range */ -typedef UINT8 IxEthDBVlanSet[512]; - -#define IX_ETH_DB_802_1Q_VLAN_MASK (0xFFF) -#define IX_ETH_DB_802_1Q_QOS_MASK (0x7) - -#define IX_ETH_DB_802_1Q_MAX_VLAN_ID (0xFFE) - -/** - * @def IX_ETH_DB_SET_VLAN_ID - * @brief returns the given 802.1Q tag with the VLAN ID field substituted with the given VLAN ID - * - * This macro is used to change the VLAN ID in a 802.1Q tag. - * - * Example: - * - * tag = IX_ETH_DB_SET_VLAN_ID(tag, 32) - * - * inserts the VLAN ID "32" in the given tag. - */ -#define IX_ETH_DB_SET_VLAN_ID(vlanTag, vlanID) (((vlanTag) & 0xF000) | ((vlanID) & IX_ETH_DB_802_1Q_VLAN_MASK)) - -/** -* @def IX_ETH_DB_GET_VLAN_ID -* @brief returns the VLAN ID from the given 802.1Q tag -*/ -#define IX_ETH_DB_GET_VLAN_ID(vlanTag) ((vlanTag) & IX_ETH_DB_802_1Q_VLAN_MASK) - -#define IX_ETH_DB_GET_QOS_PRIORITY(vlanTag) (((vlanTag) >> 13) & IX_ETH_DB_802_1Q_QOS_MASK) - -#define IX_ETH_DB_SET_QOS_PRIORITY(vlanTag, priority) (((vlanTag) & 0x1FFF) | (((priority) & IX_ETH_DB_802_1Q_QOS_MASK) << 13)) - -#define IX_ETH_DB_CHECK_VLAN_TAG(vlanTag) { if(((vlanTag & 0xFFFF0000) != 0) || (IX_ETH_DB_GET_VLAN_ID(vlanTag) > 4094)) return IX_ETH_DB_INVALID_VLAN; } - -#define IX_ETH_DB_CHECK_VLAN_ID(vlanId) { if (vlanId > IX_ETH_DB_802_1Q_MAX_VLAN_ID) return IX_ETH_DB_INVALID_VLAN; } - -#define IX_IEEE802_1Q_VLAN_TPID (0x8100) - -typedef enum -{ - IX_ETH_DB_UNTAGGED_FRAMES = 0x1, /**< Accepts untagged frames */ - IX_ETH_DB_VLAN_TAGGED_FRAMES = 0x2, /**< Accepts tagged frames */ - IX_ETH_DB_PRIORITY_TAGGED_FRAMES = 0x4, /**< Accepts tagged frames with VLAN ID set to 0 (no VLAN membership) */ - IX_ETH_DB_ACCEPT_ALL_FRAMES = - IX_ETH_DB_UNTAGGED_FRAMES | IX_ETH_DB_VLAN_TAGGED_FRAMES /**< Accepts all the frames */ -} IxEthDBFrameFilter; - -typedef enum -{ - IX_ETH_DB_PASS_THROUGH = 0x1, /**< Leave frame as-is */ - IX_ETH_DB_ADD_TAG = 0x2, /**< Add default port VLAN tag */ - IX_ETH_DB_REMOVE_TAG = 0x3 /**< Remove VLAN tag from frame */ -} IxEthDBTaggingAction; - -typedef enum -{ - IX_ETH_DB_FIREWALL_WHITE_LIST = 0x1, /**< Firewall operates in white-list mode (MAC address based admission) */ - IX_ETH_DB_FIREWALL_BLACK_LIST = 0x2 /**< Firewall operates in black-list mode (MAC address based blocking) */ -} IxEthDBFirewallMode; - -typedef enum -{ - IX_ETH_DB_FILTERING_RECORD = 0x01, /**< - *
Filtering record
MAC address static/dynamic type age - *
- */ - IX_ETH_DB_FILTERING_VLAN_RECORD = 0x02, /**< - *
VLAN-enabled filtering record
MAC address static/dynamic type age 802.1Q tag - *
- */ - IX_ETH_DB_WIFI_RECORD = 0x04, /**< - *
WiFi header conversion record
MAC address optional gateway MAC address - *
- */ - IX_ETH_DB_FIREWALL_RECORD = 0x08, /**< - *
Firewall record
MAC address - *
- */ - IX_ETH_DB_GATEWAY_RECORD = 0x10, /**< For internal use only */ - IX_ETH_DB_MAX_RECORD_TYPE_INDEX = 0x10, /**< For internal use only */ - IX_ETH_DB_NO_RECORD_TYPE = 0, /**< None of the registered record types */ - IX_ETH_DB_ALL_FILTERING_RECORDS = IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD, /**< All the filtering records */ - IX_ETH_DB_ALL_RECORD_TYPES = IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD | - IX_ETH_DB_WIFI_RECORD | IX_ETH_DB_FIREWALL_RECORD /**< All the record types registered within EthDB */ -} IxEthDBRecordType; - -typedef enum -{ - IX_ETH_DB_LEARNING = 0x01, /**< Learning feature; enables EthDB to learn MAC address (filtering) records, including 802.1Q enabled records */ - IX_ETH_DB_FILTERING = 0x02, /**< Filtering feature; enables EthDB to communicate with the NPEs for downloading filtering information in the NPEs; depends on the learning feature */ - IX_ETH_DB_VLAN_QOS = 0x04, /**< VLAN/QoS feature; enables EthDB to configure NPEs to operate in VLAN/QoS aware modes */ - IX_ETH_DB_FIREWALL = 0x08, /**< Firewall feature; enables EthDB to configure NPEs to operate in firewall mode, using white/black address lists */ - IX_ETH_DB_SPANNING_TREE_PROTOCOL = 0x10, /**< Spanning tree protocol feature; enables EthDB to configure the NPEs as STP nodes */ - IX_ETH_DB_WIFI_HEADER_CONVERSION = 0x20 /**< WiFi 802.3 to 802.11 header conversion feature; enables EthDB to handle WiFi conversion data */ -} IxEthDBFeature; - -typedef UINT32 IxEthDBProperty; /**< Property ID type */ - -typedef enum -{ - IX_ETH_DB_INTEGER_PROPERTY = 0x1, /**< 4 byte unsigned integer type */ - IX_ETH_DB_STRING_PROPERTY = 0x2, /**< NULL-terminated string type of maximum 255 characters (including the terminator) */ - IX_ETH_DB_MAC_ADDR_PROPERTY = 0x3, /**< 6 byte MAC address type */ - IX_ETH_DB_BOOL_PROPERTY = 0x4 /**< 4 byte boolean type; can contain only TRUE and FALSE values */ -} IxEthDBPropertyType; - -/* list of supported properties for the IX_ETH_DB_VLAN_QOS feature */ -#define IX_ETH_DB_QOS_TRAFFIC_CLASS_COUNT_PROPERTY (0x01) /**< Property identifying number the supported number of traffic classes */ -#define IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY (0x10) /**< Rx queue assigned to traffic class 0 */ -#define IX_ETH_DB_QOS_TRAFFIC_CLASS_1_RX_QUEUE_PROPERTY (0x11) /**< Rx queue assigned to traffic class 1 */ -#define IX_ETH_DB_QOS_TRAFFIC_CLASS_2_RX_QUEUE_PROPERTY (0x12) /**< Rx queue assigned to traffic class 2 */ -#define IX_ETH_DB_QOS_TRAFFIC_CLASS_3_RX_QUEUE_PROPERTY (0x13) /**< Rx queue assigned to traffic class 3 */ -#define IX_ETH_DB_QOS_TRAFFIC_CLASS_4_RX_QUEUE_PROPERTY (0x14) /**< Rx queue assigned to traffic class 4 */ -#define IX_ETH_DB_QOS_TRAFFIC_CLASS_5_RX_QUEUE_PROPERTY (0x15) /**< Rx queue assigned to traffic class 5 */ -#define IX_ETH_DB_QOS_TRAFFIC_CLASS_6_RX_QUEUE_PROPERTY (0x16) /**< Rx queue assigned to traffic class 6 */ -#define IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY (0x17) /**< Rx queue assigned to traffic class 7 */ - -/* private property used by EthAcc to indicate queue configuration complete */ -#define IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE (0x18) - -/** - * - * @brief The IEEE 802.3 Ethernet MAC address structure. - * - * The data should be packed with bytes xx:xx:xx:xx:xx:xx - * - * @note The data must be packed in network byte order. - */ -typedef struct -{ - UINT8 macAddress[IX_IEEE803_MAC_ADDRESS_SIZE]; -} IxEthDBMacAddr; - -/** - * @ingroup IxEthDB - * - * @brief Definition of an IXP400 port. - */ -typedef UINT32 IxEthDBPortId; - -/** - * @ingroup IxEthDB - * - * @brief Port dependency map definition - */ -typedef UINT8 IxEthDBPortMap[32]; - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBInit(void) - * - * @brief Initializes the Ethernet learning/filtering database - * - * @note calling this function multiple times does not constitute an error; - * redundant calls will be ignored, returning IX_ETH_DB_SUCCESS - * - * @retval IX_ETH_DB_SUCCESS initialization was successful - * @retval IX_ETH_DB_FAIL initialization failed (OS error) - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBInit(void); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBUnload(void) - * - * @brief Stops and prepares the EthDB component for unloading. - * - * @retval IX_ETH_DB_SUCCESS de-initialization was successful - * @retval IX_ETH_DB_BUSY de-initialization failed, ports must be disabled first - * @retval IX_ETH_DB_FAIL de-initialization failed (OS error) - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBUnload(void); - -/** - * @ingroup IxEthDB - * - * @fn void ixEthDBPortInit(IxEthDBPortId portID) - * - * @brief Initializes a port - * - * This function is called automatically by the Ethernet Access - * ixEthAccPortInit() routine for Ethernet NPE ports and should be manually - * called for any user-defined port (any port that is not one of - * the two Ethernet NPEs). - * - * @param portID @ref IxEthDBPortId [in] - ID of the port to be initialized - * - * @see IxEthDBPortDefs.h for port definitions - * - * @note calling this function multiple times does not constitute an error; - * redundant calls will be ignored - */ -IX_ETH_DB_PUBLIC -void ixEthDBPortInit(IxEthDBPortId portID); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPortEnable(IxEthDBPortId portID) - * - * @brief Enables a port - * - * This function is called automatically from the Ethernet Access component - * ixEthAccPortEnable() routine for Ethernet NPE ports and should be manually - * called for any user-defined port (any port that is not one of - * the Ethernet NPEs). - * - * @param portID @ref IxEthDBPortId [in] - ID of the port to enable processing on - * - * @retval IX_ETH_DB_SUCCESS if enabling is successful - * @retval IX_ETH_DB_FAIL if the enabling was not successful due to - * a message handler error - * @retval IX_ETH_DB_MAC_UNINITIALIZED the MAC address of this port was - * not initialized (only for Ethernet NPEs) - * @retval IX_ETH_DB_INVALID_PORT if portID is invalid - * - * @pre ixEthDBPortAddressSet needs to be called prior to enabling the port events - * for Ethernet NPEs - * - * @see ixEthDBPortAddressSet - * - * @see IxEthDBPortDefs.h for port definitions - * - * @note calling this function multiple times does not constitute an error; - * redundant calls will be ignored - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortEnable(IxEthDBPortId portID); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPortDisable(IxEthDBPortId portID) - * - * @brief Disables processing on a port - * - * This function is called automatically from the Ethernet Access component - * ixEthAccPortDisable() routine for Ethernet NPE ports and should be manually - * called for any user-defined port (any port that is not one of - * the Ethernet NPEs). - * - * @note Calling ixEthAccPortDisable() will disable the respective Ethernet NPE. - * After Ethernet NPEs are disabled they are stopped therefore - * when re-enabled they need to be reset, downloaded with microcode and started. - * For learning to restart working the user needs to call again - * ixEthAccPortUnicastMacAddressSet or ixEthDBUnicastAddressSet - * with the respective port MAC address. - * Residual MAC addresses learnt before the port was disabled are deleted as soon - * as the port is disabled. This only applies to dynamic (learnt) entries, static - * entries do not dissapear when the port is disabled. - * - * @param portID @ref IxEthDBPortId [in] - ID of the port to disable processing on - * - * @retval IX_ETH_DB_SUCCESS if disabling is successful - * @retval IX_ETH_DB_FAIL if the disabling was not successful due to - * a message handler error - * @retval IX_ETH_DB_INVALID_PORT if portID is invalid - * - * @note calling this function multiple times after the first time completed successfully - * does not constitute an error; redundant calls will be ignored and return IX_ETH_DB_SUCCESS -*/ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortDisable(IxEthDBPortId portID); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPortAddressSet(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) - * - * @brief Sets the port MAC address - * - * This function is to be called from the Ethernet Access component top-level - * ixEthDBUnicastAddressSet(). Event processing cannot be enabled for a port - * until its MAC address has been set. - * - * @param portID @ref IxEthDBPortId [in] - ID of the port whose MAC address is set - * @param macAddr @ref IxEthDBMacAddr [in] - port MAC address - * - * @retval IX_ETH_DB_SUCCESS MAC address was set successfully - * @retval IX_ETH_DB_FAIL MAC address was not set due to a message handler failure - * @retval IX_ETH_DB_INVALID_PORT if the port is not an Ethernet NPE - * - * @see IxEthDBPortDefs.h for port definitions - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortAddressSet(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFilteringPortMaximumFrameSizeSet(IxEthDBPortId portID, UINT32 maximumFrameSize) - * - * @brief Set the maximum frame size supported on the given port ID - * - * This functions set the maximum frame size supported on a specific port ID - * - * - Reentrant - yes - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - port ID to configure - * @param maximumFrameSize UINT32 [in] - maximum frame size to configure - * - * @retval IX_ETH_DB_SUCCESS the port is configured - * @retval IX_ETH_DB_PORT_UNINITIALIZED the port has not been initialized - * @retval IX_ETH_DB_INVALID_PORT portID is invalid - * @retval IX_ETH_DB_INVALID_ARG size parameter is out of range - * @retval IX_ETH_DB_NO_PERMISSION selected port is not an Ethernet NPE - * @retval IX_FAIL unknown OS or NPE communication error - * - * @note - * This maximum frame size is used to filter the frames based on their - * destination addresses and the capabilities of the destination port. - * The mximum value that can be set for a NPE port is 16320. - * (IX_ETHNPE_ACC_FRAME_LENGTH_MAX) - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFilteringPortMaximumFrameSizeSet(IxEthDBPortId portID, UINT32 maximumFrameSize); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFilteringStaticEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) - * - * @brief Populate the Ethernet learning/filtering database with a static MAC address - * - * Populates the Ethernet learning/filtering database with a static MAC address. The entry will not be subject to aging. - * If there is an entry (static or dynamic) with the corresponding MAC address on any port this entry will take precedence. - * Any other entry with the same MAC address will be removed. - * - * - Reentrant - yes - * - ISR Callable - yes - * - * @param portID @ref IxEthDBPortId [in] - port ID to add the static address to - * @param macAddr @ref IxEthDBMacAddr [in] - static MAC address to add - * - * @retval IX_ETH_DB_SUCCESS the add was successful - * @retval IX_ETH_DB_FAIL failed to populate the database entry - * @retval IX_ETH_DB_BUSY failed due to a temporary busy condition (i.e. lack of CPU cycles), try again later - * @retval IX_ETH_DB_INVALID_PORT portID is invalid - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE learning feature is disabled - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFilteringStaticEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFilteringDynamicEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) - * - * @brief Populate the Ethernet learning/filtering database with a dynamic MAC address - * - * Populates the Ethernet learning/filtering database with a dynamic MAC address. This entry will be subject to normal - * aging function, if aging is enabled on its port. - * If there is an entry (static or dynamic) with the same MAC address on any port this entry will take precedence. - * Any other entry with the same MAC address will be removed. - * - * - Reentrant - yes - * - ISR Callable - yes - * - * @param portID @ref IxEthDBPortId [in] - port ID to add the dynamic address to - * @param macAddr @ref IxEthDBMacAddr [in] - static MAC address to add - * - * @retval IX_ETH_DB_SUCCESS the add was successful - * @retval IX_ETH_DB_FAIL failed to populate the database entry - * @retval IX_ETH_DB_BUSY failed due to a temporary busy condition (i.e. lack of CPU cycles), try again later - * @retval IX_ETH_DB_INVALID_PORT portID is invalid - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE learning feature is disabled - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFilteringDynamicEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFilteringEntryDelete(IxEthDBMacAddr *macAddr) - * - * @brief Removes a MAC address entry from the Ethernet learning/filtering database - * - * @param macAddr IxEthDBMacAddr [in] - MAC address to remove - * - * - Reentrant - yes - * - ISR Callable - no - * - * @retval IX_ETH_DB_SUCCESS the removal was successful - * @retval IX_ETH_DB_NO_SUCH_ADDR failed to remove the address (not in the database) - * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument - * @retval IX_ETH_DB_BUSY failed due to a temporary busy condition (i.e. lack of CPU cycles), try again later - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFilteringEntryDelete(IxEthDBMacAddr *macAddr); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFilteringPortSearch(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) - * - * @brief Search the Ethernet learning/filtering database for the given MAC address and port ID - * - * This functions searches the database for a specific port ID and MAC address. Both the port ID - * and the MAC address have to match in order for the record to be reported as found. - * - * - Reentrant - yes - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - port ID to search for - * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to search for - * - * @retval IX_ETH_DB_SUCCESS the record exists in the database - * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument - * @retval IX_ETH_DB_NO_SUCH_ADDR the record was not found in the database - * @retval IX_ETH_DB_INVALID_PORT portID is invalid - * @retval IX_ETH_DB_PORT_UNINITIALIZED port ID is not initialized - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE learning feature is disabled - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFilteringPortSearch(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFilteringDatabaseSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr) - * - * @brief Search the Ethernet learning/filtering database for a MAC address and return the port ID - * - * Searches the database for a MAC address. The function returns the portID for the - * MAC address record, if found. If no match is found the function returns IX_ETH_DB_NO_SUCH_ADDR. - * The portID is only valid if the function finds a match. - * - * - Reentrant - yes - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - port ID the address belongs to (populated only on a successful search) - * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to search for - * - * @retval IX_ETH_DB_SUCCESS the record exists in the database - * @retval IX_ETH_DB_NO_SUCH_ADDR the record was not found in the database - * @retval IX_ETH_DB_INVALID_ARG invalid macAddr or portID pointer argument(s) - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFilteringDatabaseSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFilteringPortUpdatingSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr) - * - * @brief Search the filtering database for a MAC address, return the port ID and reset the record age - * - * Searches the database for a MAC address. The function returns the portID for the - * MAC address record and resets the entry age to 0, if found. - * If no match is found the function returns IX_ETH_DB_NO_SUCH_ADDR. - * The portID is only valid if the function finds a match. - * - * - Reentrant - yes - * - ISR Callable - no - * - * @retval IX_ETH_DB_SUCCESS the MAC address was found - * @retval IX_ETH_DB_NO_SUCH_ADDR the MAC address was not found - * @retval IX_ETH_DB_INVALID_ARG invalid macAddr or portID pointer argument(s) - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFilteringPortUpdatingSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr); - -/** - * @ingroup IxEthDB - * - * @def IX_ETH_DB_MAINTENANCE_TIME - * - * @brief The @ref ixEthDBDatabaseMaintenance must be called by the user at a frequency of - * IX_ETH_DB_MAINTENANCE_TIME - * - */ -#define IX_ETH_DB_MAINTENANCE_TIME (1 * 60) /* 1 Minute */ - -/** - * @ingroup IxEthDB - * - * @def IX_ETH_DB_LEARNING_ENTRY_AGE_TIME - * - * @brief The define specifies the filtering database age entry time. Static entries older than - * IX_ETH_DB_LEARNING_ENTRY_AGE_TIME +/- IX_ETH_DB_MAINTENANCE_TIME shall be removed. - * - */ -#define IX_ETH_DB_LEARNING_ENTRY_AGE_TIME (15 * 60 ) /* 15 Mins */ - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPortAgingDisable(IxEthDBPortId portID) - * - * @brief Disable the aging function for a specific port - * - * @param portID @ref IxEthDBPortId [in] - port ID to disable aging on - * - * - Reentrant - yes - * - ISR Callable - no - * - * @retval IX_ETH_DB_SUCCESS aging disabled successfully - * @retval IX_ETH_DB_INVALID_PORT portID is invalid - * @retval IX_ETH_DB_PORT_UNINITIALIZED port ID is not initialized - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE learning feature is disabled - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortAgingDisable(IxEthDBPortId portID); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPortAgingEnable(IxEthDBPortId portID) - * - * @brief Enable the aging function for a specific port - * - * Enables the aging of dynamic MAC address entries stored in the learning/filtering database - * - * @note The aging function relies on the @ref ixEthDBDatabaseMaintenance being called with a period of - * @ref IX_ETH_DB_MAINTENANCE_TIME seconds. - * - * - Reentrant - yes - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - port ID to enable aging on - * - * @retval IX_ETH_DB_SUCCESS aging enabled successfully - * @retval IX_ETH_DB_INVALID_PORT portID is invalid - * @retval IX_ETH_DB_PORT_UNINITIALIZED port ID is not initialized - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE learning feature is disabled - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortAgingEnable(IxEthDBPortId portID); - -/** - * @ingroup IxEthDB - * - * @fn void ixEthDBDatabaseMaintenance(void) - * - * @brief Performs a maintenance operation on the Ethernet learning/filtering database - * - * In order to perform a database maintenance this function must be called every - * @ref IX_ETH_DB_MAINTENANCE_TIME seconds. It should be called regardless of whether learning is - * enabled or not. - * - * - Reentrant - no - * - ISR Callable - no - * - * @note this function call will be ignored if the learning feature is disabled - */ -IX_ETH_DB_PUBLIC -void ixEthDBDatabaseMaintenance(void); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFilteringDatabaseShow(IxEthDBPortId portID) - * - * @brief This function displays the Mac Ethernet MAC address filtering tables. - * - * It displays the MAC address, port ID, entry type (dynamic/static),and age for - * the given port ID. - * - * - Reentrant - no - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - port ID to display the MAC address entries - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is invalid - * @retval IX_ETH_DB_PORT_UNINITIALIZED port ID is not initialized - * @retval IX_ETH_DB_FAIL record browser failed due to an internal busy or lock condition - * - * @note this function is deprecated and kept for compatibility reasons; use @ref ixEthDBFilteringDatabaseShowRecords instead - * - * @see ixEthDBFilteringDatabaseShowRecords - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFilteringDatabaseShow(IxEthDBPortId portID); - -/** - * @ingroup IxEthDB - * - * @fn void ixEthDBFilteringDatabaseShowAll(void) - * - * @brief Displays the MAC address recorded in the filtering database for all registered - * ports (see IxEthDBPortDefs.h), grouped by port ID. - * - * - Reentrant - no - * - ISR Callable - no - * - * @retval void - * - * @note this function is deprecated and kept for compatibility reasons; use @ref ixEthDBFilteringDatabaseShowRecords instead - * - * @see ixEthDBFilteringDatabaseShowRecords - */ -IX_ETH_DB_PUBLIC -void ixEthDBFilteringDatabaseShowAll(void); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFilteringDatabaseShowRecords(IxEthDBPortId portID, IxEthDBRecordType recordFilter) - * - * @brief This function displays per port database records, given a record type filter - * - * The supported record type filters are: - * - * - IX_ETH_DB_FILTERING_RECORD - displays the non-VLAN filtering records (MAC address, age, static/dynamic) - * - IX_ETH_DB_FILTERING_VLAN_RECORD - displays the VLAN filtering records (MAC address, age, static/dynamic, VLAN ID, CFI, QoS class) - * - IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD - displays the previous two types of records - * - IX_ETH_DB_WIFI_RECORD - displays the WiFi header conversion records (MAC address, optional gateway MAC address) and WiFi header conversion parameters (BBSID, Duration/ID) - * - IX_ETH_DB_FIREWALL_RECORD - displays the firewall MAC address table and firewall operating mode (white list/black list) - * - IX_ETH_DB_ALL_RECORD_TYPES - displays all the record types - * - IX_ETH_DB_NO_RECORD_TYPE - displays only the port status (no records are displayed) - * - * Additionally, the status of each port will be displayed, containg the following information: type, capabilities, enabled status, - * aging enabled status, group membership and maximum frame size. - * - * The port ID can either be an actual port or IX_ETH_DB_ALL_PORTS, in which case the requested information - * will be displayed for all the ports (grouped by port) - * - * - Reentrant - no - * - ISR Callable - no - * - * @param portID ID of the port to display information on (use IX_ETH_DB_ALL_PORTS for all the ports) - * @param recordFilter record type filter - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is invalid - * @retval IX_ETH_DB_PORT_UNINITIALIZED port ID is not initialized - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFilteringDatabaseShowRecords(IxEthDBPortId portID, IxEthDBRecordType recordFilter); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPortDependencyMapSet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap) - * - * @brief Sets the dependency port map for a port - * - * @param portID ID of the port to set the dependency map to - * @param dependencyPortMap new dependency map (as bitmap, each bit set indicates a port being included) - * - * This function is used to share filtering information between ports. - * By adding a port into another port's dependency map the target port - * filtering data will import the filtering data from the port it depends on. - * Any changes to filtering data for a port - such as adding, updating or removing records - - * will trigger updates in the filtering information for all the ports depending on - * on the updated port. - * - * For example, if ports 2 and 3 are set in the port 0 dependency map the filtering - * information for port 0 will also include the filtering information from ports 2 and 3. - * Adding a record to port 2 will also trigger an update not only on port 2 but also on - * port 0. - * - * The dependency map is a 256 bit array where each bit corresponds to a port corresponding to the - * bit offset (bit 0 - port 0, bit 1 - port 1 etc). Setting a bit to 1 indicates that the corresponding - * port is the port map. For example, a dependency port map of 0x14 consists in the ports with IDs 2 and 4. - * Note that the last bit (offset 255) is reserved and should never be set (it will be automatically - * cleared by the function). - * - * By default, each port has a dependency port map consisting only of itself, i.e. - * - * @verbatim - IxEthDBPortMap portMap; - - // clear all ports from port map - memset(portMap, 0, sizeof (portMap)); - - // include portID in port map - portMap[portID / 8] = 1 << (portID % 8); - @endverbatim - * - * - Reentrant - no - * - ISR Callable - no - * - * @note Setting dependency maps is useful for NPE ports, which benefit from automatic updates - * of filtering information. Setting dependency maps for user-defined ports is not an error - * but will have no actual effect. - * - * @note Including a port in its own dependency map is not compulsory, however note that - * in this case updating the port will not trigger an update on the port itself, which - * might not be the intended behavior - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid dependencyPortMap pointer - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Filtering is not available or not enabled for the port - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortDependencyMapSet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPortDependencyMapGet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap) - * - * @brief Retrieves the dependency port map for a port - * - * @param portID ID of the port to set the dependency map to - * @param dependencyPortMap location where the port dependency map is to be copied - * - * This function will copy the port dependency map to a user specified location. - * - * - Reentrant - no - * - ISR Callable - no - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid dependencyPortMap pointer - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Filtering is not available or not enabled for the port - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortDependencyMapGet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPortVlanTagSet(IxEthDBPortId portID, IxEthDBVlanTag vlanTag) - * - * @brief Sets the default 802.1Q VLAN tag for a given port - * - * @param portID @ref IxEthDBPortId [in] - ID of the port to set the default VLAN tag to - * @param vlanTag @ref IxEthDBVlanTag [in] - default 802.1Q VLAN tag - * - * The tag format has 16 bits and it is defined in the IEEE802.1Q specification. - * This tag will be used for tagging untagged frames (if enabled) and classifying - * unexpedited traffic into an internal traffic class (using the user priority field). - * - * - *
802.1Q tag format
3 bits 1 bit 12 bits - *
user priority CFI VID - *
- * - * User Priority : Defines user priority, giving eight (2^3) priority levels. IEEE 802.1P defines - * the operation for these 3 user priority bits - * - * CFI : Canonical Format Indicator is always set to zero for Ethernet switches. CFI is used for - * compatibility reason between Ethernet type network and Token Ring type network. If a frame received - * at an Ethernet port has a CFI set to 1, then that frame should not be forwarded as it is to an untagged port. - * - * VID : VLAN ID is the identification of the VLAN, which is basically used by the standard 802.1Q. - * It has 12 bits and allow the id entification of 4096 (2^12) VLANs. Of the 4096 possible VIDs, a VID of 0 - * is used to identify priority frames and value 4095 (FFF) is reserved, so the maximum possible VLAN - * configurations are 4,094. - * - * - Reentrant - no - * - ISR Callable - no - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - * @retval IX_ETH_DB_INVALID_VLAN vlanTag argument does not parse to a valid 802.1Q VLAN tag - * - * @note a VLAN ID value of 0 indicates that the port is not part of any VLAN - * @note the value of the cannonical frame indicator (CFI) field is ignored, the - * field being used only in frame tagging operations - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortVlanTagSet(IxEthDBPortId portID, IxEthDBVlanTag vlanTag); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPortVlanTagGet(IxEthDBPortId portID, IxEthDBVlanTag *vlanTag) - * - * @brief Retrieves the default 802.1Q port VLAN tag for a given port (see also @ref ixEthDBPortVlanTagSet) - * - * @param portID @ref IxEthDBPortId [in] - ID of the port to retrieve the default VLAN tag from - * @param vlanTag @ref IxEthDBVlanTag [out] - location to write the default port 802.1Q VLAN tag to - * - * - Reentrant - no - * - ISR Callable - no - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid vlanTag pointer - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortVlanTagGet(IxEthDBPortId portID, IxEthDBVlanTag *vlanTag); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBVlanTagSet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag vlanTag) - * - * @brief Sets the 802.1Q VLAN tag for a database record - * - * @param macAddr MAC address - * @param vlanTag 802.1Q VLAN tag - * - * This function is used together with @ref ixEthDBVlanTagGet to provide MAC-based VLAN classification support. - * Please note that the bridging application must contain specific code to make use of this feature (see below). - * - * VLAN tags can be set only in IX_ETH_DB_FILTERING_RECORD or IX_ETH_DB_FILTERING_VLAN_RECORD type records. - * If to an IX_ETH_DB_FILTERING_RECORD type record is added a VLAN tag the record type is automatically - * changed to IX_ETH_DB_FILTERING_VLAN_RECORD. Once this has occurred the record type will never - * revert to a non-VLAN type (unless deleted and re-added). - * - * Record types used for different purposes (such as IX_ETH_DB_WIFI_RECORD) will be ignored by - * this function. - * - * After using this function to associate a VLAN ID with a MAC address the VLAN ID can be extracted knowing the - * MAC address using @ref ixEthDBVlanTagGet. This mechanism can be used to implement MAC-based VLAN classification - * if a bridging application searches for the VLAN tag when receiving a frame based on the source MAC address - * (contained in the ixp_ne_src_mac field of the buffer header). - * If found in the database, the application can instruct the NPE to tag the frame by writing the VLAN tag - * in the ixp_ne_vlan_tci field of the buffer header. This way the NPE will inspect the Egress tagging - * rule associated with the given VLAN ID on the Tx port and tag the frame if Egress tagging on the VLAN is - * allowed. Additionally, Egress tagging can be forced by setting the ixp_ne_tx_flags.tag_over and - * ixp_ne_tx_flags.tag_mode flags in the buffer header. - * - * - Reentrant - no - * - ISR Callable - no - * - * @note this function will not add a filtering record, it can only be used to update an existing one - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer - * @retval IX_ETH_DB_NO_SUCH_ADDR a filtering record with the specified MAC address was not found - * @retval IX_ETH_DB_INVALID_VLAN vlanTag argument does not parse to a valid 802.1Q VLAN tag - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBVlanTagSet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag vlanTag); - -/** - * @ingroup IxEthDB - * - * @fn ixEthDBVlanTagGet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag *vlanTag) - * - * @brief Retrieves the 802.1Q VLAN tag from a database record given the record MAC address - * - * @param macAddr MAC address - * @param vlanTag location to write the record 802.1Q VLAN tag to - * - * @note VLAN tags can be retrieved only from IX_ETH_DB_FILTERING_VLAN_RECORD type records - * - * This function is used together with ixEthDBVlanTagSet to provide MAC-based VLAN classification support. - * Please note that the bridging application must contain specific code to make use of this feature (see @ref ixEthDBVlanTagSet). - * - * - Reentrant - no - * - ISR Callable - no - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_ARG invalid macAddr or vlanTag pointer - * @retval IX_ETH_DB_NO_SUCH_ADDR a filtering record with the specified MAC address was not found - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBVlanTagGet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag *vlanTag); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPortVlanMembershipAdd(IxEthDBPortId portID, IxEthDBVlanId vlanID) - * - * @brief Adds a VLAN ID to a port's VLAN membership table - * - * Adding a VLAN ID to a port's VLAN membership table will cause frames tagged with the specified - * VLAN ID to be accepted by the frame filter, if Ingress VLAN membership filtering is enabled. - * - * - Reentrant - no - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - ID of the port to add the VLAN ID membership to - * @param vlanID @ref IxEthDBVlanId [in] - VLAN ID to be added to the port membership table - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_VLAN vlanID is not a valid VLAN ID - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - * @retval IX_FAIL unknown OS or NPE communication error - * - * @note A port's default VLAN ID is always in its own membership table, hence there - * is no need to explicitly add it using this function (although it is not an error - * to do so) - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortVlanMembershipAdd(IxEthDBPortId portID, IxEthDBVlanId vlanID); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPortVlanMembershipRangeAdd(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax) - * - * @brief Adds a VLAN ID range to a port's VLAN membership table - * - * All the VLAN IDs in the specified range will be added to the port VLAN - * membership table, including the range start and end VLAN IDs. Tagged frames with - * VLAN IDs in the specified range will be accepted by the frame filter, if Ingress VLAN - * membership filtering is enabled. - * - * - Reentrant - no - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - port ID to add the VLAN membership range into - * @param vlanIDMin @ref IxEthDBVlanId [in] - start of the VLAN ID range - * @param vlanIDMax @ref IxEthDBVlanId [in] - end of the VLAN ID range - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_VLAN the specified VLAN IDs are invalid or do not constitute a range - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - * @retval IX_FAIL unknown OS or NPE communication error - * - * @note Is is valid to use the same VLAN ID for both vlanIDMin and vlanIDMax, in which case this - * function will behave as @ref ixEthDBPortVlanMembershipAdd - * - * @note A port's default VLAN ID is always in its own membership table, hence there is no need - * to explicitly add it using this function (although it is not an error to do so) - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortVlanMembershipRangeAdd(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPortVlanMembershipRemove(IxEthDBPortId portID, IxEthDBVlanId vlanID) - * - * @brief Removes a VLAN ID from a port's VLAN membership table - * - * Frames tagged with a VLAN ID which is not in a port's VLAN membership table - * will be discarded by the frame filter, if Ingress membership filtering is enabled. - * - * - Reentrant - no - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - ID of the port to remove the VLAN ID membership from - * @param vlanID @ref IxEthDBVlanId [in] - VLAN ID to be removed from the port membership table - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_INVALID_VLAN vlanID is not a valid VLAN ID - * @retval IX_ETH_DB_NO_PERMISSION attempted to remove the default VLAN ID - * from the port membership table (vlanID was set to the default port VLAN ID) - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - * @retval IX_FAIL unknown OS or NPE communication error - * - * @note A port's default VLAN ID cannot be removed from the port's membership - * table; attempting it will return IX_ETH_DB_NO_PERMISSION - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortVlanMembershipRemove(IxEthDBPortId portID, IxEthDBVlanId vlanID); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPortVlanMembershipRangeRemove(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax) - * - * @brief Removes a VLAN ID range from a port's VLAN membership table - * - * All the VLAN IDs in the specified range will be removed from the port VLAN - * membership table, including the range start and end VLAN IDs. Tagged frames - * with VLAN IDs in the range will be discarded by the frame filter, if Ingress - * membership filtering is enabled. - * - * - Reentrant - no - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - ID of the port to remove the VLAN membership range from - * @param vlanIDMin @ref IxEthDBVlanId [in] - start of the VLAN ID range - * @param vlanIDMax @ref IxEthDBVlanId [in] - end of the VLAN ID range - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_VLAN the specified VLAN IDs are invalid or do not constitute a range - * @retval IX_ETH_DB_NO_PERMISSION attempted to remove the default VLAN ID - * from the port membership table (both vlanIDMin and vlanIDMax were set to the default port VLAN ID) - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - * @retval IX_FAIL unknown OS or NPE communication error - * - * @note Is is valid to use the same VLAN ID for both vlanIDMin and vlanIDMax, in which case - * function will behave as @ref ixEthDBPortVlanMembershipRemove - * - * @note If the given range overlaps the default port VLAN ID this function - * will remove all the VLAN IDs in the range except for the port VLAN ID from its - * own membership table. This situation will be silently dealt with (no error message - * will be returned) as long as the range contains more than one value (i.e. at least - * one other value, apart from the default port VLAN ID). If the function is called - * with the vlanIDMin and vlanIDMax parameters both set to the port default VLAN ID, the - * function will infer that an attempt was specifically made to remove the default port - * VLAN ID from the port membership table, in which case the return value will be - * IX_ETH_DB_NO_PERMISSION. - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortVlanMembershipRangeRemove(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPortVlanMembershipSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet) - * - * @brief Sets a port's VLAN membership table - * - * Sets a port's VLAN membership table from a complete VLAN table containing all the possible - * 4096 VLAN IDs. The table format is an array containing 4096 bits (512 bytes), where each bit - * indicates whether the VLAN at that bit index is in the port's membership list (if set) or - * not (unset). - * - * The bit at index 0, indicating VLAN ID 0, indicates no VLAN membership and therefore no - * other bit must be set if bit 0 is set. - * - * The bit at index 4095 is reserved and should never be set (it will be ignored if set). - * - * The bit referencing the same VLAN ID as the default port VLAN ID should always be set, as - * the membership list must contain at least the default port VLAN ID. - * - * - Reentrant - no - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - port ID to set the VLAN membership table to - * @param vlanSet @ref IxEthDBVlanSet [in] - pointer to the VLAN membership table - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid vlanSet pointer - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - * @retval IX_FAIL unknown OS or NPE communication error - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortVlanMembershipSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPortVlanMembershipGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet) - * - * @brief Retrieves a port's VLAN membership table - * - * Retrieves the complete VLAN membership table from a port, containing all the possible - * 4096 VLAN IDs. The table format is an array containing 4096 bits (512 bytes), where each bit - * indicates whether the VLAN at that bit index is in the port's membership list (if set) or - * not (unset). - * - * The bit at index 0, indicating VLAN ID 0, indicates no VLAN membership and therefore no - * other bit will be set if bit 0 is set. - * - * The bit at index 4095 is reserved and will not be set (it will be ignored if set). - * - * The bit referencing the same VLAN ID as the default port VLAN ID will always be set, as - * the membership list must contain at least the default port VLAN ID. - * - * - Reentrant - no - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - port ID to retrieve the VLAN membership table from - * @param vlanSet @ref IxEthDBVlanSet [out] - pointer a location where the VLAN membership table will be - * written to - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid vlanSet pointer - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortVlanMembershipGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBAcceptableFrameTypeSet(IxEthDBPortId portID, IxEthDBFrameFilter frameFilter) - * - * @brief Sets a port's acceptable frame type filter - * - * The acceptable frame type is one (or a combination) of the following values: - * - IX_ETH_DB_ACCEPT_ALL_FRAMES - accepts all the frames - * - IX_ETH_DB_UNTAGGED_FRAMES - accepts untagged frames - * - IX_ETH_DB_VLAN_TAGGED_FRAMES - accepts tagged frames - * - IX_ETH_DB_PRIORITY_TAGGED_FRAMES - accepts tagged frames with VLAN ID set to 0 (no VLAN membership) - * - * Except for using the exact values given above only the following combinations are valid: - * - IX_ETH_DB_UNTAGGED_FRAMES | IX_ETH_DB_VLAN_TAGGED_FRAMES - * - IX_ETH_DB_UNTAGGED_FRAMES | IX_ETH_DB_PRIORITY_TAGGED_FRAMES - * - * Please note that IX_ETH_DB_UNTAGGED_FRAMES | IX_ETH_DB_VLAN_TAGGED_FRAMES is equivalent - * to IX_ETH_DB_ACCEPT_ALL_FRAMES. - * - * - Reentrant - no - * - ISR Callable - no - * - * @note by default the acceptable frame type filter is set to IX_ETH_DB_ACCEPT_ALL_FRAMES - * - * @note setting the acceptable frame type to PRIORITY_TAGGED_FRAMES is internally - * accomplished by changing the frame filter to VLAN_TAGGED_FRAMES and setting the - * VLAN membership list to include only VLAN ID 0; the membership list will need - * to be restored manually to an appropriate value if the acceptable frame type - * filter is changed back to ACCEPT_ALL_FRAMES or VLAN_TAGGED_FRAMES; failure to do so - * will filter all VLAN traffic bar frames tagged with VLAN ID 0 - * - * @param portID @ref IxEthDBPortId [in] - port ID to set the acceptable frame type filter to - * @param frameFilter @ref IxEthDBFrameFilter [in] - acceptable frame type filter - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid frame type filter - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - * @retval IX_FAIL unknown OS or NPE communication error - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBAcceptableFrameTypeSet(IxEthDBPortId portID, IxEthDBFrameFilter frameFilter); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBAcceptableFrameTypeGet(IxEthDBPortId portID, IxEthDBFrameFilter *frameFilter) - * - * @brief Retrieves a port's acceptable frame type filter - * - * For a description of the acceptable frame types see @ref ixEthDBAcceptableFrameTypeSet - * - * - Reentrant - no - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - port ID to retrieve the acceptable frame type filter from - * @param frameFilter @ref IxEthDBFrameFilter [out] - location to store the acceptable frame type filter - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid frameFilter pointer argument - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBAcceptableFrameTypeGet(IxEthDBPortId portID, IxEthDBFrameFilter *frameFilter); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPriorityMappingTableSet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable) - * - * @brief Sets a port's priority mapping table - * - * The priority mapping table is an 8x2 table mapping a QoS (user) priority into an internal - * traffic class. There are 8 valid QoS priorities (0..7, 0 being the lowest) which can be - * mapped into one of the 4 available traffic classes (0..3, 0 being the lowest). - * If a custom priority mapping table is not specified using this function the following - * default priority table will be used (as per IEEE 802.1Q and IEEE 802.1D): - * - * - *
QoS traffic classes
QoS priority Default traffic class Traffic type - *
0 1 Best effort, default class for unexpedited traffic - *
1 0 Background traffic - *
2 0 Spare bandwidth - *
3 1 Excellent effort - *
4 2 Controlled load - *
5 2 Video traffic - *
6 3 Voice traffic - *
7 3 Network control - *
- * - * - Reentrant - no - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - port ID of the port to set the priority mapping table to - * @param priorityTable @ref IxEthDBPriorityTable [in] - location of the user priority table - * - * @note The provided table will be copied into internal data structures in EthDB and - * can be deallocated by the called after this function has completed its execution, if - * so desired - * - * @warning The number of available traffic classes differs depending on the NPE images - * and queue configuration. Check IxEthDBQoS.h for up-to-date information on the availability of - * traffic classes. Note that specifiying a traffic class in the priority map which exceeds - * the system availability will produce an IX_ETH_DB_INVALID_PRIORITY return error code and no - * priority will be remapped. - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid priorityTable pointer - * @retval IX_ETH_DB_INVALID_PRIORITY at least one priority value exceeds - * the current number of available traffic classes - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - * @retval IX_FAIL unknown OS or NPE communication error - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPriorityMappingTableSet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPriorityMappingTableGet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable) - * - * @brief Retrieves a port's priority mapping table - * - * The priority mapping table for the given port will be copied in the location - * specified by the caller using "priorityTable" - * - * - Reentrant - no - * - ISR Callable - no - * - * @param portID ID @ref IxEthDBPortId [in] - of the port to retrieve the priority mapping table from - * @param priorityTable @ref IxEthDBPriorityTable [out] - pointer to a user specified location where the table will be copied to - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid priorityTable pointer - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPriorityMappingTableGet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPriorityMappingClassSet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority trafficClass) - * - * @brief Sets one QoS/user priority => traffic class mapping in a port's priority mapping table - * - * This function establishes a mapping between a user (QoS) priority and an internal traffic class. - * The mapping will be saved in the port's priority mapping table. Use this function when not all - * the QoS priorities need remapping (see also @ref ixEthDBPriorityMappingTableSet) - * - * - Reentrant - no - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - ID of the port to set the mapping to - * @param userPriority @ref IxEthDBPriority [in] - user (QoS) priority, between 0 and 7 (0 being the lowest) - * @param trafficClass @ref IxEthDBPriority [in] - internal traffic class, between 0 and 3 (0 being the lowest) - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_PRIORITY userPriority out of range or - * trafficClass is beyond the number of currently available traffic classes - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - * @retval IX_FAIL unknown OS or NPE communication error - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPriorityMappingClassSet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority trafficClass); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPriorityMappingClassGet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority *trafficClass) - * - * @brief Retrieves one QoS/user priority => traffic class mapping in a port's priority mapping table - * - * This function retrieves the internal traffic class associated with a QoS (user) priority from a given - * port's priority mapping table. Use this function when not all the QoS priority mappings are - * required (see also @ref ixEthDBPriorityMappingTableGet) - * - * - Reentrant - no - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - ID of the port to set the mapping to - * @param userPriority @ref IxEthDBPriority [in] - user (QoS) priority, between 0 and 7 (0 being the lowest) - * @param trafficClass @ref IxEthDBPriority [out] - location to write the corresponding internal traffic class to - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_PRIORITY invalid userPriority value (out of range) - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - * @retval IX_ETH_DB_INVALID_ARG invalid trafficClass pointer argument - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPriorityMappingClassGet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority *trafficClass); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL enabled) - * - * @brief Enables or disables Egress VLAN tagging for a port and a given VLAN - * - * This function enables or disables Egress VLAN tagging for the given port and VLAN ID. - * If the VLAN tagging for a certain VLAN ID is enabled then all the frames to be - * transmitted on the given port tagged with the same VLAN ID will be transmitted in a tagged format. - * If tagging is not enabled for the given VLAN ID, the VLAN tag from the frames matching - * this VLAN ID will be removed (the frames will be untagged). - * - * VLAN ID 4095 is reserved and should never be used with this function. - * VLAN ID 0 has the special meaning of "No VLAN membership" and it is used in this - * context to allow the port to send priority-tagged frames or not. - * - * By default, no Egress VLAN tagging is enabled on any port. - * - * - Reentrant - no - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - ID of the port to enable or disable the VLAN ID Egress tagging on - * @param vlanID @ref IxEthDBVlanId [in] - VLAN ID to be matched against outgoing frames - * @param enabled BOOL [in] - TRUE to enable Egress VLAN tagging on the port and given VLAN, and - * FALSE to disable Egress VLAN tagging - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_VLAN invalid VLAN ID (out of range) - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - * @retval IX_FAIL unknown OS or NPE communication error - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL enabled); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL *enabled) - * - * @brief Retrieves the Egress VLAN tagging enabling status for a port and VLAN ID - * - * @param portID [in] - ID of the port to extract the Egress VLAN ID tagging status from - * @param vlanID VLAN [in] - ID whose tagging status is to be extracted - * @param enabled [in] - user-specifed location where the status is copied to; following - * the successfull execution of this function the value will be TRUE if Egress VLAN - * tagging is enabled for the given port and VLAN ID, and FALSE otherwise - * - * - Reentrant - no - * - ISR Callable - no - * - * @see ixEthDBEgressVlanEntryTaggingEnabledGet - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_VLAN invalid VLAN ID (out of range) - * @retval IX_ETH_DB_INVALID_ARG invalid enabled argument pointer - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL *enabled); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBEgressVlanRangeTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax, BOOL enabled) - * - * @brief Enables or disables Egress VLAN tagging for a port and given VLAN range - * - * This function is very similar to @ref ixEthDBEgressVlanEntryTaggingEnabledSet with the - * difference that it can manipulate the Egress tagging status on multiple VLAN IDs, - * defined by a contiguous range. Note that both limits in the range are explicitly - * included in the execution of this function. - * - * - Reentrant - no - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - ID of the port to enable or disable the VLAN ID Egress tagging on - * @param vlanIDMin @ref IxEthDBVlanId [in] - start of the VLAN range to be matched against outgoing frames - * @param vlanIDMax @ref IxEthDBVlanId [in] - end of the VLAN range to be matched against outgoing frames - * @param enabled BOOL [in] - TRUE to enable Egress VLAN tagging on the port and given VLAN range, - * and FALSE to disable Egress VLAN tagging - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_VLAN invalid VLAN ID (out of range), or do not constitute a range - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - * @retval IX_ETH_DB_NO_PERMISSION attempted to explicitly remove the default port VLAN ID from the tagging table - * @retval IX_FAIL unknown OS or NPE communication error - * - * @note Specifically removing the default port VLAN ID from the Egress tagging table by setting both vlanIDMin and vlanIDMax - * to the VLAN ID portion of the PVID is not allowed by this function and will return IX_ETH_DB_NO_PERMISSION. - * However, this can be circumvented, should the user specifically desire this, by either using a - * larger range (vlanIDMin < vlanIDMax) or by using ixEthDBEgressVlanEntryTaggingEnabledSet. - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBEgressVlanRangeTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax, BOOL enabled); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBEgressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet) - * - * @brief Sets the complete Egress VLAN tagging table for a port - * - * This function is used to set the VLAN tagging/untagging per VLAN ID for a given port - * covering the entire VLAN ID range (0..4094). The vlanSet parameter is a 4096 - * bit array, each bit indicating the Egress behavior for the corresponding VLAN ID. - * If a bit is set then outgoing frames with the corresponding VLAN ID will be transmitted - * with the VLAN tag, otherwise the frame will be transmitted without the VLAN tag. - * - * Bit 0 has a special significance, indicating tagging or tag removal for priority-tagged - * frames. - * - * Bit 4095 is reserved and should never be set (it will be ignored if set). - * - * - Reentrant - no - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - ID of the port whose Egress VLAN tagging behavior is set - * @param vlanSet @ref IxEthDBVlanSet [in] - 4096 bit array controlling per-VLAN tagging and untagging - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid vlanSet pointer - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - * @retval IX_FAIL unknown OS or NPE communication error - * - * @warning This function will automatically add the default port VLAN ID to the Egress tagging table - * every time it is called. The user should manually call ixEthDBEgressVlanEntryTaggingEnabledSet to - * prevent tagging on the default port VLAN ID if the default behavior is not intended. - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBEgressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBEgressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet) - * - * @brief Retrieves the complete Egress VLAN tagging table from a port - * - * This function copies the 4096 bit table controlling the Egress VLAN tagging into a user specified - * area. Each bit in the array indicates whether tagging for the corresponding VLAN (the bit position - * in the array) is enabled (the bit is set) or not (the bit is unset). - * - * Bit 4095 is reserved and should not be set (it will be ignored if set). - * - * @see ixEthDBEgressVlanTaggingEnabledSet - * - * @param portID @ref IxEthDBPortId [in] - ID of the port whose Egress VLAN tagging behavior is retrieved - * @param vlanSet @ref IxEthDBVlanSet [out] - user location to copy the Egress tagging table into; should have - * room to store 4096 bits (512 bytes) - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid vlanSet pointer - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBEgressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBIngressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBTaggingAction taggingAction) - * - * @brief Sets the Ingress VLAN tagging behavior for a port - * - * A port's Ingress tagging behavior is controlled by the taggingAction parameter, - * which can take one of the following values: - * - * - IX_ETH_DB_PASS_THROUGH - leaves the frame unchanged (does not add or remove the VLAN tag) - * - IX_ETH_DB_ADD_TAG - adds the VLAN tag if not present, using the default port VID - * - IX_ETH_DB_REMOVE_TAG - removes the VLAN tag if present - * - * @param portID @ref IxEthDBPortId [in] - ID of the port whose Ingress VLAN tagging behavior is set - * @param taggingAction @ref IxEthDBTaggingAction [in] - tagging behavior for the port - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid taggingAction argument - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - * @retval IX_FAIL unknown OS or NPE communication error - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBIngressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBTaggingAction taggingAction); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBIngressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBTaggingAction *taggingAction) - * - * @brief Retrieves the Ingress VLAN tagging behavior from a port (see @ref ixEthDBIngressVlanTaggingEnabledSet) - * - * @param portID @ref IxEthDBPortId [in] - ID of the port whose Ingress VLAN tagging behavior is set - * @param taggingAction @ref IxEthDBTaggingAction [out] - location where the tagging behavior for the port is written to - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid taggingAction pointer argument - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBIngressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBTaggingAction *taggingAction); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBVlanPortExtractionEnable(IxEthDBPortId portID, BOOL enable) - * - * @brief Enables or disables port ID extraction - * - * This feature can be used in the situation when a multi-port device (e.g. a switch) - * is connected to an IXP4xx port and the device can provide incoming frame port - * identification by tagging the TPID field in the Ethernet frame. Enabling - * port extraction will instruct the NPE to copy the TPID field from the frame and - * place it in the ixp_ne_src_port of the ixp_buf header. In addition, - * the NPE restores the TPID field to 0. - * - * If the frame is not tagged the NPE will fill the ixp_ne_src_port with the - * port ID of the MII interface the frame was received from. - * - * The TPID field is the least significant byte of the type/length field, which is - * normally set to 0x8100 for 802.1Q-tagged frames. - * - * This feature is disabled by default. - * - * @param portID ID of the port to configure port ID extraction on - * @param enable TRUE to enable port ID extraction and FALSE to disable it - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - * @retval IX_FAIL unknown OS or NPE communication error - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBVlanPortExtractionEnable(IxEthDBPortId portID, BOOL enable); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFeatureCapabilityGet(IxEthDBPortId portID, IxEthDBFeature *featureSet) - * - * @brief Retrieves the feature capability set for a port - * - * This function retrieves the feature capability set for a port or the common capabilities shared between all - * the ports, writing the feature capability set in a user specified location. - * - * The feature capability set will consist of a set formed by OR-ing one or more of the following values: - * - IX_ETH_DB_LEARNING - Learning feature; enables EthDB to learn MAC address (filtering) records, including 802.1Q enabled records - * - IX_ETH_DB_FILTERING - Filtering feature; enables EthDB to communicate with the NPEs for downloading filtering information in the NPEs; depends on the learning feature - * - IX_ETH_DB_VLAN_QOS - VLAN/QoS feature; enables EthDB to configure NPEs to operate in VLAN/QoS aware modes - * - IX_ETH_DB_FIREWALL - Firewall feature; enables EthDB to configure NPEs to operate in firewall mode, using white/black address lists - * - IX_ETH_DB_SPANNING_TREE_PROTOCOL - Spanning tree protocol feature; enables EthDB to configure the NPEs as STP nodes - * - IX_ETH_DB_WIFI_HEADER_CONVERSION - WiFi 802.3 to 802.11 header conversion feature; enables EthDB to handle WiFi conversion data - * - * Note that EthDB provides only the LEARNING feature for non-NPE ports. - * - * @param portID @ref IxEthDBPortId [in] - ID of the port to retrieve the capability set for - * (use IX_ETH_DB_ALL_PORTS to retrieve the common capabilities shared between all the ports) - * @param featureSet @ref IxEthDBFeature [out] - location where the capability set will be written to - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid featureSet pointer - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFeatureCapabilityGet(IxEthDBPortId portID, IxEthDBFeature *featureSet); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFeatureEnable(IxEthDBPortId portID, IxEthDBFeature feature, BOOL enabled) - * - * @brief Enables or disables one or more EthDB features - * - * Selects one or more features (see @ref ixEthDBFeatureCapabilityGet for a description of the supported - * features) to be enabled or disabled on the selected port (or all the ports). - * - * Note that some features are mutually incompatible: - * - IX_ETH_DB_FILTERING is incompatible with IX_ETH_DB_WIFI_HEADER_CONVERSION - * - * Also note that some features require other features to be enabled: - * - IX_ETH_DB_FILTERING requires IX_ETH_DB_LEARNING - * - * This function will either enable the entire selected feature set for the selected port (or all the ports), - * in which case it will return IX_ETH_DB_SUCCESS, or in case of error it will not enable any feature at all - * and return an appropriate error message. - * - * The following features are enabled by default (for ports with the respective capability), - * for compatibility reasons with previous versions of CSR: - * - IX_ETH_DB_LEARNING - * - IX_ETH_DB_FILTERING - * - * All other features are disabled by default and require manual enabling using ixEthDBFeatureEnable. - * - * Default settings for VLAN, QoS, Firewall and WiFi header conversion features: - * - * VLAN - * - * When the VLAN/QoS feature is enabled for a port for the first time the default VLAN behavior - * of the port is set to be as permissive (it will accept all the frames) and - * non-interferential (it will not change any frames) as possible: - * - the port VLAN ID (VID) is set to 0 - * - the Ingress acceptable frame filter is set to accept all frames - * - the VLAN port membership is set to the complete VLAN range (0 - 4094) - * - the Ingress tagging mode is set to pass-through (will not change frames) - * - the Egress tagging mode is to send tagged frames in the entire VLAN range (0 - 4094) - * - * Note that further disabling and re-enabling the VLAN feature for a given port will not reset the port VLAN behavior - * to the settings listed above. Any VLAN settings made by the user are kept. - * - * QoS - * - * The following default priority mapping table will be used (as per IEEE 802.1Q and IEEE 802.1D): - * - * - *
QoS traffic classes
QoS priority Default traffic class Traffic type - *
0 1 Best effort, default class for unexpedited traffic - *
1 0 Background traffic - *
2 0 Spare bandwidth - *
3 1 Excellent effort - *
4 2 Controlled load - *
5 2 Video traffic - *
6 3 Voice traffic - *
7 3 Network control - *
- * - * Firewall - * - * The port firewall is configured by default in black-list mode, and the firewall address table is empty. - * This means the firewall will not filter any frames until the feature is configured and the firewall table is - * downloaded to the NPE. - * - * Spanning Tree - * - * The port is set to STP unblocked mode, therefore it will accept all frames until re-configured. - * - * WiFi header conversion - * - * The WiFi header conversion database is empty, therefore no actual header conversion will take place until this - * feature is configured and the conversion table downloaded to the NPE. - * - * @param portID @ref IxEthDBPortId [in] - ID of the port to enable or disable the features on (use IX_ETH_DB_ALL_PORTS for all the ports) - * @param feature @ref IxEthDBFeature [in] - feature or feature set to enable or disable - * @param enabled BOOL [in] - TRUE to enable the feature and FALSE to disable it - * - * @note Certain features, from a functional point of view, cannot be disabled as such at NPE level; - * when such features are set to disabled using the EthDB API they will be configured in such - * a way to determine a behavior equivalent to the feature being disabled. As well as this, disabled - * features cannot be configured or accessed via the EthDB API (except for getting their status). - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_NO_PERMISSION attempted to enable mutually exclusive features, - * or a feature that depends on another feature which is not present or enabled - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE at least one of the features selected is unavailable - * @retval IX_FAIL unknown OS or NPE communication error - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFeatureEnable(IxEthDBPortId portID, IxEthDBFeature feature, BOOL enabled); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFeatureStatusGet(IxEthDBPortId portID, IxEthDBFeature feature, BOOL *present, BOOL *enabled) - * - * @brief Retrieves the availability and status of a feature set - * - * This function returns the availability and status for a feature set. - * Note that if more than one feature is selected (e.g. IX_ETH_DB_LEARNING | IX_ETH_DB_FILTERING) - * the "present" and "enabled" return values will be set to TRUE only if all the features in the - * feature set are present and enabled (not only some). - * - * @param portID @ref IxEthDBPortId [in] - ID of the port - * @param feature @ref IxEthDBFeature [in] - identifier of the feature to retrieve the status for - * @param present BOOL [out] - location where a boolean flag indicating whether this feature is present will be written to - * @param enabled BOOL [out] - location where a boolean flag indicating whether this feature is enabled will be written to - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG either present or enabled pointer argument is invalid - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFeatureStatusGet(IxEthDBPortId portID, IxEthDBFeature feature, BOOL *present, BOOL *enabled); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFeaturePropertyGet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, IxEthDBPropertyType *type, void *value) - * - * @brief Retrieves the value of a feature property - * - * The EthDB features usually contain feature-specific properties describing or - * controlling how the feature operates. While essential properties (e.g. the - * firewall operating mode) have their own API, secondary properties can be - * retrieved using this function. - * - * Properties can be read-only or read-write. ixEthDBFeaturePropertyGet operates with - * both types of features. - * - * Properties have types associated with them. A descriptor indicating the property - * type is returned in the type argument for convenience. - * - * The currently supported properties and their corresponding features are as follows: - * - * - *
Properties for IX_ETH_DB_VLAN_QOS
Property identifier Property type Property value Read-Only - *
IX_ETH_DB_QOS_TRAFFIC_CLASS_COUNT_PROPERTY IX_ETH_DB_INTEGER_PROPERTY number of internal traffic classes Yes - *
IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY IX_ETH_DB_INTEGER_PROPERTY queue assignment for traffic class 0 Yes - *
IX_ETH_DB_QOS_TRAFFIC_CLASS_1_RX_QUEUE_PROPERTY IX_ETH_DB_INTEGER_PROPERTY queue assignment for traffic class 1 Yes - *
IX_ETH_DB_QOS_TRAFFIC_CLASS_2_RX_QUEUE_PROPERTY IX_ETH_DB_INTEGER_PROPERTY queue assignment for traffic class 2 Yes - *
IX_ETH_DB_QOS_TRAFFIC_CLASS_3_RX_QUEUE_PROPERTY IX_ETH_DB_INTEGER_PROPERTY queue assignment for traffic class 3 Yes - *
IX_ETH_DB_QOS_TRAFFIC_CLASS_4_RX_QUEUE_PROPERTY IX_ETH_DB_INTEGER_PROPERTY queue assignment for traffic class 4 Yes - *
IX_ETH_DB_QOS_TRAFFIC_CLASS_5_RX_QUEUE_PROPERTY IX_ETH_DB_INTEGER_PROPERTY queue assignment for traffic class 5 Yes - *
IX_ETH_DB_QOS_TRAFFIC_CLASS_6_RX_QUEUE_PROPERTY IX_ETH_DB_INTEGER_PROPERTY queue assignment for traffic class 6 Yes - *
IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY IX_ETH_DB_INTEGER_PROPERTY queue assignment for traffic class 7 Yes - *
- * - * @see ixEthDBFeaturePropertySet - * - * @param portID @ref IxEthDBPortId [in] - ID of the port - * @param feature @ref IxEthDBFeature [in] - EthDB feature for which the property is retrieved - * @param property @ref IxEthDBProperty [in] - property identifier - * @param type @ref IxEthDBPropertyType [out] - location where the property type will be stored - * @param value void [out] - location where the property value will be stored - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_INVALID_ARG invalid property identifier, type or value pointer arguments - * @retval IX_ETH_DB_FAIL incorrect property value or unknown error - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFeaturePropertyGet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, IxEthDBPropertyType *type, void *value); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFeaturePropertySet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, void *value) - * - * @brief Sets the value of a feature property - * - * Unlike @ref ixEthDBFeaturePropertyGet, this function operates only with read-write properties - * - * The currently supported properties and their corresponding features are as follows: - * - * - IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE (for IX_ETH_DB_VLAN_QOS): freezes the availability of traffic classes - * to the number of traffic classes currently in use - * - * Note that this function creates deep copies of the property values; once the function is invoked the client - * can free or reuse the memory area containing the original property value. - * - * Copy behavior for different property types is defined as follows: - * - * - IX_ETH_DB_INTEGER_PROPERTY - 4 bytes are copied from the source location - * - IX_ETH_DB_STRING_PROPERTY - the source string will be copied up to the NULL '\0' string terminator, maximum of 255 characters - * - IX_ETH_DB_MAC_ADDR_PROPERTY - 6 bytes are copied from the source location - * - IX_ETH_DB_BOOL_PROPERTY - 4 bytes are copied from the source location; the only allowed values are TRUE (1L) and false (0L) - * - * @see ixEthDBFeaturePropertySet - * - * @warning IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE is provided for EthAcc internal use; - * do not attempt to set this property directly - * - * @param portID @ref IxEthDBPortId [in] - ID of the port - * @param feature @ref IxEthDBFeature [in] - EthDB feature for which the property is set - * @param property @ref IxEthDBProperty [in] - property identifier - * @param value void [in] - location where the property value is to be copied from - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_INVALID_ARG invalid property identifier, value pointer, or invalid property value - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFeaturePropertySet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, void *value); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBDatabaseClear(IxEthDBPortId portID, IxEthDBRecordType recordType) - * - * @brief Deletes a set of record types from the Ethernet Database - * - * This function deletes all the records of certain types (specified in the recordType filter) - * associated with a port. Additionally, the IX_ETH_DB_ALL_PORTS value can be used as port ID - * to indicate that the specified record types should be deleted for all the ports. - * - * The record type filter can be an ORed combination of the following types: - * - * Record types - * - IX_ETH_DB_FILTERING_RECORD - * - *
Filtering record
MAC address static/dynamic type age
- * - * - IX_ETH_DB_FILTERING_VLAN_RECORD - * - *
VLAN-enabled filtering record
MAC address static/dynamic type age 802.1Q tag
- * - * - IX_ETH_DB_WIFI_RECORD - * - *
WiFi header conversion record
MAC address optional gateway MAC address
- * - * - IX_ETH_DB_FIREWALL_RECORD - * - *
Firewall record
MAC address
- * - IX_ETH_DB_ALL_RECORD_TYPES - * - * Any combination of the above types is valid e.g. - * - * (IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD | IX_ETH_DB_FIREWALL_RECORD), - * - * although some might be redundant (it is not an error to do so) e.g. - * - * (IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_ALL_RECORD_TYPES) - * - * @param portID @ref IxEthDBPortId [in] - ID of the port - * @param recordType @ref IxEthDBRecordType [in] - record type filter - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_INVALID_ARG invalid recordType filter - * - * @note If the record type filter contains any unrecognized value (hence the - * IX_ETH_DB_INVALID_ARG error value is returned) no actual records will be deleted. - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBDatabaseClear(IxEthDBPortId portID, IxEthDBRecordType recordType); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBWiFiStationEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) - * - * @brief Adds an "Access Point to Station" record to the database, for 802.3 => 802.11 frame - * header conversion - * - * Frame header conversion is controlled by the set of MAC addresses - * added using @ref ixEthDBWiFiStationEntryAdd and @ref ixEthDBWiFiAccessPointEntryAdd. - * Conversion arguments are added using @ref ixEthDBWiFiFrameControlSet, - * @ref ixEthDBWiFiDurationIDSet and @ref ixEthDBWiFiBBSIDSet. - * - * Note that adding the same MAC address twice will not return an error - * (but will not accomplish anything either), while re-adding a record previously added - * as an "Access Point to Access Point" will migrate the record to the "Access Point - * to Station" type. - * - * @param portID @ref IxEthDBPortId [in] - ID of the port - * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to add - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_INVALID_ARG macAddr is an invalid pointer - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled - * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument - * @retval IX_ETH_DB_NOMEM maximum number of records reached - * @retval IX_ETH_DB_BUSY lock condition or transaction in progress, try again later - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBWiFiStationEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBWiFiAccessPointEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr, IxEthDBMacAddr *gatewayMacAddr) - * - * @brief Adds an "Access Point to Access Point" record to the database - * - * @see ixEthDBWiFiStationEntryAdd - * - * Note that adding the same MAC address twice will simply overwrite the previously - * defined gateway MAC address value in the same record, if the record was previously of the - * "Access Point to Access Point" type. - * - * Re-adding a MAC address as "Access Point to Access Point", which was previously added as - * "Access Point to Station" will migrate the record type to "Access Point to Access Point" and - * record the gateway MAC address. - * - * @param portID @ref IxEthDBPortId [in] - ID of the port - * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to add - * @param gatewayMacAddr @ref IxEthDBMacAddr [in] - MAC address of the gateway Access Point - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG macAddr is an invalid pointer - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled - * @retval IX_ETH_DB_INVALID_ARG invalid macAddr or gatewayMacAddr pointer argument - * @retval IX_ETH_DB_NOMEM maximum number of records reached - * @retval IX_ETH_DB_BUSY lock condition or transaction in progress, try again later - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBWiFiAccessPointEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr, IxEthDBMacAddr *gatewayMacAddr); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBWiFiEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) - * - * @brief Removes a WiFi station record - * - * This function removes both types of WiFi records ("Access Point to Station" and - * "Access Point to Access Point"). - * - * @param portID @ref IxEthDBPortId [in] - ID of the port - * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to remove - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument - * @retval IX_ETH_DB_NO_SUCH_ADDR specified address was not found in the database - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled - * @retval IX_ETH_DB_BUSY lock condition or transaction in progress, try again later - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBWiFiEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBWiFiConversionTableDownload(IxEthDBPortId portID) - * - * @brief Downloads the MAC address table for 802.3 => 802.11 frame header - * conversion to the NPE - * - * Note that the frame conversion MAC address table must be individually downloaded - * to each NPE for which the frame header conversion feature is enabled (i.e. it - * is not possible to specify IX_ETH_DB_ALL_PORTS). - * - * @param portID @ref IxEthDBPortId [in] - ID of the port - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled - * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBWiFiConversionTableDownload(IxEthDBPortId portID); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBWiFiFrameControlSet(IxEthDBPortId portID, UINT16 frameControl) - * - * @brief Sets the GlobalFrameControl field - * - * The GlobalFrameControl field is a 2-byte value inserted in the Frame Control - * field for all 802.3 to 802.11 frame header conversions - * - * @param portID @ref IxEthDBPortId [in] - ID of the port - * @param frameControl UINT16 [in] - GlobalFrameControl value - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled - * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBWiFiFrameControlSet(IxEthDBPortId portID, UINT16 frameControl); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBWiFiDurationIDSet(IxEthDBPortId portID, UINT16 durationID) - * - * @brief Sets the GlobalDurationID field - * - * The GlobalDurationID field is a 2-byte value inserted in the Duration/ID - * field for all 802.3 to 802.11 frame header conversions - * - * @param portID @ref IxEthDBPortId [in] - ID of the port - * @param durationID UINT16 [in] - GlobalDurationID field - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled - * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBWiFiDurationIDSet(IxEthDBPortId portID, UINT16 durationID); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBWiFiBBSIDSet(IxEthDBPortId portID, IxEthDBMacAddr *bbsid) - * - * @brief Sets the BBSID field - * - * The BBSID field is a 6-byte value which - * identifies the infrastructure of the service set managed - * by the Access Point having the IXP400 as its processor. The value - * is written in the BBSID field of the 802.11 frame header. - * The BBSID value is the MAC address of the Access Point. - * - * @param portID @ref IxEthDBPortId [in] - ID of the port - * @param bbsid @ref IxEthDBMacAddr [in] - pointer to 6 bytes containing the BSSID - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid bbsid pointer argument - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled - * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBWiFiBBSIDSet(IxEthDBPortId portID, IxEthDBMacAddr *bbsid); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBSpanningTreeBlockingStateSet(IxEthDBPortId portID, BOOL blocked) - * - * @brief Sets the STP blocked/unblocked state for a port - * - * @param portID @ref IxEthDBPortId [in] - ID of the port - * @param blocked BOOL [in] - TRUE to set the port as STP blocked, FALSE to set it as unblocked - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Spanning Tree Protocol feature not enabled - * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBSpanningTreeBlockingStateSet(IxEthDBPortId portID, BOOL blocked); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBSpanningTreeBlockingStateGet(IxEthDBPortId portID, BOOL *blocked) - * - * @brief Retrieves the STP blocked/unblocked state for a port - * - * @param portID @ref IxEthDBPortId [in] - ID of the port - * @param blocked BOOL * [in] - set to TRUE if the port is STP blocked, FALSE otherwise - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid blocked pointer argument - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Spanning Tree Protocol feature not enabled - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBSpanningTreeBlockingStateGet(IxEthDBPortId portID, BOOL *blocked); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFirewallModeSet(IxEthDBPortId portID, IxEthDBFirewallMode mode) - * - * @brief Sets the firewall mode to use white or black listing - * - * When enabled, the NPE MAC address based firewall support operates in two modes: - * - * - white-list mode (MAC address based admission) - * - mode set to IX_ETH_DB_FIREWALL_WHITE_LIST - * - only packets originating from MAC addresses contained in the firewall address list - * are allowed on the Rx path - * - black-list mode (MAC address based blocking) - * - mode set to IX_ETH_DB_FIREWALL_BLACK_LIST - * - packets originating from MAC addresses contained in the firewall address list - * are discarded - * - * @param portID @ref IxEthDBPortId [in] - ID of the port - * @param mode @ref IxEthDBFirewallMode [in] - firewall mode (IX_ETH_DB_FIREWALL_WHITE_LIST or IX_ETH_DB_FIREWALL_BLACK_LIST) - * - * @note by default the firewall operates in black-list mode with an empty address - * list, hence it doesn't filter any packets - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Firewall feature not enabled - * @retval IX_ETH_DB_INVALID_ARGUMENT mode argument is not a valid firewall configuration mode - * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error -*/ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFirewallModeSet(IxEthDBPortId portID, IxEthDBFirewallMode mode); - -/** - * @ingroup IxEthDB - * - * @fn ixEthDBFirewallInvalidAddressFilterEnable(IxEthDBPortId portID, BOOL enable) - * - * @brief Enables or disables invalid MAC address filtering - * - * According to IEEE802 it is illegal for a source address to be a multicast - * or broadcast address. If this feature is enabled the NPE inspects the source - * MAC addresses of incoming frames and discards them if invalid addresses are - * detected. - * - * By default this service is enabled, if the firewall feature is supported by the - * NPE image. - * - * @param portID ID of the port - * @param enable TRUE to enable invalid MAC address filtering and FALSE to disable it - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Firewall feature not enabled - * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFirewallInvalidAddressFilterEnable(IxEthDBPortId portID, BOOL enable); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFirewallEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) - * - * @brief Adds a MAC address to the firewall address list - * - * Note that adding the same MAC address twice will not return an error - * but will not actually accomplish anything. - * - * The firewall MAC address list has a limited number of entries; once - * the maximum number of entries has been reached this function will failed - * to add more addresses, returning IX_ETH_DB_NOMEM. - * - * @param portID @ref IxEthDBPortId [in] - ID of the port - * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to be added - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument - * @retval IX_ETH_DB_NOMEM maximum number of records reached - * @retval IX_ETH_DB_BUSY lock condition or transaction in progress, try again later - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Firewall feature not enabled - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFirewallEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFirewallEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) - * - * @brief Removes a MAC address from the firewall address list - * - * @param portID @ref IxEthDBPortId [in] - ID of the port - * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to be removed - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument - * @retval IX_ETH_DB_NO_SUCH_ADDR address not found - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Firewall feature not enabled - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFirewallEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFirewallTableDownload(IxEthDBPortId portID) - * - * @brief Downloads the MAC firewall table to a port - * - * @param portID ID of the port - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Firewall feature not enabled - * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFirewallTableDownload(IxEthDBPortId portID); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBUserFieldSet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void *field) - * - * @brief Adds a user-defined field to a database record - * - * This function associates a user-defined field to a database record. - * The user-defined field is passed as a (void *) parameter, hence it can be used - * for any purpose (such as identifying a structure). Retrieving the user-defined field from - * a record is done using @ref ixEthDBUserFieldGet. Note that EthDB never uses the user-defined - * field for any internal operation and it is not aware of the significance of its contents. The - * field is only stored as a pointer. - * - * The database record is identified using a combination of the given parameters, depending on the record type. - * All the record types require the record MAC address. - * - * - IX_ETH_DB_FILTERING_RECORD requires only the MAC address - * - IX_ETH_DB_VLAN_FILTERING_RECORD requires the MAC address and the VLAN ID - * - IX_ETH_DB_WIFI_RECORD requires the MAC address and the portID - * - IX_ETH_DB_FIREWALL_RECORD requires the MAC address and the portID - * - * Please note that if a parameter is not required it is completely ignored (it does not undergo parameter checking). - * The user-defined field can be cleared using a NULL field parameter. - * - * @param recordType @ref IxEthDBRecordType [in] - type of record (can be IX_ETH_DB_FILTERING_RECORD, - * IX_ETH_DB_FILTERING_VLAN_RECORD, IX_ETH_DB_WIFI_RECORD or IX_ETH_DB_FIREWALL_RECORD) - * @param portID @ref IxEthDBPortId [in] - ID of the port (required only for WIFI and FIREWALL records) - * @param macAddr @ref IxEthDBMacAddr * [in] - MAC address of the record - * @param vlanID @ref IxEthDBVlanId [in] - VLAN ID of the record (required only for FILTERING_VLAN records) - * @param field void * [in] - user defined field - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID was required but it is not a valid port identifier - * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument - * @retval IX_ETH_DB_NO_SUCH_ADDR record not found - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBUserFieldSet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void *field); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBUserFieldGet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void **field) - * - * @brief Retrieves a user-defined field from a database record - * - * The database record is identified using a combination of the given parameters, depending on the record type. - * All the record types require the record MAC address. - * - * - IX_ETH_DB_FILTERING_RECORD requires only the MAC address - * - IX_ETH_DB_VLAN_FILTERING_RECORD requires the MAC address and the VLAN ID - * - IX_ETH_DB_WIFI_RECORD requires the MAC address and the portID - * - IX_ETH_DB_FIREWALL_RECORD requires the MAC address and the portID - * - * Please note that if a parameter is not required it is completely ignored (it does not undergo parameter checking). - * - * If no user-defined field was registered with the specified record then NULL will be written - * at the location specified by field. - * - * @param recordType type of record (can be IX_ETH_DB_FILTERING_RECORD, IX_ETH_DB_FILTERING_VLAN_RECORD, IX_ETH_DB_WIFI_RECORD - * or IX_ETH_DB_FIREWALL_RECORD) - * @param portID ID of the port (required only for WIFI and FIREWALL records) - * @param macAddr MAC address of the record - * @param vlanID VLAN ID of the record (required only for FILTERING_VLAN records) - * @param field location to write the user defined field into - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID was required but it is not a valid port identifier - * @retval IX_ETH_DB_INVALID_ARG invalid macAddr or field pointer arguments - * @retval IX_ETH_DB_NO_SUCH_ADDR record not found - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBUserFieldGet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portId, IxEthDBVlanId vlanID, void **field); - -/** - * @} - */ - -#endif /* IxEthDB_H */ diff --git a/cpu/ixp/npe/include/IxEthDBLocks_p.h b/cpu/ixp/npe/include/IxEthDBLocks_p.h deleted file mode 100644 index 1d8b24fdf6..0000000000 --- a/cpu/ixp/npe/include/IxEthDBLocks_p.h +++ /dev/null @@ -1,122 +0,0 @@ -/** - * @file IxEthAccDBLocks_p.h - * - * @brief Definition of transaction lock stacks and lock utility macros - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#ifndef IxEthAccDBLocks_p_H -#define IxEthAccDBLocks_p_H - -#include "IxOsPrintf.h" - -/* Lock and lock stacks */ -typedef struct -{ - IxOsalFastMutex* locks[MAX_LOCKS]; - UINT32 stackPointer, basePointer; -} LockStack; - -#define TRY_LOCK(mutex) \ - { \ - if (ixOsalFastMutexTryLock(mutex) != IX_SUCCESS) \ - { \ - return IX_ETH_DB_BUSY; \ - } \ - } - - -#define UNLOCK(mutex) { ixOsalFastMutexUnlock(mutex); } - -#define INIT_STACK(stack) \ - { \ - (stack)->basePointer = 0; \ - (stack)->stackPointer = 0; \ - } - -#define PUSH_LOCK(stack, lock) \ - { \ - if ((stack)->stackPointer == MAX_LOCKS) \ - { \ - ERROR_LOG("Ethernet DB: maximum number of elements in a lock stack has been exceeded on push, heavy chaining?\n"); \ - UNROLL_STACK(stack); \ - \ - return IX_ETH_DB_NOMEM; \ - } \ - \ - if (ixOsalFastMutexTryLock(lock) == IX_SUCCESS) \ - { \ - (stack)->locks[(stack)->stackPointer++] = (lock); \ - } \ - else \ - { \ - UNROLL_STACK(stack); \ - \ - return IX_ETH_DB_BUSY; \ - } \ - } - -#define POP_LOCK(stack) \ - { \ - ixOsalFastMutexUnlock((stack)->locks[--(stack)->stackPointer]); \ - } - -#define UNROLL_STACK(stack) \ - { \ - while ((stack)->stackPointer > (stack)->basePointer) \ - { \ - POP_LOCK(stack); \ - } \ - } - -#define SHIFT_STACK(stack) \ - { \ - if ((stack)->basePointer == MAX_LOCKS - 1) \ - { \ - ERROR_LOG("Ethernet DB: maximum number of elements in a lock stack has been exceeded on shift, heavy chaining?\n"); \ - UNROLL_STACK(stack); \ - \ - return IX_ETH_DB_BUSY; \ - } \ - \ - ixOsalFastMutexUnlock((stack)->locks[(stack)->basePointer++]); \ - } - -#endif /* IxEthAccDBLocks_p_H */ diff --git a/cpu/ixp/npe/include/IxEthDBLog_p.h b/cpu/ixp/npe/include/IxEthDBLog_p.h deleted file mode 100644 index 1d6b0bb20d..0000000000 --- a/cpu/ixp/npe/include/IxEthDBLog_p.h +++ /dev/null @@ -1,227 +0,0 @@ -/** - * @file IxEthDBLog_p.h - * - * @brief definitions of log macros and log configuration - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#include - -#ifdef IX_UNIT_TEST -#define NULL_PRINT_ROUTINE(format, arg...) /* nothing */ -#else -#define NULL_PRINT_ROUTINE if(0) printf -#endif - -/*************************************************** - * Globals * - ***************************************************/ -/* safe to permanently leave these on */ -#define HAS_ERROR_LOG -#define HAS_ERROR_IRQ_LOG -#define HAS_WARNING_LOG - -/*************************************************** - * Log Configuration * - ***************************************************/ - -/* debug output can be turned on unless specifically - declared as a non-debug build */ -#ifndef NDEBUG - -#undef HAS_EVENTS_TRACE -#undef HAS_EVENTS_VERBOSE_TRACE - -#undef HAS_SUPPORT_TRACE -#undef HAS_SUPPORT_VERBOSE_TRACE - -#undef HAS_NPE_TRACE -#undef HAS_NPE_VERBOSE_TRACE -#undef HAS_DUMP_NPE_TREE - -#undef HAS_UPDATE_TRACE -#undef HAS_UPDATE_VERBOSE_TRACE - -#endif /* NDEBUG */ - - -/*************************************************** - * Log Macros * - ***************************************************/ - -/************** Globals ******************/ - -#ifdef HAS_ERROR_LOG - - #define ERROR_LOG printf - -#else - - #define ERROR_LOG NULL_PRINT_ROUTINE - -#endif - -#ifdef HAS_ERROR_IRQ_LOG - - #define ERROR_IRQ_LOG(format, arg1, arg2, arg3, arg4, arg5, arg6) ixOsalLog(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, format, arg1, arg2, arg3, arg4, arg5, arg6) - -#else - - #define ERROR_IRQ_LOG(format, arg1, arg2, arg3, arg4, arg5, arg6) /* nothing */ - -#endif - -#ifdef HAS_WARNING_LOG - - #define WARNING_LOG printf - -#else - - #define WARNING_LOG NULL_PRINT_ROUTINE - -#endif - -/************** Events *******************/ - -#ifdef HAS_EVENTS_TRACE - - #define IX_ETH_DB_EVENTS_TRACE printf - #define IX_ETH_DB_IRQ_EVENTS_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, format, arg1, arg2, arg3, arg4, arg5, arg6) - - #ifdef HAS_EVENTS_VERBOSE_TRACE - - #define IX_ETH_DB_EVENTS_VERBOSE_TRACE printf - - #else - - #define IX_ETH_DB_EVENTS_VERBOSE_TRACE NULL_PRINT_ROUTINE - - #endif /* HAS_EVENTS_VERBOSE_TRACE */ - -#else - - #define IX_ETH_DB_EVENTS_TRACE NULL_PRINT_ROUTINE - #define IX_ETH_DB_EVENTS_VERBOSE_TRACE NULL_PRINT_ROUTINE - #define IX_ETH_DB_IRQ_EVENTS_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) /* nothing */ - -#endif /* HAS_EVENTS_TRACE */ - -/************** Support *******************/ - -#ifdef HAS_SUPPORT_TRACE - - #define IX_ETH_DB_SUPPORT_TRACE printf - #define IX_ETH_DB_SUPPORT_IRQ_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, format, arg1, arg2, arg3, arg4, arg5, arg6) - - #ifdef HAS_SUPPORT_VERBOSE_TRACE - - #define IX_ETH_DB_SUPPORT_VERBOSE_TRACE printf - - #else - - #define IX_ETH_DB_SUPPORT_VERBOSE_TRACE NULL_PRINT_ROUTINE - - #endif /* HAS_SUPPORT_VERBOSE_TRACE */ - -#else - - #define IX_ETH_DB_SUPPORT_TRACE NULL_PRINT_ROUTINE - #define IX_ETH_DB_SUPPORT_VERBOSE_TRACE NULL_PRINT_ROUTINE - #define IX_ETH_DB_SUPPORT_IRQ_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) /* nothing */ - -#endif /* HAS_SUPPORT_TRACE */ - -/************** NPE Adaptor *******************/ - -#ifdef HAS_NPE_TRACE - - #define IX_ETH_DB_NPE_TRACE printf - #define IX_ETH_DB_NPE_IRQ_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, format, arg1, arg2, arg3, arg4, arg5, arg6) - - #ifdef HAS_NPE_VERBOSE_TRACE - - #define IX_ETH_DB_NPE_VERBOSE_TRACE printf - - #else - - #define IX_ETH_DB_NPE_VERBOSE_TRACE NULL_PRINT_ROUTINE - - #endif /* HAS_NPE_VERBOSE_TRACE */ - -#else - - #define IX_ETH_DB_NPE_TRACE NULL_PRINT_ROUTINE - #define IX_ETH_DB_NPE_VERBOSE_TRACE NULL_PRINT_ROUTINE - #define IX_ETH_DB_NPE_IRQ_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) /* nothing */ - -#endif /* HAS_NPE_TRACE */ - -#ifdef HAS_DUMP_NPE_TREE - -#define IX_ETH_DB_NPE_DUMP_ELT(eltBaseAddress, eltSize) ixEthELTDumpTree(eltBaseAddress, eltSize) - -#else - -#define IX_ETH_DB_NPE_DUMP_ELT(eltBaseAddress, eltSize) /* nothing */ - -#endif /* HAS_DUMP_NPE_TREE */ - -/************** Port Update *******************/ - -#ifdef HAS_UPDATE_TRACE - - #define IX_ETH_DB_UPDATE_TRACE printf - - #ifdef HAS_UPDATE_VERBOSE_TRACE - - #define IX_ETH_DB_UPDATE_VERBOSE_TRACE printf - - #else - - #define IX_ETH_DB_UPDATE_VERBOSE_TRACE NULL_PRINT_ROUTINE - - #endif - -#else /* HAS_UPDATE_VERBOSE_TRACE */ - - #define IX_ETH_DB_UPDATE_TRACE NULL_PRINT_ROUTINE - #define IX_ETH_DB_UPDATE_VERBOSE_TRACE NULL_PRINT_ROUTINE - -#endif /* HAS_UPDATE_TRACE */ diff --git a/cpu/ixp/npe/include/IxEthDBMessages_p.h b/cpu/ixp/npe/include/IxEthDBMessages_p.h deleted file mode 100644 index ff18160c1f..0000000000 --- a/cpu/ixp/npe/include/IxEthDBMessages_p.h +++ /dev/null @@ -1,258 +0,0 @@ -/** - * @file IxEthDBMessages_p.h - * - * @brief Definitions of NPE messages - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#ifndef IxEthDBMessages_p_H -#define IxEthDBMessages_p_H - -#include -#include -#include "IxEthDB_p.h" - -/* events watched by the Eth event processor */ -#define IX_ETH_DB_MIN_EVENT_ID (IX_ETHNPE_EDB_GETMACADDRESSDATABASE) -#define IX_ETH_DB_MAX_EVENT_ID (IX_ETHNPE_PC_SETAPMACTABLE) - -/* macros to fill and extract data from NPE messages - place any endian conversions here */ -#define RESET_ELT_MESSAGE(message) { memset((void *) &(message), 0, sizeof((message))); } -#define NPE_MSG_ID(msg) ((msg).data[0] >> 24) - -#define FILL_SETPORTVLANTABLEENTRY_MSG(message, portID, setOffset, vlanMembershipSet, ttiSet) \ - do { \ - message.data[0] = (IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY << 24) | (portID << 16) | (setOffset * 2); \ - message.data[1] = (vlanMembershipSet << 8) | ttiSet; \ - } while (0); - -#define FILL_SETPORTVLANTABLERANGE_MSG(message, portID, offset, length, zone) \ - do { \ - message.data[0] = IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE << 24 | portID << 16 | offset << 9 | length << 1; \ - message.data[1] = (UINT32) zone; \ - } while (0); - -#define FILL_SETDEFAULTRXVID_MSG(message, portID, tpid, vlanTag) \ - do { \ - message.data[0] = (IX_ETHNPE_VLAN_SETDEFAULTRXVID << 24) \ - | (portID << 16); \ - \ - message.data[1] = (tpid << 16) | vlanTag; \ - } while (0); - -#define FILL_SETRXTAGMODE_MSG(message, portID, filterMode, tagMode) \ - do { \ - message.data[0] = IX_ETHNPE_VLAN_SETRXTAGMODE << 24 \ - | portID << 16 \ - | filterMode << 2 \ - | tagMode; \ - \ - message.data[1] = 0; \ - } while (0); - -#define FILL_SETRXQOSENTRY(message, portID, classIndex, trafficClass, aqmQueue) \ - do { \ - message.data[0] = IX_ETHNPE_VLAN_SETRXQOSENTRY << 24 \ - | portID << 16 \ - | classIndex; \ - \ - message.data[1] = trafficClass << 24 \ - | 0x1 << 23 \ - | aqmQueue << 16 \ - | aqmQueue << 4; \ - } while (0); - -#define FILL_SETPORTIDEXTRACTIONMODE(message, portID, enable) \ - do { \ - message.data[0] = IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE << 24 \ - | portID << 16 \ - | (enable ? 0x1 : 0x0); \ - \ - message.data[1] = 0; \ - } while (0); - - -#define FILL_SETBLOCKINGSTATE_MSG(message, portID, blocked) \ - do { \ - message.data[0] = IX_ETHNPE_STP_SETBLOCKINGSTATE << 24 \ - | portID << 16 \ - | (blocked ? 0x1 : 0x0); \ - \ - message.data[1] = 0; \ - } while (0); - -#define FILL_SETBBSID_MSG(message, portID, bbsid) \ - do { \ - message.data[0] = IX_ETHNPE_PC_SETBBSID << 24 \ - | portID << 16 \ - | bbsid->macAddress[0] << 8 \ - | bbsid->macAddress[1]; \ - \ - message.data[1] = bbsid->macAddress[2] << 24 \ - | bbsid->macAddress[3] << 16 \ - | bbsid->macAddress[4] << 8 \ - | bbsid->macAddress[5]; \ - } while (0); - -#define FILL_SETFRAMECONTROLDURATIONID(message, portID, frameControlDurationID) \ - do { \ - message.data[0] = (IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID << 24) | (portID << 16); \ - message.data[1] = frameControlDurationID; \ - } while (0); - -#define FILL_SETAPMACTABLE_MSG(message, zone) \ - do { \ - message.data[0] = IX_ETHNPE_PC_SETAPMACTABLE << 24 \ - | 0 << 8 /* always use index 0 */ \ - | 64; /* 32 entries, 8 bytes each, 4 bytes in a word */ \ - message.data[1] = (UINT32) zone; \ - } while (0); - -#define FILL_SETFIREWALLMODE_MSG(message, portID, epDelta, mode, address) \ - do { \ - message.data[0] = IX_ETHNPE_FW_SETFIREWALLMODE << 24 \ - | portID << 16 \ - | (epDelta & 0xFF) << 8 \ - | mode; \ - \ - message.data[1] = (UINT32) address; \ - } while (0); - -#define FILL_SETMACADDRESSDATABASE_MSG(message, portID, epDelta, blockCount, address) \ - do { \ - message.data[0] = IX_ETHNPE_EDB_SETMACADDRESSSDATABASE << 24 \ - | (epDelta & 0xFF) << 8 \ - | (blockCount & 0xFF); \ - \ - message.data[1] = (UINT32) address; \ - } while (0); - -#define FILL_GETMACADDRESSDATABASE(message, npeId, zone) \ - do { \ - message.data[0] = IX_ETHNPE_EDB_GETMACADDRESSDATABASE << 24; \ - message.data[1] = (UINT32) zone; \ - } while (0); - -#define FILL_SETMAXFRAMELENGTHS_MSG(message, portID, maxRxFrameSize, maxTxFrameSize) \ - do { \ - message.data[0] = IX_ETHNPE_SETMAXFRAMELENGTHS << 24 \ - | portID << 16 \ - | ((maxRxFrameSize + 63) / 64) << 8 /* max Rx 64-byte blocks */ \ - | (maxTxFrameSize + 63) / 64; /* max Tx 64-byte blocks */ \ - \ - message.data[1] = maxRxFrameSize << 16 | maxTxFrameSize; \ - } while (0); - -#define FILL_SETPORTADDRESS_MSG(message, portID, macAddress) \ - do { \ - message.data[0] = IX_ETHNPE_EDB_SETPORTADDRESS << 24 \ - | portID << 16 \ - | macAddress[0] << 8 \ - | macAddress[1]; \ - \ - message.data[1] = macAddress[2] << 24 \ - | macAddress[3] << 16 \ - | macAddress[4] << 8 \ - | macAddress[5]; \ - } while (0); - -/* access to a MAC node in the NPE tree */ -#define NPE_NODE_BYTE(eltNodeAddr, offset) (((UINT8 *) (eltNodeAddr))[offset]) - -/* browsing of the implicit linear binary tree structure of the NPE tree */ -#define LEFT_CHILD_OFFSET(offset) ((offset) << 1) -#define RIGHT_CHILD_OFFSET(offset) (((offset) << 1) + 1) - -#define IX_EDB_FLAGS_ACTIVE (0x2) -#define IX_EDB_FLAGS_VALID (0x1) -#define IX_EDB_FLAGS_RESERVED (0xfc) -#define IX_EDB_FLAGS_INACTIVE_VALID (0x1) - -#define IX_EDB_NPE_NODE_ELT_PORT_ID_OFFSET (6) -#define IX_EDB_NPE_NODE_ELT_FLAGS_OFFSET (7) -#define IX_EDB_NPE_NODE_WIFI_INDEX_OFFSET (6) -#define IX_EDB_NPE_NODE_WIFI_FLAGS_OFFSET (7) -#define IX_EDB_NPE_NODE_FW_FLAGS_OFFSET (1) -#define IX_EDB_NPE_NODE_FW_RESERVED_OFFSET (6) -#define IX_EDB_NPE_NODE_FW_ADDR_OFFSET (2) - -#define IX_EDB_NPE_NODE_VALID(address) ((NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_FLAGS_OFFSET) & IX_EDB_FLAGS_VALID) != 0) -#define IX_EDB_NPE_NODE_ACTIVE(address) ((NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_FLAGS_OFFSET) & IX_EDB_FLAGS_ACTIVE) != 0) -#define IX_EDB_NPE_NODE_PORT_ID(address) (NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_PORT_ID_OFFSET)) - -/* macros to send messages to the NPEs */ -#define IX_ETHDB_ASYNC_SEND_NPE_MSG(npeId, msg, result) \ - do { \ - result = ixNpeMhMessageSend(npeId, msg, IX_NPEMH_SEND_RETRIES_DEFAULT); \ - \ - if (result != IX_SUCCESS) \ - { \ - ERROR_LOG("DB: Failed to send NPE message\n"); \ - } \ - } while (0); - -#define IX_ETHDB_SYNC_SEND_NPE_MSG(npeId, msg, result) \ - do { \ - result = ixNpeMhMessageWithResponseSend(npeId, msg, msg.data[0] >> 24, ixEthDBNpeMsgAck, IX_NPEMH_SEND_RETRIES_DEFAULT); \ - \ - if (result == IX_SUCCESS) \ - { \ - result = ixOsalMutexLock(&ixEthDBPortInfo[IX_ETH_DB_NPE_TO_PORT_ID(npeId)].npeAckLock, IX_ETH_DB_NPE_TIMEOUT); \ - \ - if (result != IX_SUCCESS) \ - { \ - ERROR_LOG("DB: NPE failed to respond within %dms\n", IX_ETH_DB_NPE_TIMEOUT); \ - } \ - } \ - else \ - { \ - ERROR_LOG("DB: Failed to send NPE message\n"); \ - } \ - } while (0); - -#ifndef IX_NDEBUG -#define IX_ETH_DB_NPE_MSG_HISTORY_DEPTH (100) -extern IX_ETH_DB_PUBLIC UINT32 npeMsgHistory[IX_ETH_DB_NPE_MSG_HISTORY_DEPTH][2]; -extern IX_ETH_DB_PUBLIC UINT32 npeMsgHistoryLen; -#endif - -#define IX_ETHDB_SEND_NPE_MSG(npeId, msg, result) { LOG_NPE_MSG(msg); IX_ETHDB_SYNC_SEND_NPE_MSG(npeId, msg, result); } - -#endif /* IxEthDBMessages_p_H */ diff --git a/cpu/ixp/npe/include/IxEthDBPortDefs.h b/cpu/ixp/npe/include/IxEthDBPortDefs.h deleted file mode 100644 index c3acbdddef..0000000000 --- a/cpu/ixp/npe/include/IxEthDBPortDefs.h +++ /dev/null @@ -1,163 +0,0 @@ -/** - * @file IxEthDBPortDefs.h - * - * @brief Public definition of the ports and port capabilities - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -/** - * @defgroup IxEthDBPortDefs IXP400 Ethernet Database Port Definitions (IxEthDBPortDefs) - * - * @brief IXP400 Public definition of the ports and port capabilities - * - * @{ - */ - -#ifndef IxEthDBPortDefs_H -#define IxEthDBPortDefs_H - -/** - * @brief Port types - currently only Ethernet NPEs are recognized as specific types - * All other (user-defined) ports must be specified as IX_ETH_GENERIC - */ -typedef enum -{ - IX_ETH_GENERIC = 0, /**< generic ethernet port */ - IX_ETH_NPE /**< specific Ethernet NPE */ -} IxEthDBPortType; - -/** - * @brief Port capabilities - used by ixEthAccDatabaseMaintenance to decide whether it - * should manually age entries or not depending on the port capabilities. - * - * Ethernet NPEs have aging capabilities, meaning that they will age the entries - * automatically (by themselves).*/ -typedef enum -{ - IX_ETH_NO_CAPABILITIES = 0, /**< no aging capabilities */ - IX_ETH_ENTRY_AGING = 0x1 /**< aging capabilities present */ -} IxEthDBPortCapability; - -/** - * @brief Port Definition - a structure contains the Port type and capabilities - */ -typedef struct -{ - IxEthDBPortType type; - IxEthDBPortCapability capabilities; -} IxEthDBPortDefinition; - -/** - * @brief Port definitions structure, indexed on the port ID - * @warning Ports 0 and 1 are used by the Ethernet access component therefore - * it is essential to be left untouched. Port 2 here (WAN) is given as - * an example port. The NPE firmware also assumes the NPE B to be - * the port 0 and NPE C to be the port 1. - * - * @note that only 32 ports (0..31) are supported by EthDB - */ -static const IxEthDBPortDefinition ixEthDBPortDefinitions[] = -{ - /* id type capabilities */ - { /* 0 */ IX_ETH_NPE, IX_ETH_NO_CAPABILITIES }, /* Ethernet NPE B */ - { /* 1 */ IX_ETH_NPE, IX_ETH_NO_CAPABILITIES }, /* Ethernet NPE C */ - { /* 2 */ IX_ETH_NPE, IX_ETH_NO_CAPABILITIES }, /* Ethernet NPE A */ - { /* 3 */ IX_ETH_GENERIC, IX_ETH_NO_CAPABILITIES }, /* WAN port */ -}; - -/** - * @def IX_ETH_DB_NUMBER_OF_PORTS - * @brief number of supported ports - */ -#define IX_ETH_DB_NUMBER_OF_PORTS (sizeof (ixEthDBPortDefinitions) / sizeof (ixEthDBPortDefinitions[0])) - -/** - * @def IX_ETH_DB_UNKNOWN_PORT - * @brief definition of an unknown port - */ -#define IX_ETH_DB_UNKNOWN_PORT (0xff) - -/** - * @def IX_ETH_DB_ALL_PORTS - * @brief Special port ID indicating all the ports - * @note This port ID can be used only by a subset of the EthDB API; each - * function specifically mentions whether this is a valid parameter as the port ID - */ -#define IX_ETH_DB_ALL_PORTS (IX_ETH_DB_NUMBER_OF_PORTS + 1) - -/** - * @def IX_ETH_DB_PORTS_ASSERTION - * @brief catch invalid port definitions (<2) with a - * compile-time assertion resulting in a duplicate case error. - */ -#define IX_ETH_DB_PORTS_ASSERTION { switch(0) { case 0 : ; case 1 : ; case IX_ETH_DB_NUMBER_OF_PORTS : ; }} - -/** - * @def IX_ETH_DB_CHECK_PORT(portID) - * @brief safety checks to verify whether the port is invalid or uninitialized - */ -#define IX_ETH_DB_CHECK_PORT(portID) \ -{ \ - if ((portID) >= IX_ETH_DB_NUMBER_OF_PORTS) \ - { \ - return IX_ETH_DB_INVALID_PORT; \ - } \ - \ - if (!ixEthDBPortInfo[(portID)].enabled) \ - { \ - return IX_ETH_DB_PORT_UNINITIALIZED; \ - } \ -} - -/** - * @def IX_ETH_DB_CHECK_PORT_ALL(portID) - * @brief safety checks to verify whether the port is invalid or uninitialized; - * tolerates the use of IX_ETH_DB_ALL_PORTS - */ -#define IX_ETH_DB_CHECK_PORT_ALL(portID) \ -{ \ - if ((portID) != IX_ETH_DB_ALL_PORTS) \ - IX_ETH_DB_CHECK_PORT(portID) \ -} - -#endif /* IxEthDBPortDefs_H */ -/** - *@} - */ diff --git a/cpu/ixp/npe/include/IxEthDBQoS.h b/cpu/ixp/npe/include/IxEthDBQoS.h deleted file mode 100644 index 6d34889452..0000000000 --- a/cpu/ixp/npe/include/IxEthDBQoS.h +++ /dev/null @@ -1,154 +0,0 @@ -/** - * @file IxEthDBQoS.h - * - * @brief Public definitions for QoS traffic classes - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -/** - * @defgroup IxEthDBPortDefs IXP400 Ethernet QoS definitions - * - * @brief IXP00 Public definitions for QoS traffic classes - * - * @{ - */ - -#ifndef IxEthDBQoS_H -#define IxEthDBQoS_H - -/** - * @def IX_ETH_DB_QUEUE_UNAVAILABLE - * @brief alias to indicate a queue (traffic class) is not available - */ -#define IX_ETH_DB_QUEUE_UNAVAILABLE (0) - -#ifndef IX_IEEE802_1Q_QOS_PRIORITY_COUNT -/** - * @def IX_IEEE802_1Q_QOS_PRIORITY_COUNT - * @brief number of QoS priorities, according to IEEE 802.1Q - */ -#define IX_IEEE802_1Q_QOS_PRIORITY_COUNT (8) -#endif - -/** - * @brief array containing all the supported traffic class configurations - */ -static const -UINT8 ixEthDBQueueAssignments[][IX_IEEE802_1Q_QOS_PRIORITY_COUNT] = -{ - { 4, 5, 6, 7, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE }, - { 15, 16, 17, 18, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE }, - { 11, 23, 26, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE }, - { 4, 5, 6, 7, 8, 9, 10, 11 } - /* add here all other cases of queue configuration structures and update ixEthDBTrafficClassDefinitions to use them */ -}; - -/** - * @brief value used to index the NPE A functionality ID in the traffic class definition table - */ -#define IX_ETH_DB_NPE_A_FUNCTIONALITY_ID_INDEX (0) - -/** - * @brief value used to index the traffic class count in the traffic class definition table - */ -#define IX_ETH_DB_TRAFFIC_CLASS_COUNT_INDEX (1) - -/** - * @brief value used to index the queue assignment index in the traffic class definition table - */ -#define IX_ETH_DB_QUEUE_ASSIGNMENT_INDEX (2) - -/** - * @brief traffic class definitions - * - * This array contains the default traffic class definition configuration, - * as well as any special cases dictated by the functionality ID of NPE A. - * - * The default case should not be removed (otherwise the Ethernet - * components will assert a fatal failure on initialization). - */ -static const -UINT8 ixEthDBTrafficClassDefinitions[][3] = -{ - /* NPE A functionality ID | traffic class count | queue assignment index (points to the queue enumeration in ixEthDBQueueAssignments) */ - { 0x00, 4, 0 }, /* default case - DO NOT REMOVE */ - { 0x04, 4, 1 }, /* NPE A image ID 0.4.0.0 */ - { 0x09, 3, 2 }, /* NPE A image ID 0.9.0.0 */ - { 0x80, 8, 3 }, /* NPE A image ID 10.80.02.0 */ - { 0x81, 8, 3 }, /* NPE A image ID 10.81.02.0 */ - { 0x82, 8, 3 } /* NPE A image ID 10.82.02.0 */ -}; - -/** - * @brief IEEE 802.1Q recommended QoS Priority => traffic class maps - * - * @verbatim - Number of available traffic classes - 1 2 3 4 5 6 7 8 - QoS Priority - 0 0 0 0 1 1 1 1 2 - 1 0 0 0 0 0 0 0 0 - 2 0 0 0 0 0 0 0 1 - 3 0 0 0 1 1 2 2 3 - 4 0 1 1 2 2 3 3 4 - 5 0 1 1 2 3 4 4 5 - 6 0 1 2 3 4 5 5 6 - 7 0 1 2 3 4 5 6 7 - - @endverbatim - */ -static const -UINT8 ixEthIEEE802_1QUserPriorityToTrafficClassMapping[IX_IEEE802_1Q_QOS_PRIORITY_COUNT][IX_IEEE802_1Q_QOS_PRIORITY_COUNT] = - { - { 0, 0, 0, 0, 0, 0, 0, 0 }, /* 1 traffic class available */ - { 0, 0, 0, 0, 1, 1, 1, 1 }, /* 2 traffic classes available */ - { 0, 0, 0, 0, 1, 1, 2, 2 }, /* 3 traffic classes available */ - { 1, 0, 0, 1, 2, 2, 3, 3 }, /* 4 traffic classes available */ - { 1, 0, 0, 1, 2, 3, 4, 4 }, /* 5 traffic classes available */ - { 1, 0, 0, 2, 3, 4, 5, 5 }, /* 6 traffic classes available */ - { 1, 0, 0, 2, 3, 4, 5, 6 }, /* 7 traffic classes available */ - { 2, 0, 1, 3, 4, 5, 6, 7 } /* 8 traffic classes available */ - }; - -#endif /* IxEthDBQoS_H */ - -/** - *@} - */ diff --git a/cpu/ixp/npe/include/IxEthDB_p.h b/cpu/ixp/npe/include/IxEthDB_p.h deleted file mode 100644 index ccec7ea7be..0000000000 --- a/cpu/ixp/npe/include/IxEthDB_p.h +++ /dev/null @@ -1,710 +0,0 @@ -/** - * @file IxEthDB_p.h - * - * @brief Private MAC learning API - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#ifndef IxEthDB_p_H -#define IxEthDB_p_H - -#include -#include -#include -#include -#include - -#include "IxEthDBMessages_p.h" -#include "IxEthDBLog_p.h" - -#if (CPU==SIMSPARCSOLARIS) - -/* when running unit tests intLock() won't protect the event queue so we lock it manually */ -#define TEST_FIXTURE_LOCK_EVENT_QUEUE { ixOsalMutexLock(&eventQueueLock, IX_OSAL_WAIT_FOREVER); } -#define TEST_FIXTURE_UNLOCK_EVENT_QUEUE { ixOsalMutexUnlock(&eventQueueLock); } - -#else - -#define TEST_FIXTURE_LOCK_EVENT_QUEUE /* nothing */ -#define TEST_FIXTURE_UNLOCK_EVENT_QUEUE /* nothing */ - -#endif /* #if(CPU==SIMSPARCSOLARIS) */ - -#ifndef IX_UNIT_TEST - -#define TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER /* nothing */ -#define TEST_FIXTURE_MARK_OVERFLOW_EVENT /* nothing */ - -#else - -extern int dbAccessCounter; -extern int overflowEvent; - -#define TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER { dbAccessCounter++; } -#define TEST_FIXTURE_MARK_OVERFLOW_EVENT { overflowEvent = 1; } - -#endif - -/* code readability markers */ -#define __mempool__ /* memory pool marker */ -#define __lock__ /* hash write locking marker */ -#define __smartpointer__ /* smart pointer marker - warning: use only clone() when duplicating! */ -#define __alignment__ /* marker for data used only as alignment zones */ - -/* constants */ -#define IX_ETH_DB_NPE_TIMEOUT (100) /* NPE response timeout, in ms */ - -/** - * number of hash table buckets - * it should be at least 8x the predicted number of entries for performance - * each bucket needs 8 bytes - */ -#define NUM_BUCKETS (8192) - -/** - * number of hash table buckets to preload when incrementing bucket iterator - * = two cache lines - */ -#define IX_ETHDB_CACHE_LINE_AHEAD (2) - -#define IX_ETHDB_BUCKETPTR_AHEAD ((IX_ETHDB_CACHE_LINE_AHEAD * IX_OSAL_CACHE_LINE_SIZE)/sizeof(void *)) - -#define IX_ETHDB_BUCKET_INDEX_MASK (((IX_OSAL_CACHE_LINE_SIZE)/sizeof(void *)) - 1) - -/* locks */ -#define MAX_LOCKS (20) /**< maximum number of locks used simultaneously, do not tamper with */ - -/* learning tree constants */ -#define INITIAL_ELT_SIZE (8) /**< initial byte size of tree (empty unused root size) */ -#define MAX_ELT_SIZE (512) /**< maximum number of entries (includes unused root) */ -#define MAX_GW_SIZE (32) /**< maximum number of gateway entries (including unused root) */ -#define MAX_FW_SIZE (32) /**< maximum number of firewall entries (including unused root) */ -#define ELT_ENTRY_SIZE (8) /**< entry size, in bytes */ -#define ELT_ROOT_OFFSET (ELT_ENTRY_SIZE) /**< tree root offset, in bytes - node preceeding root is unused */ -#define FULL_ELT_BYTE_SIZE (MAX_ELT_SIZE * ELT_ENTRY_SIZE) /**< full size of tree, in bytes, including unused root */ -#define FULL_GW_BYTE_SIZE (MAX_GW_SIZE * ELT_ENTRY_SIZE) /**< full size of gateway list, in bytes, including unused root */ -#define FULL_FW_BYTE_SIZE (MAX_FW_SIZE * ELT_ENTRY_SIZE) /**< full size of firewall table, in bytes, including unused root */ - -/* maximum size of the VLAN table: - * 4096 bits (one per VLAN) - * 8 bits in one byte - * interleaved VLAN membership and VLAN TTI (*2) */ -#define FULL_VLAN_BYTE_SIZE (4096 / 8 * 2) - -/* upper 9 bits used as set index, lower 3 bits as byte index */ -#define VLAN_SET_OFFSET(vlanID) ((vlanID) >> 3) -#define VLAN_SET_MASK(vlanID) (0x7 - ((vlanID) & 0x7)) - -/* Update zone definitions */ -#define NPE_TREE_MEM_SIZE (4096) /* ((511 entries + 1 unused root) * 8 bytes/entry) */ - -/* check the above value, we rely on 4k */ -#if NPE_TREE_MEM_SIZE != 4096 - #error NPE_TREE_MEM_SIZE is not defined to 4096 bytes! -#endif - -/* Size Filtering limits (Jumbo frame filtering) */ -#define IX_ETHDB_MAX_FRAME_SIZE 65535 /* other ports than NPE ports */ -#define IX_ETHDB_MIN_FRAME_SIZE 1 /* other ports than NPE ports */ -#define IX_ETHDB_MAX_NPE_FRAME_SIZE 16320 /* NPE ports firmware limit */ -#define IX_ETHDB_MIN_NPE_FRAME_SIZE 1 /* NPE ports firmware limit */ -#define IX_ETHDB_DEFAULT_FRAME_SIZE 1522 - -/* memory management pool sizes */ - -/* - * Note: - * - * NODE_POOL_SIZE controls the maximum number of elements in the database at any one time. - * It should be large enough to cover all the search trees of all the ports simultaneously. - * - * MAC_POOL_SIZE should be higher than NODE_POOL_SIZE by at least the total number of MAC addresses - * possible to be held at any time in all the ports. - * - * TREE_POOL_SIZE should follow the same guideline as for MAC_POOL_SIZE. - * - * The database structure described here (2000/4000/4000) is enough for two NPEs holding at most 511 - * entries each plus one PCI NIC holding at most 900 entries. - */ - -#define NODE_POOL_SIZE (2000) /**< number of HashNode objects - also master number of elements in the database; each entry has 16 bytes */ -#define MAC_POOL_SIZE (4000) /**< number of MacDescriptor objects; each entry has 28 bytes */ -#define TREE_POOL_SIZE (4000) /**< number of MacTreeNode objects; each entry has 16 bytes */ - -/* retry policies */ -#define BUSY_RETRY_ENABLED (TRUE) /**< if set to TRUE the API will retry automatically calls returning BUSY */ -#define FOREVER_RETRY (TRUE) /**< if set to TRUE the API will retry forever BUSY calls */ -#define MAX_RETRIES (400) /**< upper retry limit - used only when FOREVER_RETRY is FALSE */ -#define BUSY_RETRY_YIELD (5) /**< ticks to yield for every failed retry */ - -/* event management */ -#define EVENT_QUEUE_SIZE (500) /**< size of the sink collecting events from the Message Handler FIFO */ -#define EVENT_PROCESSING_LIMIT (100) /**< batch processing control size (how many events are extracted from the queue at once) */ - -/* MAC descriptors */ -#define STATIC_ENTRY (TRUE) -#define DYNAMIC_ENTRY (FALSE) - -/* age reset on next maintenance - incrementing by 1 will reset to 0 */ -#define AGE_RESET (0xFFFFFFFF) - -/* dependency maps */ -#define EMPTY_DEPENDENCY_MAP (0) - -/* trees */ -#define RIGHT (1) -#define LEFT (-1) - -/* macros */ -#define IX_ETH_DB_CHECK_PORT_EXISTS(portID) \ -{ \ - if ((portID) >= IX_ETH_DB_NUMBER_OF_PORTS) \ - { \ - return IX_ETH_DB_INVALID_PORT; \ - } \ -} - -#define IX_ETH_DB_CHECK_PORT_INITIALIZED(portID) \ -{ \ - if ((portID) >= IX_ETH_DB_NUMBER_OF_PORTS) \ - { \ - return IX_ETH_DB_INVALID_PORT; \ - } \ - else \ - { \ - if (!ixEthDBPortInfo[portID].initialized) \ - { \ - return IX_ETH_DB_PORT_UNINITIALIZED; \ - } \ - } \ -} - -/* single NPE check */ -#define IX_ETH_DB_CHECK_SINGLE_NPE(portID) \ - if (ixEthDBSingleEthNpeCheck(portID) != IX_ETH_DB_SUCCESS) \ - { \ - WARNING_LOG("EthDB: port ID %d is unavailable\n",(UINT32) portID); \ - \ - return IX_ETH_DB_INVALID_PORT; \ - } - -/* feature check */ -#define IX_ETH_DB_CHECK_FEATURE(portID, feature) \ - if ((ixEthDBPortInfo[portID].featureStatus & feature) == 0) \ - { \ - return IX_ETH_DB_FEATURE_UNAVAILABLE; \ - } - -/* busy retrying */ -#define BUSY_RETRY(functionCall) \ - { \ - UINT32 retries = 0; \ - IxEthDBStatus br_result; \ - \ - while ((br_result = functionCall) == IX_ETH_DB_BUSY \ - && BUSY_RETRY_ENABLED && (FOREVER_RETRY || ++retries < MAX_RETRIES)) { ixOsalSleep(BUSY_RETRY_YIELD); }; \ - \ - if ((!FOREVER_RETRY && retries == MAX_RETRIES) || (br_result == IX_ETH_DB_FAIL)) \ - {\ - ERROR_LOG("Ethernet Learning Database Error: BUSY_RETRY failed at %s:%d\n", __FILE__, __LINE__); \ - }\ - } - -#define BUSY_RETRY_WITH_RESULT(functionCall, brwr_result) \ - { \ - UINT32 retries = 0; \ - \ - while ((brwr_result = functionCall) == IX_ETH_DB_BUSY \ - && BUSY_RETRY_ENABLED && (FOREVER_RETRY || ++retries < MAX_RETRIES)) { ixOsalSleep(BUSY_RETRY_YIELD); }; \ - \ - if ((!FOREVER_RETRY && retries == MAX_RETRIES) || (brwr_result == IX_ETH_DB_FAIL)) \ - {\ - ERROR_LOG("Ethernet Learning Database Error: BUSY_RETRY_WITH_RESULT failed at %s:%d\n", __FILE__, __LINE__); \ - }\ - } - -/* iterators */ -#define IS_ITERATOR_VALID(iteratorPtr) ((iteratorPtr)->node != NULL) - -/* dependency port maps */ - -/* Warning: if port indexing starts from 1 replace (portID) with (portID - 1) in DEPENDENCY_MAP (and make sure IX_ETH_DB_NUMBER_OF_PORTS is big enough) */ - -/* gives an empty dependency map */ -#define SET_EMPTY_DEPENDENCY_MAP(map) { int i = 0; for (; i < 32 ; i++) map[i] = 0; } - -#define IS_EMPTY_DEPENDENCY_MAP(result, map) { int i = 0 ; result = TRUE; for (; i < 32 ; i++) if (map[i] != 0) { result = FALSE; break; }} - -/** - * gives a map consisting only of 'portID' - */ -#define SET_DEPENDENCY_MAP(map, portID) {SET_EMPTY_DEPENDENCY_MAP(map); map[portID >> 3] = 1 << (portID & 0x7);} - -/** - * gives a map resulting from joining map1 and map2 - */ -#define JOIN_MAPS(map, map1, map2) { int i = 0; for (; i < 32 ; i++) map[i] = map1[i] | map2[i]; } - -/** - * gives the map resulting from joining portID and map - */ -#define JOIN_PORT_TO_MAP(map, portID) { map[portID >> 3] |= 1 << (portID & 0x7); } - -/** - * gives the map resulting from excluding portID from map - */ -#define EXCLUDE_PORT_FROM_MAP(map, portID) { map[portID >> 3] &= ~(1 << (portID & 0x7); } - -/** - * returns TRUE if map1 is a subset of map2 and FALSE otherwise - */ -#define IS_MAP_SUBSET(result, map1, map2) { int i = 0; result = TRUE; for (; i < 32 ; i++) if ((map1[i] | map2[i]) != map2[i]) result = FALSE; } - -/** - * returns TRUE is portID is part of map and FALSE otherwise - */ -#define IS_PORT_INCLUDED(portID, map) ((map[portID >> 3] & (1 << (portID & 0x7))) != 0) - -/** - * returns the difference between map1 and map2 (ports included in map1 and not included in map2) - */ -#define DIFF_MAPS(map, map1, map2) { int i = 0; for (; i < 32 ; i++) map[i] = map1[i] ^ (map1[i] & map2[i]); } - -/** - * returns TRUE if the maps collide (have at least one port in common) and FALSE otherwise - */ -#define MAPS_COLLIDE(result, map1, map2) { int i = 0; result = FALSE; for (; i < 32 ; i++) if ((map1[i] & map2[i]) != 0) result = TRUE; } - -/* size (number of ports) of a dependency map */ -#define GET_MAP_SIZE(map, size) { int i = 0, b = 0; size = 0; for (; i < 32 ; i++) { char y = map[i]; for (; b < 8 && (y >>= 1); b++) size += (y & 1); }} - -/* copy map2 into map1 */ -#define COPY_DEPENDENCY_MAP(map1, map2) { memcpy (map1, map2, sizeof (map1)); } - -/* definition of a port map size/port number which cannot be reached (we support at most 32 ports) */ -#define MAX_PORT_SIZE (0xFF) -#define MAX_PORT_NUMBER (0xFF) - -#define IX_ETH_DB_CHECK_REFERENCE(ptr) { if ((ptr) == NULL) { return IX_ETH_DB_INVALID_ARG; } } -#define IX_ETH_DB_CHECK_MAP(portID, map) { if (!IS_PORT_INCLUDED(portID, map)) { return IX_ETH_DB_INVALID_ARG; } } - -/* event queue macros */ -#define EVENT_QUEUE_WRAP(offset) ((offset) >= EVENT_QUEUE_SIZE ? (offset) - EVENT_QUEUE_SIZE : (offset)) - -#define CAN_ENQUEUE(eventQueuePtr) ((eventQueuePtr)->length < EVENT_QUEUE_SIZE) - -#define QUEUE_HEAD(eventQueuePtr) (&(eventQueuePtr)->queue[EVENT_QUEUE_WRAP((eventQueuePtr)->base + (eventQueuePtr)->length)]) - -#define QUEUE_TAIL(eventQueuePtr) (&(eventQueuePtr)->queue[(eventQueuePtr)->base]) - -#define PUSH_UPDATE_QUEUE(eventQueuePtr) { (eventQueuePtr)->length++; } - -#define SHIFT_UPDATE_QUEUE(eventQueuePtr) \ - { \ - (eventQueuePtr)->base = EVENT_QUEUE_WRAP((eventQueuePtr)->base + 1); \ - (eventQueuePtr)->length--; \ - } - -#define RESET_QUEUE(eventQueuePtr) \ - { \ - (eventQueuePtr)->base = 0; \ - (eventQueuePtr)->length = 0; \ - } - -/* node stack macros - used to browse a tree without using a recursive function */ -#define NODE_STACK_INIT(stack) { (stack)->nodeCount = 0; } -#define NODE_STACK_PUSH(stack, node, offset) { (stack)->nodes[(stack)->nodeCount] = (node); (stack)->offsets[(stack)->nodeCount++] = (offset); } -#define NODE_STACK_POP(stack, node, offset) { (node) = (stack)->nodes[--(stack)->nodeCount]; offset = (stack)->offsets[(stack)->nodeCount]; } -#define NODE_STACK_NONEMPTY(stack) ((stack)->nodeCount != 0) - -#ifndef IX_NDEBUG -#define IX_ETH_DB_NPE_MSG_HISTORY_DEPTH (100) -#define LOG_NPE_MSG(msg) \ - do { \ - UINT32 npeMsgHistoryIndex = (npeMsgHistoryLen++) % IX_ETH_DB_NPE_MSG_HISTORY_DEPTH; \ - npeMsgHistory[npeMsgHistoryIndex][0] = msg.data[0]; \ - npeMsgHistory[npeMsgHistoryIndex][1] = msg.data[1]; \ - } while (0); -#else -#define LOG_NPE_MSG() /* nothing */ -#endif - -/* ----------- Data -------------- */ - -/* typedefs */ - -typedef UINT32 (*HashFunction)(void *entity); -typedef BOOL (*MatchFunction)(void *reference, void *entry); -typedef void (*FreeFunction)(void *entry); - -/** - * basic component of a hash table - */ -typedef struct HashNode_t -{ - void *data; /**< specific data */ - struct HashNode_t *next; /**< used for bucket chaining */ - - __mempool__ struct HashNode_t *nextFree; /**< memory pool management */ - - __lock__ IxOsalFastMutex lock; /**< node lock */ -} HashNode; - -/** - * @brief hash table iterator definition - * - * an iterator is an object which can be used - * to browse a hash table - */ -typedef struct -{ - UINT32 bucketIndex; /**< index of the currently iterated bucket */ - HashNode *previousNode; /**< reference to the previously iterated node within the current bucket */ - HashNode *node; /**< reference to the currently iterated node */ -} HashIterator; - -/** - * definition of a MAC descriptor (a database record) - */ - -typedef enum -{ - IX_ETH_DB_WIFI_AP_TO_STA = 0x0, - IX_ETH_DB_WIFI_AP_TO_AP = 0x1 -} IxEthDBWiFiRecordType; - -typedef union -{ - struct - { - UINT32 age; - BOOL staticEntry; /**< TRUE if this address is static (doesn't age) */ - } filteringData; - - struct - { - UINT32 age; - BOOL staticEntry; - UINT32 ieee802_1qTag; - } filteringVlanData; - - struct - { - IxEthDBWiFiRecordType type; /**< AP_TO_AP (0x1) or AP_TO_STA (0x0) */ - UINT32 gwAddressIndex; /**< used only when linearizing the entries for NPE usage */ - UINT8 gwMacAddress[IX_IEEE803_MAC_ADDRESS_SIZE]; - - __alignment__ UINT8 reserved2[2]; - } wifiData; -} IxEthDBRecordData; - -typedef struct MacDescriptor_t -{ - UINT8 macAddress[IX_IEEE803_MAC_ADDRESS_SIZE]; - - __alignment__ UINT8 reserved1[2]; - - UINT32 portID; - IxEthDBRecordType type; - IxEthDBRecordData recordData; - - /* used for internal operations, such as NPE linearization */ - void *internal; - - /* custom user data */ - void *user; - - __mempool__ struct MacDescriptor_t *nextFree; /**< memory pool management */ - __smartpointer__ UINT32 refCount; /**< smart pointer reference counter */ -} MacDescriptor; - -/** - * hash table definition - */ -typedef struct -{ - HashNode *hashBuckets[NUM_BUCKETS]; - UINT32 numBuckets; - - __lock__ IxOsalFastMutex bucketLocks[NUM_BUCKETS]; - - HashFunction entryHashFunction; - MatchFunction *matchFunctions; - FreeFunction freeFunction; -} HashTable; - -typedef enum -{ - IX_ETH_DB_MAC_KEY = 1, - IX_ETH_DB_MAC_PORT_KEY = 2, - IX_ETH_DB_MAC_VLAN_KEY = 3, - IX_ETH_DB_MAX_KEY_INDEX = 3 -} IxEthDBSearchKeyType; - -typedef struct MacTreeNode_t -{ - __smartpointer__ MacDescriptor *descriptor; - struct MacTreeNode_t *left, *right; - - __mempool__ struct MacTreeNode_t *nextFree; -} MacTreeNode; - -typedef IxEthDBStatus (*IxEthDBPortUpdateHandler)(IxEthDBPortId portID, IxEthDBRecordType type); - -typedef void (*IxEthDBNoteWriteFn)(void *address, MacTreeNode *node); - -typedef struct -{ - BOOL updateEnabled; /**< TRUE if updates are enabled for port */ - BOOL userControlled; /**< TRUE if the user has manually used ixEthDBPortUpdateEnableSet */ - BOOL treeInitialized; /**< TRUE if the NPE has received an initial tree */ - IxEthDBPortUpdateHandler updateHandler; /**< port update handler routine */ - void *npeUpdateZone; /**< port update memory zone */ - void *npeGwUpdateZone; /**< port update memory zone for gateways */ - void *vlanUpdateZone; /**< port update memory zone for VLAN tables */ - MacTreeNode *searchTree; /**< internal search tree, in MacTreeNode representation */ - BOOL searchTreePendingWrite; /**< TRUE if searchTree holds a tree pending write to the port */ -} PortUpdateMethod; - -typedef struct -{ - IxEthDBPortId portID; /**< port ID */ - BOOL enabled; /**< TRUE if the port is enabled */ - BOOL agingEnabled; /**< TRUE if aging on this port is enabled */ - BOOL initialized; - IxEthDBPortMap dependencyPortMap; /**< dependency port map for this port */ - PortUpdateMethod updateMethod; /**< update method structure */ - BOOL macAddressUploaded; /**< TRUE if the MAC address was uploaded into the port */ - UINT32 maxRxFrameSize; /**< maximum Rx frame size for this port */ - UINT32 maxTxFrameSize; /**< maximum Rx frame size for this port */ - - UINT8 bbsid[6]; - __alignment__ UINT8 reserved[2]; - UINT32 frameControlDurationID; /**< Frame Control - Duration/ID WiFi control */ - - IxEthDBVlanTag vlanTag; /**< default VLAN tag for port */ - IxEthDBPriorityTable priorityTable; /**< QoS <=> internal priority mapping */ - IxEthDBVlanSet vlanMembership; - IxEthDBVlanSet transmitTaggingInfo; - IxEthDBFrameFilter frameFilter; - IxEthDBTaggingAction taggingAction; - - UINT32 npeFrameFilter; - UINT32 npeTaggingAction; - - IxEthDBFirewallMode firewallMode; - BOOL srcAddressFilterEnabled; - - BOOL stpBlocked; - - IxEthDBFeature featureCapability; - IxEthDBFeature featureStatus; - - UINT32 ixEthDBTrafficClassAQMAssignments[IX_IEEE802_1Q_QOS_PRIORITY_COUNT]; - - UINT32 ixEthDBTrafficClassCount; - - UINT32 ixEthDBTrafficClassAvailable; - - - - __lock__ IxOsalMutex npeAckLock; -} PortInfo; - -/* list of port information structures indexed on port Ids */ -extern IX_ETH_DB_PUBLIC PortInfo ixEthDBPortInfo[IX_ETH_DB_NUMBER_OF_PORTS]; - -typedef enum -{ - IX_ETH_DB_ADD_FILTERING_RECORD = 0xFF0001, - IX_ETH_DB_REMOVE_FILTERING_RECORD = 0xFF0002 -} PortEventType; - -typedef struct -{ - UINT32 eventType; - IxEthDBPortId portID; - IxEthDBMacAddr macAddr; - BOOL staticEntry; -} PortEvent; - -typedef struct -{ - PortEvent queue[EVENT_QUEUE_SIZE]; - UINT32 base; - UINT32 length; -} PortEventQueue; - -typedef struct -{ - IxEthDBPortId portID; /**< originating port */ - MacDescriptor *macDescriptors[MAX_ELT_SIZE]; /**< addresses to be synced into db */ - UINT32 addressCount; /**< number of addresses */ -} TreeSyncInfo; - -typedef struct -{ - MacTreeNode *nodes[MAX_ELT_SIZE]; - UINT32 offsets[MAX_ELT_SIZE]; - UINT32 nodeCount; -} MacTreeNodeStack; - -/* Prototypes */ - -/* ----------- Memory management -------------- */ - -IX_ETH_DB_PUBLIC void ixEthDBInitMemoryPools(void); - -IX_ETH_DB_PUBLIC HashNode* ixEthDBAllocHashNode(void); -IX_ETH_DB_PUBLIC void ixEthDBFreeHashNode(HashNode *); - -IX_ETH_DB_PUBLIC __smartpointer__ MacDescriptor* ixEthDBAllocMacDescriptor(void); -IX_ETH_DB_PUBLIC __smartpointer__ MacDescriptor* ixEthDBCloneMacDescriptor(MacDescriptor *macDescriptor); -IX_ETH_DB_PUBLIC __smartpointer__ void ixEthDBFreeMacDescriptor(MacDescriptor *); - -IX_ETH_DB_PUBLIC __smartpointer__ MacTreeNode* ixEthDBAllocMacTreeNode(void); -IX_ETH_DB_PUBLIC __smartpointer__ MacTreeNode* ixEthDBCloneMacTreeNode(MacTreeNode *); -IX_ETH_DB_PUBLIC __smartpointer__ void ixEthDBFreeMacTreeNode(MacTreeNode *); - -IX_ETH_DB_PUBLIC void ixEthDBPoolFreeMacTreeNode(MacTreeNode *); -IX_ETH_DB_PUBLIC UINT32 ixEthDBSearchTreeUsageGet(MacTreeNode *tree); -IX_ETH_DB_PUBLIC int ixEthDBShowMemoryStatus(void); - -/* Hash Table */ -IX_ETH_DB_PUBLIC void ixEthDBInitHash(HashTable *hashTable, UINT32 numBuckets, HashFunction entryHashFunction, MatchFunction *matchFunctions, FreeFunction freeFunction); - -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBAddHashEntry(HashTable *hashTable, void *entry); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBRemoveHashEntry(HashTable *hashTable, int keyType, void *reference); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBSearchHashEntry(HashTable *hashTable, int keyType, void *reference, HashNode **searchResult); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPeekHashEntry(HashTable *hashTable, int keyType, void *reference); -IX_ETH_DB_PUBLIC void ixEthDBReleaseHashNode(HashNode *node); - -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBInitHashIterator(HashTable *hashTable, HashIterator *iterator); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBIncrementHashIterator(HashTable *hashTable, HashIterator *iterator); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBRemoveEntryAtHashIterator(HashTable *hashTable, HashIterator *iterator); -IX_ETH_DB_PUBLIC void ixEthDBReleaseHashIterator(HashIterator *iterator); - -/* API Support */ -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortAddressSet(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); -IX_ETH_DB_PUBLIC void ixEthDBMaximumFrameSizeAckCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg); - -/* DB Core functions */ -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBInit(void); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBAdd(MacDescriptor *newRecordTemplate, IxEthDBPortMap updateTrigger); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBRemove(MacDescriptor *templateRecord, IxEthDBPortMap updateTrigger); -IX_ETH_DB_PUBLIC HashNode* ixEthDBSearch(IxEthDBMacAddr *macAddress, IxEthDBRecordType typeFilter); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPeek(IxEthDBMacAddr *macAddress, IxEthDBRecordType typeFilter); - -/* Learning support */ -IX_ETH_DB_PUBLIC UINT32 ixEthDBAddressCompare(UINT8 *mac1, UINT8 *mac2); -IX_ETH_DB_PUBLIC BOOL ixEthDBAddressMatch(void *reference, void *entry); -IX_ETH_DB_PUBLIC UINT32 ixEthDBEntryXORHash(void *macDescriptor); -IX_ETH_DB_PUBLIC UINT32 ixEthDBKeyXORHash(void *macAddress); - -/* Port updates */ -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBNPEUpdateHandler(IxEthDBPortId portID, IxEthDBRecordType type); -IX_ETH_DB_PUBLIC void ixEthDBUpdatePortLearningTrees(IxEthDBPortMap triggerPorts); -IX_ETH_DB_PUBLIC void ixEthDBNPEAccessRequest(IxEthDBPortId portID); -IX_ETH_DB_PUBLIC void ixEthDBUpdateLock(void); -IX_ETH_DB_PUBLIC void ixEthDBUpdateUnlock(void); -IX_ETH_DB_PUBLIC MacTreeNode* ixEthDBQuery(MacTreeNode *searchTree, IxEthDBPortMap query, IxEthDBRecordType recordFilter, UINT32 maximumEntries); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBFirewallUpdate(IxEthDBPortId portID, void *address, UINT32 epDelta); - -/* Init/unload */ -IX_ETH_DB_PUBLIC void ixEthDBPortSetAckCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBEventProcessorInit(void); -IX_ETH_DB_PUBLIC void ixEthDBPortInit(IxEthDBPortId portID); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortEnable(IxEthDBPortId portID); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortDisable(IxEthDBPortId portID); -IX_ETH_DB_PUBLIC void ixEthDBNPEUpdateAreasInit(void); -IX_ETH_DB_PUBLIC UINT32 ixEthDBMatchMethodsRegister(MatchFunction *matchFunctions); -IX_ETH_DB_PUBLIC UINT32 ixEthDBRecordSerializeMethodsRegister(void); -IX_ETH_DB_PUBLIC UINT32 ixEthDBUpdateTypeRegister(BOOL *typeArray); -IX_ETH_DB_PUBLIC void ixEthDBNPEUpdateAreasUnload(void); -IX_ETH_DB_PUBLIC void ixEthDBFeatureCapabilityScan(void); -IX_ETH_DB_PUBLIC UINT32 ixEthDBKeyTypeRegister(UINT32 *keyType); - -/* Event processing */ -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBDefaultEventCallbackEnable(IxEthDBPortId portID, BOOL enable); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBTriggerAddPortUpdate(IxEthDBMacAddr *macAddr, IxEthDBPortId portID, BOOL staticEntry); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBTriggerRemovePortUpdate(IxEthDBMacAddr *macAddr, IxEthDBPortId portID); -IX_ETH_DB_PUBLIC void ixEthDBNPEEventCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg); - -/* NPE adaptor */ -IX_ETH_DB_PUBLIC void ixEthDBGetMacDatabaseCbk(IxNpeMhNpeId npeID, IxNpeMhMessage msg); -IX_ETH_DB_PUBLIC void ixEthDBNpeMsgAck(IxNpeMhNpeId npeID, IxNpeMhMessage msg); -IX_ETH_DB_PUBLIC void ixEthDBNPESyncScan(IxEthDBPortId portID, void *eltBaseAddress, UINT32 eltSize); -IX_ETH_DB_PUBLIC void ixEthDBNPETreeWrite(IxEthDBRecordType type, UINT32 totalSize, void *baseAddress, MacTreeNode *tree, UINT32 *blocks, UINT32 *startIndex); -IX_ETH_DB_PUBLIC void ixEthDBNPEGatewayNodeWrite(void *address, MacTreeNode *node); - -/* Other public API functions */ -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBStartLearningFunction(void); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBStopLearningFunction(void); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortUpdateEnableSet(IxEthDBPortId portID, BOOL enableUpdate); - -/* Maximum Tx/Rx public functions */ -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBFilteringPortMaximumRxFrameSizeSet(IxEthDBPortId portID, UINT32 maximumRxFrameSize); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBFilteringPortMaximumTxFrameSizeSet(IxEthDBPortId portID, UINT32 maximumTxFrameSize); - -/* VLAN-related */ -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortVlanTableSet(IxEthDBPortId portID, IxEthDBVlanSet portVlanTable, IxEthDBVlanSet vlanSet); - -/* Record search */ -IX_ETH_DB_PUBLIC BOOL ixEthDBAddressRecordMatch(void *untypedReference, void *untypedEntry); -IX_ETH_DB_PUBLIC BOOL ixEthDBVlanRecordMatch(void *untypedReference, void *untypedEntry); -IX_ETH_DB_PUBLIC BOOL ixEthDBPortRecordMatch(void *untypedReference, void *untypedEntry); -IX_ETH_DB_PUBLIC BOOL ixEthDBNullMatch(void *reference, void *entry); -IX_ETH_DB_PUBLIC HashNode* ixEthDBPortSearch(IxEthDBMacAddr *macAddress, IxEthDBPortId portID, IxEthDBRecordType typeFilter); -IX_ETH_DB_PUBLIC HashNode* ixEthDBVlanSearch(IxEthDBMacAddr *macAddress, IxEthDBVlanId vlanID, IxEthDBRecordType typeFilter); - -/* Utilities */ -IX_ETH_DB_PUBLIC const char* mac2string(const unsigned char *mac); -IX_ETH_DB_PUBLIC void showHashInfo(void); -IX_ETH_DB_PUBLIC int ixEthDBAnalyzeHash(void); -IX_ETH_DB_PUBLIC const char* errorString(IxEthDBStatus error); -IX_ETH_DB_PUBLIC int numHashElements(void); -IX_ETH_DB_PUBLIC void zapHashtable(void); -IX_ETH_DB_PUBLIC BOOL ixEthDBCheckSingleBitValue(UINT32 value); - -/* Single Eth NPE Check */ -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBSingleEthNpeCheck(IxEthDBPortId portId); - -#endif /* IxEthDB_p_H */ - diff --git a/cpu/ixp/npe/include/IxEthMii.h b/cpu/ixp/npe/include/IxEthMii.h deleted file mode 100644 index 397253a947..0000000000 --- a/cpu/ixp/npe/include/IxEthMii.h +++ /dev/null @@ -1,270 +0,0 @@ -/** - * @file IxEthMii.h - * - * @brief this file contains the public API of @ref IxEthMii component - * - * Design notes : - * The main intent of this API is to inplement MII high level fonctionalitoes - * to support the codelets provided with the IXP400 software releases. It - * superceedes previous interfaces provided with @ref IxEThAcc component. - * - * This API has been tested with the PHYs provided with the - * IXP400 development platforms. It may not work for specific Ethernet PHYs - * used on specific boards. - * - * This source code detects and interface the LXT972, LXT973 and KS6995 - * Ethernet PHYs. - * - * This source code should be considered as an example which may need - * to be adapted for different hardware implementations. - * - * It is strongly recommended to use public domain and GPL utilities - * like libmii, mii-diag for MII interface support. - * - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#ifndef IxEthMii_H -#define IxEthMii_H - -#include - -/** - * @defgroup IxEthMii IXP400 Ethernet Phy Access (IxEthMii) API - * - * @brief ethMii is a library that does provides access to the - * Ethernet PHYs - * - *@{ - */ - -/** - * @ingroup IxEthMii - * - * @fn ixEthMiiPhyScan(BOOL phyPresent[], UINT32 maxPhyCount) - * - * @brief Scan the MDIO bus for PHYs - * This function scans PHY addresses 0 through 31, and sets phyPresent[n] to - * TRUE if a phy is discovered at address n. - * - * - Reentrant - no - * - ISR Callable - no - * - * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock. - * - * @param phyPresent BOOL [in] - boolean array of IXP425_ETH_ACC_MII_MAX_ADDR entries - * @param maxPhyCount UINT32 [in] - number of PHYs to search for (the scan will stop when - * the indicated number of PHYs is found). - * - * @return IX_STATUS - * - IX_ETH_ACC_SUCCESS - * - IX_ETH_ACC_FAIL : invalid arguments. - * - *
- */ -PUBLIC IX_STATUS ixEthMiiPhyScan(BOOL phyPresent[], UINT32 maxPhyCount); - -/** - * @ingroup IxEthMii - * - * @fn ixEthMiiPhyConfig(UINT32 phyAddr, - BOOL speed100, - BOOL fullDuplex, - BOOL autonegotiate) - * - * - * @brief Configure a PHY - * Configure a PHY's speed, duplex and autonegotiation status - * - * - Reentrant - no - * - ISR Callable - no - * - * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock. - * - * @param phyAddr UINT32 [in] - * @param speed100 BOOL [in] - set to TRUE for 100Mbit/s operation, FALSE for 10Mbit/s - * @param fullDuplex BOOL [in] - set to TRUE for Full Duplex, FALSE for Half Duplex - * @param autonegotiate BOOL [in] - set to TRUE to enable autonegotiation - * - * @return IX_STATUS - * - IX_SUCCESS - * - IX_FAIL : invalid arguments. - * - *
- */ -PUBLIC IX_STATUS ixEthMiiPhyConfig(UINT32 phyAddr, - BOOL speed100, - BOOL fullDuplex, - BOOL autonegotiate); - -/** - * @ingroup IxEthMii - * - * @fn ixEthMiiPhyLoopbackEnable(UINT32 phyAddr) - * - * - * @brief Enable PHY Loopback in a specific Eth MII port - * - * @note When PHY Loopback is enabled, frames sent out to the PHY from the - * IXP400 will be looped back to the IXP400. They will not be transmitted out - * on the wire. - * - * - Reentrant - no - * - ISR Callable - no - * - * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31) - * - * @return IX_STATUS - * - IX_SUCCESS - * - IX_FAIL : invalid arguments. - *
- */ -PUBLIC IX_STATUS -ixEthMiiPhyLoopbackEnable (UINT32 phyAddr); - -/** - * @ingroup IxEthMii - * - * @fn ixEthMiiPhyLoopbackDisable(UINT32 phyAddr) - * - * - * @brief Disable PHY Loopback in a specific Eth MII port - * - * - Reentrant - no - * - ISR Callable - no - * - * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31) - * - * @return IX_STATUS - * - IX_SUCCESS - * - IX_FAIL : invalid arguments. - *
- */ -PUBLIC IX_STATUS -ixEthMiiPhyLoopbackDisable (UINT32 phyAddr); - -/** - * @ingroup IxEthMii - * - * @fn ixEthMiiPhyReset(UINT32 phyAddr) - * - * @brief Reset a PHY - * Reset a PHY - * - * - Reentrant - no - * - ISR Callable - no - * - * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock. - * - * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31) - * - * @return IX_STATUS - * - IX_SUCCESS - * - IX_FAIL : invalid arguments. - * - *
- */ -PUBLIC IX_STATUS ixEthMiiPhyReset(UINT32 phyAddr); - - -/** - * @ingroup IxEthMii - * - * @fn ixEthMiiLinkStatus(UINT32 phyAddr, - BOOL *linkUp, - BOOL *speed100, - BOOL *fullDuplex, - BOOL *autoneg) - * - * @brief Retrieve the current status of a PHY - * Retrieve the link, speed, duplex and autonegotiation status of a PHY - * - * - Reentrant - no - * - ISR Callable - no - * - * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock. - * - * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31) - * @param linkUp BOOL [out] - set to TRUE if the link is up - * @param speed100 BOOL [out] - set to TRUE indicates 100Mbit/s, FALSE indicates 10Mbit/s - * @param fullDuplex BOOL [out] - set to TRUE indicates Full Duplex, FALSE indicates Half Duplex - * @param autoneg BOOL [out] - set to TRUE indicates autonegotiation is enabled, FALSE indicates autonegotiation is disabled - * - * @return IX_STATUS - * - IX_SUCCESS - * - IX_FAIL : invalid arguments. - * - *
- */ -PUBLIC IX_STATUS ixEthMiiLinkStatus(UINT32 phyAddr, - BOOL *linkUp, - BOOL *speed100, - BOOL *fullDuplex, - BOOL *autoneg); - -/** - * @ingroup IxEthMii - * - * @fn ixEthMiiPhyShow (UINT32 phyAddr) - * - * - * @brief Display information on a specified PHY - * Display link status, speed, duplex and Auto Negotiation status - * - * - Reentrant - no - * - ISR Callable - no - * - * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock. - * - * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31) - * - * @return IX_STATUS - * - IX_SUCCESS - * - IX_FAIL : invalid arguments. - * - *
- */ -PUBLIC IX_STATUS ixEthMiiPhyShow (UINT32 phyAddr); - -#endif /* ndef IxEthMii_H */ -/** - *@} - */ diff --git a/cpu/ixp/npe/include/IxEthMii_p.h b/cpu/ixp/npe/include/IxEthMii_p.h deleted file mode 100644 index 104b65c1f0..0000000000 --- a/cpu/ixp/npe/include/IxEthMii_p.h +++ /dev/null @@ -1,185 +0,0 @@ -/** - * @file IxEthMii_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 - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#ifndef IxEthMii_p_H -#define IxEthMii_p_H - - -/* MII definitions - these have been verified against the LXT971 and - LXT972 PHYs*/ - -#define IX_ETH_MII_MAX_REG_NUM 0x20 /* max number of registers */ - -#define IX_ETH_MII_CTRL_REG 0x0 /* Control Register */ -#define IX_ETH_MII_STAT_REG 0x1 /* Status Register */ -#define IX_ETH_MII_PHY_ID1_REG 0x2 /* PHY identifier 1 Register */ -#define IX_ETH_MII_PHY_ID2_REG 0x3 /* PHY identifier 2 Register */ -#define IX_ETH_MII_AN_ADS_REG 0x4 /* Auto-Negotiation */ - /* Advertisement Register */ -#define IX_ETH_MII_AN_PRTN_REG 0x5 /* Auto-Negotiation */ - /* partner ability Register */ -#define IX_ETH_MII_AN_EXP_REG 0x6 /* Auto-Negotiation */ - /* Expansion Register */ -#define IX_ETH_MII_AN_NEXT_REG 0x7 /* Auto-Negotiation */ - /* next-page transmit Register */ - -#define IX_ETH_MII_STAT2_REG 0x11 /* Status Register 2*/ - - -/* MII control register bit */ - -#define IX_ETH_MII_CR_COLL_TEST 0x0080 /* collision test */ -#define IX_ETH_MII_CR_FDX 0x0100 /* FDX =1, half duplex =0 */ -#define IX_ETH_MII_CR_RESTART 0x0200 /* restart auto negotiation */ -#define IX_ETH_MII_CR_ISOLATE 0x0400 /* isolate PHY from MII */ -#define IX_ETH_MII_CR_POWER_DOWN 0x0800 /* power down */ -#define IX_ETH_MII_CR_AUTO_EN 0x1000 /* auto-negotiation enable */ -#define IX_ETH_MII_CR_100 0x2000 /* 0 = 10mb, 1 = 100mb */ -#define IX_ETH_MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */ -#define IX_ETH_MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */ -#define IX_ETH_MII_CR_NORM_EN 0x0000 /* just enable the PHY */ -#define IX_ETH_MII_CR_DEF_0_MASK 0xca7f /* they must return zero */ -#define IX_ETH_MII_CR_RES_MASK 0x007f /* reserved bits, return zero */ - -/* MII Status register bit definitions */ - -#define IX_ETH_MII_SR_LINK_STATUS 0x0004 /* link Status -- 1 = link */ -#define IX_ETH_MII_SR_AUTO_SEL 0x0008 /* auto speed select capable */ -#define IX_ETH_MII_SR_REMOTE_FAULT 0x0010 /* Remote fault detect */ -#define IX_ETH_MII_SR_AUTO_NEG 0x0020 /* auto negotiation complete */ -#define IX_ETH_MII_SR_10T_HALF_DPX 0x0800 /* 10BaseT HD capable */ -#define IX_ETH_MII_SR_10T_FULL_DPX 0x1000 /* 10BaseT FD capable */ -#define IX_ETH_MII_SR_TX_HALF_DPX 0x2000 /* TX HD capable */ -#define IX_ETH_MII_SR_TX_FULL_DPX 0x4000 /* TX FD capable */ -#define IX_ETH_MII_SR_T4 0x8000 /* T4 capable */ -#define IX_ETH_MII_SR_ABIL_MASK 0xff80 /* abilities mask */ -#define IX_ETH_MII_SR_EXT_CAP 0x0001 /* extended capabilities */ - - -/* LXT971/2 Status 2 register bit definitions */ -#define IX_ETH_MII_SR2_100 0x4000 -#define IX_ETH_MII_SR2_TX 0x2000 -#define IX_ETH_MII_SR2_RX 0x1000 -#define IX_ETH_MII_SR2_COL 0x0800 -#define IX_ETH_MII_SR2_LINK 0x0400 -#define IX_ETH_MII_SR2_FD 0x0200 -#define IX_ETH_MII_SR2_AUTO 0x0100 -#define IX_ETH_MII_SR2_AUTO_CMPLT 0x0080 -#define IX_ETH_MII_SR2_POLARITY 0x0020 -#define IX_ETH_MII_SR2_PAUSE 0x0010 -#define IX_ETH_MII_SR2_ERROR 0x0008 - -/* MII Link Code word bit definitions */ - -#define IX_ETH_MII_BP_FAULT 0x2000 /* remote fault */ -#define IX_ETH_MII_BP_ACK 0x4000 /* acknowledge */ -#define IX_ETH_MII_BP_NP 0x8000 /* nexp page is supported */ - -/* MII Next Page bit definitions */ - -#define IX_ETH_MII_NP_TOGGLE 0x0800 /* toggle bit */ -#define IX_ETH_MII_NP_ACK2 0x1000 /* acknowledge two */ -#define IX_ETH_MII_NP_MSG 0x2000 /* message page */ -#define IX_ETH_MII_NP_ACK1 0x4000 /* acknowledge one */ -#define IX_ETH_MII_NP_NP 0x8000 /* nexp page will follow */ - -/* MII Expansion Register bit definitions */ - -#define IX_ETH_MII_EXP_FAULT 0x0010 /* parallel detection fault */ -#define IX_ETH_MII_EXP_PRTN_NP 0x0008 /* link partner next-page able */ -#define IX_ETH_MII_EXP_LOC_NP 0x0004 /* local PHY next-page able */ -#define IX_ETH_MII_EXP_PR 0x0002 /* full page received */ -#define IX_ETH_MII_EXP_PRT_AN 0x0001 /* link partner auto neg able */ - -/* technology ability field bit definitions */ - -#define IX_ETH_MII_TECH_10BASE_T 0x0020 /* 10Base-T */ -#define IX_ETH_MII_TECH_10BASE_FD 0x0040 /* 10Base-T Full Duplex */ -#define IX_ETH_MII_TECH_100BASE_TX 0x0080 /* 100Base-TX */ -#define IX_ETH_MII_TECH_100BASE_TX_FD 0x0100 /* 100Base-TX Full Duplex */ - -#define IX_ETH_MII_TECH_100BASE_T4 0x0200 /* 100Base-T4 */ -#define IX_ETH_MII_ADS_TECH_MASK 0x1fe0 /* technology abilities mask */ -#define IX_ETH_MII_TECH_MASK IX_ETH_MII_ADS_TECH_MASK -#define IX_ETH_MII_ADS_SEL_MASK 0x001f /* selector field mask */ - -#define IX_ETH_MII_AN_FAIL 0x10 /* auto-negotiation fail */ -#define IX_ETH_MII_STAT_FAIL 0x20 /* errors in the status register */ -#define IX_ETH_MII_PHY_NO_ABLE 0x40 /* the PHY lacks some abilities */ - -/* Definitions for MII access routines*/ - -#define IX_ETH_MII_GO BIT(31) -#define IX_ETH_MII_WRITE BIT(26) -#define IX_ETH_MII_TIMEOUT_10TH_SECS (5) -#define IX_ETH_MII_10TH_SEC_IN_MILLIS (100) -#define IX_ETH_MII_READ_FAIL BIT(31) - -/* When we reset the PHY we delay for 2 seconds to allow the reset to - complete*/ -#define IX_ETH_MII_RESET_DELAY_MS (2000) -#define IX_ETH_MII_RESET_POLL_MS (50) - -#define IX_ETH_MII_REG_SHL 16 -#define IX_ETH_MII_ADDR_SHL 21 - -/* supported PHYs */ -#define IX_ETH_MII_LXT971_PHY_ID 0x001378E0 -#define IX_ETH_MII_LXT972_PHY_ID 0x001378E2 -#define IX_ETH_MII_LXT973_PHY_ID 0x00137A10 -#define IX_ETH_MII_LXT973A3_PHY_ID 0x00137A11 -#define IX_ETH_MII_KS8995_PHY_ID 0x00221450 -#define IX_ETH_MII_LXT9785_PHY_ID 0x001378FF - - -#define IX_ETH_MII_INVALID_PHY_ID 0x00000000 -#define IX_ETH_MII_UNKNOWN_PHY_ID 0xffffffff - -#endif /*IxEthAccMii_p_H*/ diff --git a/cpu/ixp/npe/include/IxEthNpe.h b/cpu/ixp/npe/include/IxEthNpe.h deleted file mode 100644 index 21bdedc5a7..0000000000 --- a/cpu/ixp/npe/include/IxEthNpe.h +++ /dev/null @@ -1,695 +0,0 @@ -#ifndef __doxygen_HIDE /* This file is not part of the API */ - -/** - * @file IxEthNpe.h - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- -*/ - -/** - * @defgroup IxEthNpe IXP400 Ethernet NPE (IxEthNpe) API - * - * @brief Contains the API for Ethernet NPE. - * - * All messages given to NPE, get back an acknowledgment. The acknowledgment - * is identical to the message sent to the NPE (except for NPE_GETSTATUS message). - * - * @{ - */ - - -/*-------------------------------------------------------------------------- - * APB Message IDs - XScale->NPE - *------------------------------------------------------------------------*/ - -/** - * @def IX_ETHNPE_NPE_GETSTATUS - * - * @brief Request from the XScale client for the NPE to return the firmware - * version of the currently executing image. - * - * Acknowledgment message id is same as the request message id. - * NPE returns the firmware version ID to XScale. - */ -#define IX_ETHNPE_NPE_GETSTATUS 0x00 - -/** - * @def IX_ETHNPE_EDB_SETPORTADDRESS - * - * @brief Request from the XScale client for the NPE to set the Ethernet - * port's port ID and MAC address. - */ -#define IX_ETHNPE_EDB_SETPORTADDRESS 0x01 - -/** - * @def IX_ETHNPE_EDB_GETMACADDRESSDATABASE - * - * @brief Request from XScale client to the NPE requesting upload of - * Ethernet Filtering Database or Header Conversion Database from NPE's - * data memory to XScale accessible SDRAM. - */ -#define IX_ETHNPE_EDB_GETMACADDRESSDATABASE 0x02 - -/** - * @def IX_ETHNPE_EDB_SETMACADDRESSSDATABASE - * - * @brief Request from XScale client to the NPE requesting download of - * Ethernet Filtering Database or Header Conversion Database from SDRAM - * to the NPE's datamemory. - */ -#define IX_ETHNPE_EDB_SETMACADDRESSSDATABASE 0x03 - -/** - * @def IX_ETHNPE_GETSTATS - * - * @brief Request from the XScale client for the current MAC port statistics - * data to be written to the (empty) statistics structure and the specified - * location in externa memory. - */ -#define IX_ETHNPE_GETSTATS 0x04 - -/** - * @def IX_ETHNPE_RESETSTATS - * - * @brief Request from the XScale client to the NPE to reset all of its internal - * MAC port statistics state variables. - * - * As a side effect, this message entails an implicit request that the NPE - * write the current MAC port statistics into the MAC statistics structure - * at the specified location in external memory. - */ -#define IX_ETHNPE_RESETSTATS 0x05 - -/** - * @def IX_ETHNPE_SETMAXFRAMELENGTHS - * - * @brief Request from the XScale client to the NPE to configure maximum framelengths - * and block sizes in receive and transmit direction. - */ -#define IX_ETHNPE_SETMAXFRAMELENGTHS 0x06 - -/** - * @def IX_ETHNPE_VLAN_SETRXTAGMODE - * - * @brief Request from the XScale client to the NPE to configure VLAN frame type - * filtering and VLAN the tagging mode for the receiver. - */ -#define IX_ETHNPE_VLAN_SETRXTAGMODE 0x07 - -/** - * @def IX_ETHNPE_VLAN_SETDEFAULTRXVID - * - * @brief Request from the XScale client to the NPE to set receiver's default - * VLAN tag (PVID)and internal traffic class. - */ -#define IX_ETHNPE_VLAN_SETDEFAULTRXVID 0x08 - -/** - * @def IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY - * - * @brief Request from the XScale client to the NPE to configure VLAN Port - * membership and Tx tagging for 8 consecutive VLANID's. - */ -#define IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY 0x09 - -/** - * @def IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE - * - * @brief Request from the XScale client to the NPE to configure VLAN Port - * membership and Tx tagging for a range of VLANID's. - */ -#define IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE 0x0A - -/** - * @def IX_ETHNPE_VLAN_SETRXQOSENTRY - * - * @brief Request from the XScale client to the NPE to map a user priority - * to QoS class and an AQM queue number. - */ -#define IX_ETHNPE_VLAN_SETRXQOSENTRY 0x0B - -/** - * @def IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE - * - * @brief Request from the XScale client to the NPE to enable or disable - * portID extraction from VLAN-tagged frames for the specified port. - */ -#define IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE 0x0C - -/** - * @def IX_ETHNPE_STP_SETBLOCKINGSTATE - * - * @brief Request from the XScale client to the NPE to block or unblock - * forwarding for spanning tree BPDUs. - */ -#define IX_ETHNPE_STP_SETBLOCKINGSTATE 0x0D - -/** - * @def IX_ETHNPE_FW_SETFIREWALLMODE - * - * @brief Request from the XScale client to the NPE to configure firewall - * services modes of operation and/or download Ethernet Firewall Database from - * SDRAM to NPE. - */ -#define IX_ETHNPE_FW_SETFIREWALLMODE 0x0E - -/** - * @def IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID - * - * @brief Request from the XScale client to the NPE to set global frame control - * and duration/ID field for the 802.3 to 802.11 protocol header conversion - * service. - */ -#define IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID 0x0F - -/** - * @def IX_ETHNPE_PC_SETBBSID - * - * @brief Request from the XScale client to the NPE to set global BBSID field - * value for the 802.3 to 802.11 protocol header conversion service. - */ -#define IX_ETHNPE_PC_SETBBSID 0x10 - -/** - * @def IX_ETHNPE_PC_SETAPMACTABLE - * - * @brief Request from the XScale client to the NPE to update a block/section/ - * range of the AP MAC Address Table. - */ -#define IX_ETHNPE_PC_SETAPMACTABLE 0x11 - -/** - * @def IX_ETHNPE_SETLOOPBACK_MODE - * - * @brief Turn on or off the NPE frame loopback. - */ -#define IX_ETHNPE_SETLOOPBACK_MODE (0x12) - -/*-------------------------------------------------------------------------- - * APB Message IDs - NPE->XScale - *------------------------------------------------------------------------*/ - -/** - * @def IX_ETHNPE_NPE_GETSTATUS_ACK - * - * @brief Acknowledgment to IX_ETHNPE_NPE_GETSTATUS message. NPE firmware version - * id is returned in the message. - */ -#define IX_ETHNPE_NPE_GETSTATUS_ACK 0x00 - -/** - * @def IX_ETHNPE_EDB_SETPORTADDRESS_ACK - * - * @brief Acknowledgment to IX_ETHNPE_EDB_SETPORTADDRESS message. - */ -#define IX_ETHNPE_EDB_SETPORTADDRESS_ACK 0x01 - -/** - * @def IX_ETHNPE_EDB_GETMACADDRESSDATABASE_ACK - * - * @brief Acknowledgment to IX_ETHNPE_EDB_GETMACADDRESSDATABASE message - */ -#define IX_ETHNPE_EDB_GETMACADDRESSDATABASE_ACK 0x02 - -/** - * @def IX_ETHNPE_EDB_SETMACADDRESSSDATABASE_ACK - * - * @brief Acknowledgment to IX_ETHNPE_EDB_SETMACADDRESSSDATABASE message. - */ -#define IX_ETHNPE_EDB_SETMACADDRESSSDATABASE_ACK 0x03 - -/** - * @def IX_ETHNPE_GETSTATS_ACK - * - * @brief Acknowledgment to IX_ETHNPE_GETSTATS message. - */ -#define IX_ETHNPE_GETSTATS_ACK 0x04 - -/** - * @def IX_ETHNPE_RESETSTATS_ACK - * - * @brief Acknowledgment to IX_ETHNPE_RESETSTATS message. - */ -#define IX_ETHNPE_RESETSTATS_ACK 0x05 - -/** - * @def IX_ETHNPE_SETMAXFRAMELENGTHS_ACK - * - * @brief Acknowledgment to IX_ETHNPE_SETMAXFRAMELENGTHS message. - */ -#define IX_ETHNPE_SETMAXFRAMELENGTHS_ACK 0x06 - -/** - * @def IX_ETHNPE_VLAN_SETRXTAGMODE_ACK - * - * @brief Acknowledgment to IX_ETHNPE_VLAN_SETRXTAGMODE message. - */ -#define IX_ETHNPE_VLAN_SETRXTAGMODE_ACK 0x07 - -/** - * @def IX_ETHNPE_VLAN_SETDEFAULTRXVID_ACK - * - * @brief Acknowledgment to IX_ETHNPE_VLAN_SETDEFAULTRXVID message. - */ -#define IX_ETHNPE_VLAN_SETDEFAULTRXVID_ACK 0x08 - -/** - * @def IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY_ACK - * - * @brief Acknowledgment to IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY message. - */ -#define IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY_ACK 0x09 - -/** - * @def IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE_ACK - * - * @brief Acknowledgment to IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE message. - */ -#define IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE_ACK 0x0A - -/** - * @def IX_ETHNPE_VLAN_SETRXQOSENTRY_ACK - * - * @brief Acknowledgment to IX_ETHNPE_VLAN_SETRXQOSENTRY message. - */ -#define IX_ETHNPE_VLAN_SETRXQOSENTRY_ACK 0x0B - -/** - * @def IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE_ACK - * - * @brief Acknowledgment to IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE message. - */ -#define IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE_ACK 0x0C - -/** - * @def IX_ETHNPE_STP_SETBLOCKINGSTATE_ACK - * - * @brief Acknowledgment to IX_ETHNPE_STP_SETBLOCKINGSTATE message. - */ -#define IX_ETHNPE_STP_SETBLOCKINGSTATE_ACK 0x0D - -/** - * @def IX_ETHNPE_FW_SETFIREWALLMODE_ACK - * - * @brief Acknowledgment to IX_ETHNPE_FW_SETFIREWALLMODE message. - */ -#define IX_ETHNPE_FW_SETFIREWALLMODE_ACK 0x0E - -/** - * @def IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID_ACK - * - * @brief Acknowledgment to IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID message. - */ -#define IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID_ACK 0x0F - -/** - * @def IX_ETHNPE_PC_SETBBSID_ACK - * - * @brief Acknowledgment to IX_ETHNPE_PC_SETBBSID message. - */ -#define IX_ETHNPE_PC_SETBBSID_ACK 0x10 - -/** - * @def IX_ETHNPE_PC_SETAPMACTABLE_ACK - * - * @brief Acknowledgment to IX_ETHNPE_PC_SETAPMACTABLE message. - */ -#define IX_ETHNPE_PC_SETAPMACTABLE_ACK 0x11 - -/** - * @def IX_ETHNPE_SETLOOPBACK_MODE_ACK - * - * @brief Acknowledgment to IX_ETHNPE_SETLOOPBACK_MODE message. - */ -#define IX_ETHNPE_SETLOOPBACK_MODE_ACK (0x12) - -/*-------------------------------------------------------------------------- - * Queue Manager Queue entry bit field boundary definitions - *------------------------------------------------------------------------*/ - -/** - * @def MASK(hi,lo) - * - * @brief Macro for mask - */ -#define MASK(hi,lo) (((1 << (1 + ((hi) - (lo)))) - 1) << (lo)) - -/** - * @def BITS(x,hi,lo) - * - * @brief Macro for bits - */ -#define BITS(x,hi,lo) (((x) & MASK(hi,lo)) >> (lo)) - -/** - * @def IX_ETHNPE_QM_Q_RXENET_LENGTH_MASK - * - * @brief QMgr Queue LENGTH field mask - */ -#define IX_ETHNPE_QM_Q_RXENET_LENGTH_MASK 0x3fff - -/** - * @def IX_ETHNPE_QM_Q_FIELD_FLAG_R - * - * @brief QMgr Queue FLAG field right boundary - */ -#define IX_ETHNPE_QM_Q_FIELD_FLAG_R 20 - -/** - * @def IX_ETHNPE_QM_Q_FIELD_FLAG_MASK - * - * @brief QMgr Queue FLAG field mask - * - * Multicast bit : BIT(4) - * Broadcast bit : BIT(5) - * IP bit : BIT(6) (linux only) - * - */ -#ifdef __vxworks -#define IX_ETHNPE_QM_Q_FIELD_FLAG_MASK 0x30 -#else -#define IX_ETHNPE_QM_Q_FIELD_FLAG_MASK 0x70 -#endif - - -/** - * @def IX_ETHNPE_QM_Q_FIELD_NPEID_L - * - * @brief QMgr Queue NPE ID field left boundary - */ -#define IX_ETHNPE_QM_Q_FIELD_NPEID_L 1 - -/** - * @def IX_ETHNPE_QM_Q_FIELD_NPEID_R - * - * @brief QMgr Queue NPE ID field right boundary - */ -#define IX_ETHNPE_QM_Q_FIELD_NPEID_R 0 - -/** - * @def IX_ETHNPE_QM_Q_FIELD_PRIOR_L - * - * @brief QMgr Queue Priority field left boundary - */ -#define IX_ETHNPE_QM_Q_FIELD_PRIOR_L 2 - -/** - * @def IX_ETHNPE_QM_Q_FIELD_PRIOR_R - * - * @brief QMgr Queue Priority field right boundary - */ -#define IX_ETHNPE_QM_Q_FIELD_PRIOR_R 0 - -/** - * @def IX_ETHNPE_QM_Q_FIELD_ADDR_L - * - * @brief QMgr Queue Address field left boundary - */ -#define IX_ETHNPE_QM_Q_FIELD_ADDR_L 31 - -/** - * @def IX_ETHNPE_QM_Q_FIELD_ADDR_R - * - * @brief QMgr Queue Address field right boundary - */ -#define IX_ETHNPE_QM_Q_FIELD_ADDR_R 5 - -/*-------------------------------------------------------------------------- - * Queue Manager Queue entry bit field masks - *------------------------------------------------------------------------*/ - -/** - * @def IX_ETHNPE_QM_Q_FREEENET_ADDR_MASK - * - * @brief Macro to mask the Address field of the FreeEnet Queue Manager Entry - */ -#define IX_ETHNPE_QM_Q_FREEENET_ADDR_MASK \ - MASK (IX_ETHNPE_QM_Q_FIELD_ADDR_L, \ - IX_ETHNPE_QM_Q_FIELD_ADDR_R) - -/** - * @def IX_ETHNPE_QM_Q_RXENET_NPEID_MASK - * - * @brief Macro to mask the NPE ID field of the RxEnet Queue Manager Entry - */ -#define IX_ETHNPE_QM_Q_RXENET_NPEID_MASK \ - MASK (IX_ETHNPE_QM_Q_FIELD_NPEID_L, \ - IX_ETHNPE_QM_Q_FIELD_NPEID_R) - -/** - * @def IX_ETHNPE_QM_Q_RXENET_ADDR_MASK - * - * @brief Macro to mask the Mbuf Address field of the RxEnet Queue Manager Entry - */ -#define IX_ETHNPE_QM_Q_RXENET_ADDR_MASK \ - MASK (IX_ETHNPE_QM_Q_FIELD_ADDR_L, \ - IX_ETHNPE_QM_Q_FIELD_ADDR_R) - -/** - * @def IX_ETHNPE_QM_Q_TXENET_PRIOR_MASK - * - * @brief Macro to mask the Priority field of the TxEnet Queue Manager Entry - */ -#define IX_ETHNPE_QM_Q_TXENET_PRIOR_MASK \ - MASK (IX_ETHNPE_QM_Q_FIELD_PRIOR_L, \ - IX_ETHNPE_QM_Q_FIELD_PRIOR_R) - -/** - * @def IX_ETHNPE_QM_Q_TXENET_ADDR_MASK - * - * @brief Macro to mask the Mbuf Address field of the TxEnet Queue Manager Entry - */ -#define IX_ETHNPE_QM_Q_TXENET_ADDR_MASK \ - MASK (IX_ETHNPE_QM_Q_FIELD_ADDR_L, \ - IX_ETHNPE_QM_Q_FIELD_ADDR_R) - -/** - * @def IX_ETHNPE_QM_Q_TXENETDONE_NPEID_MASK - * - * @brief Macro to mask the NPE ID field of the TxEnetDone Queue Manager Entry - */ -#define IX_ETHNPE_QM_Q_TXENETDONE_NPEID_MASK \ - MASK (IX_ETHNPE_QM_Q_FIELD_NPEID_L, \ - IX_ETHNPE_QM_Q_FIELD_NPEID_R) - -/** - * @def IX_ETHNPE_QM_Q_TXENETDONE_ADDR_MASK - * - * @brief Macro to mask the Mbuf Address field of the TxEnetDone Queue Manager - * Entry - */ -#define IX_ETHNPE_QM_Q_TXENETDONE_ADDR_MASK \ - MASK (IX_ETHNPE_QM_Q_FIELD_ADDR_L, \ - IX_ETHNPE_QM_Q_FIELD_ADDR_R) - -/*-------------------------------------------------------------------------- - * Queue Manager Queue entry bit field value extraction macros - *------------------------------------------------------------------------*/ - -/** - * @def IX_ETHNPE_QM_Q_FREEENET_ADDR_VAL(x) - * - * @brief Extraction macro for Address field of FreeNet Queue Manager Entry - * - * Pointer to an mbuf buffer descriptor - */ -#define IX_ETHNPE_QM_Q_FREEENET_ADDR_VAL(x) \ - ((x) & IX_ETHNPE_QM_Q_FREEENET_ADDR_MASK) - -/** - * @def IX_ETHNPE_QM_Q_RXENET_NPEID_VAL(x) - * - * @brief Extraction macro for NPE ID field of RxEnet Queue Manager Entry - * - * Set to 0 for entries originating from the Eth0 NPE; - * Set to 1 for entries originating from the Eth1 NPE. - */ -#define IX_ETHNPE_QM_Q_RXENET_NPEID_VAL(x) \ - BITS (x, IX_ETHNPE_QM_Q_FIELD_NPEID_L, \ - IX_ETHNPE_QM_Q_FIELD_NPEID_R) - -/** - * @def IX_ETHNPE_QM_Q_RXENET_PORTID_VAL(x) - * - * @brief Extraction macro for Port ID field of RxEnet Queue Manager Entry - * - * 0-5: Assignable (by the XScale client) to any of the physical ports. - * 6: It is reserved - * 7: Indication that the NPE did not find the associated frame's destination MAC address within - * its internal filtering database. - */ -#define IX_ETHNPE_QM_Q_RXENET_PORTID_VAL(x) \ - BITS (x, IX_ETHNPE_QM_Q_FIELD_PORTID_L, \ - IX_ETHNPE_QM_Q_Field_PortID_R) - -/** - * @def IX_ETHNPE_QM_Q_RXENET_ADDR_VAL(x) - * - * @brief Extraction macro for Address field of RxEnet Queue Manager Entry - * - * Pointer to an mbuf buffer descriptor - */ -#define IX_ETHNPE_QM_Q_RXENET_ADDR_VAL(x) \ - ((x) & IX_ETHNPE_QM_Q_RXENET_ADDR_MASK) - -/** - * @def IX_ETHNPE_QM_Q_TXENET_PRIOR_VAL(x) - * - * @brief Extraction macro for Priority field of TxEnet Queue Manager Entry - * - * Priority of the packet (as described in IEEE 802.1D). This field is - * cleared upon return from the Ethernet NPE to the TxEnetDone queue. - */ -#define IX_ETHNPE_QM_Q_TXENET_PRIOR_VAL(x) \ - BITS (x, IX_ETHNPE_QM_Q_FIELD_PRIOR_L, \ - IX_ETHNPE_QM_Q_FIELD_PRIOR_R) - -/** - * @def IX_ETHNPE_QM_Q_TXENET_ADDR_VAL(x) - * - * @brief Extraction macro for Address field of Queue Manager TxEnet Queue - * Manager Entry - * - * Pointer to an mbuf buffer descriptor - */ -#define IX_ETHNPE_QM_Q_TXENET_ADDR_VAL(x) \ - ((x) & IX_ETHNPE_QM_Q_TXENET_ADDR_MASK) - -/** - * @def IX_ETHNPE_QM_Q_TXENETDONE_NPEID_VAL(x) - * - * @brief Extraction macro for NPE ID field of TxEnetDone Queue Manager Entry - * - * Set to 0 for entries originating from the Eth0 NPE; set to 1 for en-tries - * originating from the Eth1 NPE. - */ -#define IX_ETHNPE_QM_Q_TXENETDONE_NPEID_VAL(x) \ - BITS (x, IX_ETHNPE_QM_Q_FIELD_NPEID_L, \ - IX_ETHNPE_QM_Q_FIELD_NPEID_R) - -/** - * @def IX_ETHNPE_QM_Q_TXENETDONE_ADDR_VAL(x) - * - * @brief Extraction macro for Address field of TxEnetDone Queue Manager Entry - * - * Pointer to an mbuf buffer descriptor - */ -#define IX_ETHNPE_QM_Q_TXENETDONE_ADDR_VAL(x) \ - ((x) & IX_ETHNPE_QM_Q_TXENETDONE_ADDR_MASK) - - -/*-------------------------------------------------------------------------- - * NPE limits - *------------------------------------------------------------------------*/ - -/** - * @def IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN - * - * @brief Macro to check the minimum length of a rx free buffer - */ -#define IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN (64) - -/** - * @def IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MASK - * - * @brief Mask to apply to the mbuf length before submitting it to the NPE - * (the NPE handles only rx free mbufs which are multiple of 64) - * - * @sa IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MASK - */ -#define IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MASK (~63) - -/** - * @def IX_ETHNPE_ACC_RXFREE_BUFFER_ROUND_UP(size) - * - * @brief Round up to get the size necessary to receive without chaining - * the frames which are (size) bytes (the NPE operates by multiple of 64) - * e.g. To receive 1514 bytes frames, the size of the buffers in replenish - * has to be at least (1514+63)&(~63) = 1536 bytes. - * - */ -#define IX_ETHNPE_ACC_RXFREE_BUFFER_ROUND_UP(size) (((size) + 63) & ~63) - -/** - * @def IX_ETHNPE_ACC_RXFREE_BUFFER_ROUND_DOWN(size) - * - * @brief Round down to apply to the mbuf length before submitting - * it to the NPE. (the NPE operates by multiple of 64) - * - */ -#define IX_ETHNPE_ACC_RXFREE_BUFFER_ROUND_DOWN(size) ((size) & ~63) - -/** - * @def IX_ETHNPE_ACC_FRAME_LENGTH_MAX - * - * @brief maximum mbuf length supported by the NPE - * - * @sa IX_ETHNPE_ACC_FRAME_LENGTH_MAX - */ -#define IX_ETHNPE_ACC_FRAME_LENGTH_MAX (16320) - -/** - * @def IX_ETHNPE_ACC_FRAME_LENGTH_DEFAULT - * - * @brief default mbuf length supported by the NPE - * - * @sa IX_ETHNPE_ACC_FRAME_LENGTH_DEFAULT - */ -#define IX_ETHNPE_ACC_FRAME_LENGTH_DEFAULT (1522) - -/** - * @def IX_ETHNPE_ACC_LENGTH_OFFSET - * - * @brief Offset of the cluster length field in the word shared with the NPEs - */ -#define IX_ETHNPE_ACC_LENGTH_OFFSET 16 - -/** - * @def IX_ETHNPE_ACC_PKTLENGTH_MASK - * - * @brief Mask of the cluster length field in the word shared with the NPEs - */ -#define IX_ETHNPE_ACC_PKTLENGTH_MASK 0x3fff - - -/** - *@} - */ - -#endif /* __doxygen_HIDE */ diff --git a/cpu/ixp/npe/include/IxFeatureCtrl.h b/cpu/ixp/npe/include/IxFeatureCtrl.h deleted file mode 100644 index dabc38e25e..0000000000 --- a/cpu/ixp/npe/include/IxFeatureCtrl.h +++ /dev/null @@ -1,742 +0,0 @@ -/** - * @file IxFeatureCtrl.h - * - * @date 30-Jan-2003 - - * @brief This file contains the public API of the IXP400 Feature Control - * component. - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- -*/ -/* ------------------------------------------------------ - Doxygen group definitions - ------------------------------------------------------ */ -/** - * @defgroup IxFeatureCtrlAPI IXP400 Feature Control (IxFeatureCtrl) API - * - * @brief The Public API for the IXP400 Feature Control. - * - * @{ - */ - -#ifndef IXFEATURECTRL_H -#define IXFEATURECTRL_H - -/* - * User defined include files - */ -#include "IxOsal.h" - -/* - * #defines and macros - */ - -/************************************************************* - * The following are IxFeatureCtrlComponentCheck return values. - ************************************************************/ - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURE_CTRL_COMPONENT_DISABLED - * - * @brief Hardware Component is disabled/unavailable. - * Return status by ixFeatureCtrlComponentCheck() - */ -#define IX_FEATURE_CTRL_COMPONENT_DISABLED 0 - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURE_CTRL_COMPONENT_ENABLED - * - * @brief Hardware Component is available. - * Return status by ixFeatureCtrlComponentCheck() - */ -#define IX_FEATURE_CTRL_COMPONENT_ENABLED 1 - -/*********************************************************************************** - * Product ID in XScale CP15 - Register 0 - * - It contains information on the maximum XScale Core Frequency and - * Silicon Stepping. - * - XScale Core Frequency Id indicates only the maximum XScale frequency - * achievable and not the running XScale frequency (maybe stepped down). - * - The register is read by using ixFeatureCtrlProductIdRead. - * - Usage example: - * productId = ixFeatureCtrlProductIdRead(); - * if( (productId & IX_FEATURE_CTRL_SILICON_STEPPING_MASK) == - * IX_FEATURE_CTRL_SILICON_TYPE_A0 ) - * if( (productId & IX_FEATURE_CTRL_XSCALE_FREQ_MASK) == - * IX_FEATURE_CTRL_XSCALE_FREQ_533 ) - * - * 31 28 27 24 23 20 19 16 15 12 11 9 8 4 3 0 - * -------------------------------------------------------------------------------- - * | 0x6 | 0x9 | 0x0 | 0x5 | 0x4 | Device ID | XScale Core Freq Id | Si Stepping Id | - * -------------------------------------------------------------------------------- - * - * Maximum Achievable XScale Core Frequency Id : 533MHz - 0x1C - * 400MHz - 0x1D - * 266MHz - 0x1F - * - * THE CORE FREQUENCY ID IS NOT APPLICABLE TO IXP46X <\b> - * - * The above is applicable to IXP42X only. CP15 in IXP46X does not contain any - * Frequency ID. - * - * Si Stepping Id : A - 0x0 - * B - 0x1 - * - * XScale Core freq Id - Device ID [11:9] : IXP42X - 0x0 - * IXP46X - 0x1 - *************************************************************************************/ - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURE_CTRL_SILICON_TYPE_A0 - * - * @brief This is the value of A0 Silicon in product ID. - */ -#define IX_FEATURE_CTRL_SILICON_TYPE_A0 0 - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURE_CTRL_SILICON_TYPE_B0 - * - * @brief This is the value of B0 Silicon in product ID. - */ -#define IX_FEATURE_CTRL_SILICON_TYPE_B0 1 - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURE_CTRL_SILICON_STEPPING_MASK - * - * @brief This is the mask of silicon stepping in product ID. - */ -#define IX_FEATURE_CTRL_SILICON_STEPPING_MASK 0xF - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURE_CTRL_DEVICE_TYPE_MASK - * - * @brief This is the mask of silicon stepping in product ID. - */ -#define IX_FEATURE_CTRL_DEVICE_TYPE_MASK (0x7) - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURE_CTRL_DEVICE_TYPE_OFFSET - * - * @brief This is the mask of silicon stepping in product ID. - */ -#define IX_FEATURE_CTRL_DEVICE_TYPE_OFFSET 9 - - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURE_CTRL_XSCALE_FREQ_533 - * - * @brief This is the value of 533MHz XScale Core in product ID. - */ -#define IX_FEATURE_CTRL_XSCALE_FREQ_533 ((0x1C)<<4) - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURE_CTRL_XSCALE_FREQ_400 - * - * @brief This is the value of 400MHz XScale Core in product ID. - */ -#define IX_FEATURE_CTRL_XSCALE_FREQ_400 ((0x1D)<<4) - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURE_CTRL_XSCALE_FREQ_266 - * - * @brief This is the value of 266MHz XScale Core in product ID. - */ -#define IX_FEATURE_CTRL_XSCALE_FREQ_266 ((0x1F)<<4) - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURE_CTRL_XSCALE_FREQ_MASK - * - * @brief This is the mask of XScale Core in product ID. - */ -#define IX_FEATURE_CTRL_XSCALE_FREQ_MASK ((0xFF)<<4) - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURECTRL_REG_UTOPIA_32PHY - * - * @brief Maximum UTOPIA PHY available is 32. - * - */ -#define IX_FEATURECTRL_REG_UTOPIA_32PHY 0x0 - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURECTRL_REG_UTOPIA_16PHY - * - * @brief Maximum UTOPIA PHY available is 16. - * - */ -#define IX_FEATURECTRL_REG_UTOPIA_16PHY 0x1 - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURECTRL_REG_UTOPIA_8PHY - * - * @brief Maximum UTOPIA PHY available to is 8. - * - */ -#define IX_FEATURECTRL_REG_UTOPIA_8PHY 0x2 - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURECTRL_REG_UTOPIA_4PHY - * - * @brief Maximum UTOPIA PHY available to is 4. - * - */ -#define IX_FEATURECTRL_REG_UTOPIA_4PHY 0x3 - -#ifdef __ixp46X - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURECTRL_REG_XSCALE_533FREQ - * - * @brief Maximum frequency available to IXP46x is 533 MHz. - * - */ -#define IX_FEATURECTRL_REG_XSCALE_533FREQ 0x0 - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURECTRL_REG_XSCALE_667FREQ - * - * @brief Maximum frequency available to IXP46x is 667 MHz. - * - */ -#define IX_FEATURECTRL_REG_XSCALE_667FREQ 0x1 - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURECTRL_REG_XSCALE_400FREQ - * - * @brief Maximum frequency available to IXP46x is 400 MHz. - * - */ -#define IX_FEATURECTRL_REG_XSCALE_400FREQ 0x2 - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURECTRL_REG_XSCALE_266FREQ - * - * @brief Maximum frequency available to IXP46x is 266 MHz. - * - */ -#define IX_FEATURECTRL_REG_XSCALE_266FREQ 0x3 - -#endif /* __ixp46X */ - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE - * - * @brief Component selected is not available for device - * - */ -#define IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE 0x0000 - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURECTRL_COMPONENT_ALWAYS_AVAILABLE - * - * @brief Component selected is not available for device - * - */ -#define IX_FEATURECTRL_COMPONENT_ALWAYS_AVAILABLE 0xffff - -/** - * @defgroup IxFeatureCtrlSwConfig Software Configuration for Access Component - * - * @ingroup IxFeatureCtrlAPI - * - * @brief This section describes software configuration in access component. The - * configuration can be changed at run-time. ixFeatureCtrlSwConfigurationCheck( ) - * will be used across applicable access component to check the configuration. - * ixFeatureCtrlSwConfigurationWrite( ) is used to write the software configuration. - * - * @note All software configurations are default to be enabled. - * - * @{ - */ -/** - * @ingroup IxFeatureCtrlSwConfig - * - * @def IX_FEATURE_CTRL_SWCONFIG_DISABLED - * - * @brief Software configuration is disabled. - * - */ -#define IX_FEATURE_CTRL_SWCONFIG_DISABLED 0 - -/** - * @ingroup IxFeatureCtrlSwConfig - * - * @def IX_FEATURE_CTRL_SWCONFIG_ENABLED - * - * @brief Software configuration is enabled. - * - */ -#define IX_FEATURE_CTRL_SWCONFIG_ENABLED 1 - -/** - * Section for enums - **/ - -/** - * @ingroup IxFeatureCtrlBuildDevice - * - * @enum IxFeatureCtrlBuildDevice - * - * @brief Indicates software build type. - * - * Default build type is IXP42X - * - */ -typedef enum -{ - IX_FEATURE_CTRL_SW_BUILD_IXP42X = 0, /** - * - if(IX_FEATURE_CTRL_COMPONENT_DISABLED != - * ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0))
- * - if(IX_FEATURE_CTRL_COMPONENT_ENABLED == - * ixFeatureCtrlComponentCheck(IX_FEATURECTRL_PCI))
- * - * This function is typically called during component initialization time. - * - * @param componentType @ref IxFeatureCtrlComponentType [in] - the type of a component as - * defined above as IX_FEATURECTRL_XXX (Exp: IX_FEATURECTRL_PCI, IX_FEATURECTRL_ETH0) - - * - * @return - * - IX_FEATURE_CTRL_COMPONENT_ENABLED if component is available - * - IX_FEATURE_CTRL_COMPONENT_DISABLED if component is unavailable - */ -PUBLIC IX_STATUS -ixFeatureCtrlComponentCheck (IxFeatureCtrlComponentType componentType); - -/** - * @ingroup IxFeatureCtrlAPI - * - * @fn IxFeatureCtrlProductId ixFeatureCtrlProductIdRead (void) - * - * @brief This function will return IXP400 product ID i.e. CP15, - * Register 0. - * - * @return - * - IxFeatureCtrlProductId - the value of product ID. - * - */ -PUBLIC IxFeatureCtrlProductId -ixFeatureCtrlProductIdRead (void) ; - -/** - * @ingroup IxFeatureCtrlAPI - * - * @fn IX_STATUS ixFeatureCtrlSwConfigurationCheck (IxFeatureCtrlSwConfig swConfigType) - * - * @brief This function checks whether the specified software configuration is - * enabled or disabled. - * - * Usage Example:
- * - if(IX_FEATURE_CTRL_SWCONFIG_DISABLED != - * ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING))
- * - if(IX_FEATURE_CTRL_SWCONFIG_ENABLED == - * ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING))
- * - * This function is typically called during access component initialization time. - * - * @param swConfigType @ref IxFeatureCtrlSwConfig [in] - the type of a software configuration - * defined in IxFeatureCtrlSwConfig enumeration. - * - * @return - * - IX_FEATURE_CTRL_SWCONFIG_ENABLED if software configuration is enabled. - * - IX_FEATURE_CTRL_SWCONFIG_DISABLED if software configuration is disabled. - */ -PUBLIC IX_STATUS -ixFeatureCtrlSwConfigurationCheck (IxFeatureCtrlSwConfig swConfigType); - -/** - * @ingroup IxFeatureCtrlAPI - * - * @fn void ixFeatureCtrlSwConfigurationWrite (IxFeatureCtrlSwConfig swConfigType, BOOL enabled) - * - * @brief This function enable/disable the specified software configuration. - * - * Usage Example:
- * - ixFeatureCtrlSwConfigurationWrite(IX_FEATURECTRL_ETH_LEARNING, TRUE) is used - * to enable Ethernet Learning Feature
- * - ixFeatureCtrlSwConfigurationWrite(IX_FEATURECTRL_ETH_LEARNING, FALSE) is used - * to disable Ethernet Learning Feature
- * - * @param swConfigType IxFeatureCtrlSwConfig [in] - the type of a software configuration - * defined in IxFeatureCtrlSwConfig enumeration. - * @param enabled BOOL [in] - To enable(TRUE) / disable (FALSE) the specified software - * configuration. - * - * @return none - * - */ -PUBLIC void -ixFeatureCtrlSwConfigurationWrite (IxFeatureCtrlSwConfig swConfigType, BOOL enabled); - -/** - * @ingroup IxFeatureCtrlAPI - * - * @fn void ixFeatureCtrlIxp400SwVersionShow (void) - * - * @brief This function shows the current software release information for IXP400 - * - * @return none - * - */ -PUBLIC void -ixFeatureCtrlIxp400SwVersionShow (void); - -#endif /* IXFEATURECTRL_H */ - -/** - * @} defgroup IxFeatureCtrlAPI - */ diff --git a/cpu/ixp/npe/include/IxHssAcc.h b/cpu/ixp/npe/include/IxHssAcc.h deleted file mode 100644 index 07bb119b0b..0000000000 --- a/cpu/ixp/npe/include/IxHssAcc.h +++ /dev/null @@ -1,1316 +0,0 @@ -/** - * @file IxHssAcc.h - * - * @date 07-DEC-2001 - * - * @brief This file contains the public API of the IXP400 HSS Access - * component - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- -*/ - -/* ------------------------------------------------------ - Doxygen group definitions - ------------------------------------------------------ */ -/** - * @defgroup IxHssAccAPI IXP400 HSS Access (IxHssAcc) API - * - * @brief The public API for the IXP400 HssAccess component - * - * IxHssAcc is the access layer to the HSS packetised and channelised - * services - * - * Design Notes
- *
    - *
  • When a packet-pipe is configured for 56Kbps RAW mode, byte alignment of - * the transmitted data is not preserved. All raw data that is transmitted - * will be received in proper order by the receiver, but the first bit of - * the packet may be seen at any offset within a byte; all subsequent bytes - * will have the same offset for the duration of the packet. The same offset - * also applies to all subsequent packets received on the packet-pipe too. - * (Similar results will occur for data received from remote end.) While - * this behavior will also occur for 56Kbps HDLC mode, the HDLC - * encoding/decoding will preserve the original byte alignment at the - * receiver end. - *
- * - * 56Kbps Packetised Service Bandwidth Limitation
- *
    - *
  • IxHssAcc supports 56Kbps packetised service at a maximum aggregate rate - * for all HSS ports/HDLC channels of 12.288Mbps[1] in each direction, i.e. - * it supports 56Kbps packetised service on up to 8 T1 trunks. It does - * not support 56Kbps packetised service on 8 E1 trunks (i.e. 4 trunks per - * HSS port) unless those trunks are running 'fractional E1' with maximum - * aggregate rate of 12.288 Mbps in each direction.
    - * [1] 12.288Mbps = 1.536Mbp * 8 T1 - *
- * @{ */ - -#ifndef IXHSSACC_H -#define IXHSSACC_H - -#include "IxOsal.h" - -/* - * #defines for function return types, etc. - */ - -/** - * @def IX_HSSACC_TSLOTS_PER_HSS_PORT - * - * @brief The max number of TDM timeslots supported per HSS port - 4E1's = - * 32x4 = 128 - */ -#define IX_HSSACC_TSLOTS_PER_HSS_PORT 128 - -/* ----------------------------------------------------------- - The following are HssAccess return values returned through - service interfaces. The globally defined IX_SUCCESS (0) and - IX_FAIL (1) in IxOsalTypes.h are also used. - ----------------------------------------------------------- */ -/** - * @def IX_HSSACC_PARAM_ERR - * - * @brief HssAccess function return value for a parameter error - */ -#define IX_HSSACC_PARAM_ERR 2 - -/** - * @def IX_HSSACC_RESOURCE_ERR - * - * @brief HssAccess function return value for a resource error - */ -#define IX_HSSACC_RESOURCE_ERR 3 - -/** - * @def IX_HSSACC_PKT_DISCONNECTING - * - * @brief Indicates that a disconnect call is progressing and will - * disconnect soon - */ -#define IX_HSSACC_PKT_DISCONNECTING 4 - -/** - * @def IX_HSSACC_Q_WRITE_OVERFLOW - * - * @brief Indicates that an attempt to Tx or to replenish an - * RxFree Q failed due to Q overflow. - */ -#define IX_HSSACC_Q_WRITE_OVERFLOW 5 - -/* ------------------------------------------------------------------- - The following errors are HSS/NPE errors returned on error retrieval - ------------------------------------------------------------------- */ -/** - * @def IX_HSSACC_NO_ERROR - * - * @brief HSS port no error present - */ -#define IX_HSSACC_NO_ERROR 0 - -/** - * @def IX_HSSACC_TX_FRM_SYNC_ERR - * - * @brief HSS port TX Frame Sync error - */ -#define IX_HSSACC_TX_FRM_SYNC_ERR 1 - -/** - * @def IX_HSSACC_TX_OVER_RUN_ERR - * - * @brief HSS port TX over-run error - */ -#define IX_HSSACC_TX_OVER_RUN_ERR 2 - -/** - * @def IX_HSSACC_CHANNELISED_SW_TX_ERR - * - * @brief NPE software error in channelised TX - */ -#define IX_HSSACC_CHANNELISED_SW_TX_ERR 3 - -/** - * @def IX_HSSACC_PACKETISED_SW_TX_ERR - * - * @brief NPE software error in packetised TX - */ -#define IX_HSSACC_PACKETISED_SW_TX_ERR 4 - -/** - * @def IX_HSSACC_RX_FRM_SYNC_ERR - * - * @brief HSS port RX Frame Sync error - */ -#define IX_HSSACC_RX_FRM_SYNC_ERR 5 - -/** - * @def IX_HSSACC_RX_OVER_RUN_ERR - * - * @brief HSS port RX over-run error - */ -#define IX_HSSACC_RX_OVER_RUN_ERR 6 - -/** - * @def IX_HSSACC_CHANNELISED_SW_RX_ERR - * - * @brief NPE software error in channelised RX - */ -#define IX_HSSACC_CHANNELISED_SW_RX_ERR 7 - -/** - * @def IX_HSSACC_PACKETISED_SW_RX_ERR - * - * @brief NPE software error in packetised TX - */ -#define IX_HSSACC_PACKETISED_SW_RX_ERR 8 - -/* ----------------------------------- - Packetised service specific defines - ----------------------------------- */ - -/** - * @def IX_HSSACC_PKT_MIN_RX_MBUF_SIZE - * - * @brief Minimum size of the Rx mbuf in bytes which the client must supply - * to the component. - */ -#define IX_HSSACC_PKT_MIN_RX_MBUF_SIZE 64 - -/* -------------------------------------------------------------------- - Enumerated Types - these enumerated values may be used in setting up - the contents of hardware registers - -------------------------------------------------------------------- */ -/** - * @enum IxHssAccHssPort - * @brief The HSS port ID - There are two identical ports (0-1). - * - */ -typedef enum -{ - IX_HSSACC_HSS_PORT_0, /**< HSS Port 0 */ - IX_HSSACC_HSS_PORT_1, /**< HSS Port 1 */ - IX_HSSACC_HSS_PORT_MAX /**< Delimiter for error checks */ -} IxHssAccHssPort; - -/** - * @enum IxHssAccHdlcPort - * @brief The HDLC port ID - There are four identical HDLC ports (0-3) per - * HSS port and they correspond to the 4 E1/T1 trunks. - * - */ -typedef enum -{ - IX_HSSACC_HDLC_PORT_0, /**< HDLC Port 0 */ - IX_HSSACC_HDLC_PORT_1, /**< HDLC Port 1 */ - IX_HSSACC_HDLC_PORT_2, /**< HDLC Port 2 */ - IX_HSSACC_HDLC_PORT_3, /**< HDLC Port 3 */ - IX_HSSACC_HDLC_PORT_MAX /**< Delimiter for error checks */ -} IxHssAccHdlcPort; - -/** - * @enum IxHssAccTdmSlotUsage - * @brief The HSS TDM stream timeslot assignment types - * - */ -typedef enum -{ - IX_HSSACC_TDMMAP_UNASSIGNED, /**< Unassigned */ - IX_HSSACC_TDMMAP_HDLC, /**< HDLC - packetised */ - IX_HSSACC_TDMMAP_VOICE56K, /**< Voice56K - channelised */ - IX_HSSACC_TDMMAP_VOICE64K, /**< Voice64K - channelised */ - IX_HSSACC_TDMMAP_MAX /**< Delimiter for error checks */ -} IxHssAccTdmSlotUsage; - -/** - * @enum IxHssAccFrmSyncType - * @brief The HSS frame sync pulse type - * - */ -typedef enum -{ - IX_HSSACC_FRM_SYNC_ACTIVE_LOW, /**< Frame sync is sampled low */ - IX_HSSACC_FRM_SYNC_ACTIVE_HIGH, /**< sampled high */ - IX_HSSACC_FRM_SYNC_FALLINGEDGE, /**< sampled on a falling edge */ - IX_HSSACC_FRM_SYNC_RISINGEDGE, /**< sampled on a rising edge */ - IX_HSSACC_FRM_SYNC_TYPE_MAX /**< Delimiter for error checks */ -} IxHssAccFrmSyncType; - -/** - * @enum IxHssAccFrmSyncEnable - * @brief The IxHssAccFrmSyncEnable determines how the frame sync pulse is - * used - * */ -typedef enum -{ - IX_HSSACC_FRM_SYNC_INPUT, /**< Frame sync is sampled as an input */ - IX_HSSACC_FRM_SYNC_INVALID_VALUE, /**< 1 is not used */ - IX_HSSACC_FRM_SYNC_OUTPUT_FALLING, /**< Frame sync is an output generated - off a falling clock edge */ - IX_HSSACC_FRM_SYNC_OUTPUT_RISING, /**< Frame sync is an output generated - off a rising clock edge */ - IX_HSSACC_FRM_SYNC_ENABLE_MAX /**< Delimiter for error checks */ -} IxHssAccFrmSyncEnable; - -/** - * @enum IxHssAccClkEdge - * @brief IxHssAccClkEdge is used to determine the clk edge to use for - * framing and data - * - */ -typedef enum -{ - IX_HSSACC_CLK_EDGE_FALLING, /**< Clock sampled off a falling edge */ - IX_HSSACC_CLK_EDGE_RISING, /**< Clock sampled off a rising edge */ - IX_HSSACC_CLK_EDGE_MAX /**< Delimiter for error checks */ -} IxHssAccClkEdge; - -/** - * @enum IxHssAccClkDir - * @brief The HSS clock direction - * - */ -typedef enum -{ - IX_HSSACC_SYNC_CLK_DIR_INPUT, /**< Clock is an input */ - IX_HSSACC_SYNC_CLK_DIR_OUTPUT, /**< Clock is an output */ - IX_HSSACC_SYNC_CLK_DIR_MAX /**< Delimiter for error checks */ -} IxHssAccClkDir; - -/** - * @enum IxHssAccFrmPulseUsage - * @brief The HSS frame pulse usage - * - */ -typedef enum -{ - IX_HSSACC_FRM_PULSE_ENABLED, /**< Generate/Receive frame pulses */ - IX_HSSACC_FRM_PULSE_DISABLED, /**< Disregard frame pulses */ - IX_HSSACC_FRM_PULSE_MAX /**< Delimiter for error checks */ -} IxHssAccFrmPulseUsage; - -/** - * @enum IxHssAccDataRate - * @brief The HSS Data rate in relation to the clock - * - */ -typedef enum -{ - IX_HSSACC_CLK_RATE, /**< Data rate is at the configured clk speed */ - IX_HSSACC_HALF_CLK_RATE, /**< Data rate is half the configured clk speed */ - IX_HSSACC_DATA_RATE_MAX /**< Delimiter for error checks */ -} IxHssAccDataRate; - -/** - * @enum IxHssAccDataPolarity - * @brief The HSS data polarity type - * - */ -typedef enum -{ - IX_HSSACC_DATA_POLARITY_SAME, /**< Don't invert data between NPE and - HSS FIFOs */ - IX_HSSACC_DATA_POLARITY_INVERT, /**< Invert data between NPE and HSS - FIFOs */ - IX_HSSACC_DATA_POLARITY_MAX /**< Delimiter for error checks */ -} IxHssAccDataPolarity; - -/** - * @enum IxHssAccBitEndian - * @brief HSS Data endianness - * - */ -typedef enum -{ - IX_HSSACC_LSB_ENDIAN, /**< TX/RX Least Significant Bit first */ - IX_HSSACC_MSB_ENDIAN, /**< TX/RX Most Significant Bit first */ - IX_HSSACC_ENDIAN_MAX /**< Delimiter for the purposes of error checks */ -} IxHssAccBitEndian; - - -/** - * @enum IxHssAccDrainMode - * @brief Tx pin open drain mode - * - */ -typedef enum -{ - IX_HSSACC_TX_PINS_NORMAL, /**< Normal mode */ - IX_HSSACC_TX_PINS_OPEN_DRAIN, /**< Open Drain mode */ - IX_HSSACC_TX_PINS_MAX /**< Delimiter for error checks */ -} IxHssAccDrainMode; - -/** - * @enum IxHssAccSOFType - * @brief HSS start of frame types - * - */ -typedef enum -{ - IX_HSSACC_SOF_FBIT, /**< Framing bit transmitted and expected on rx */ - IX_HSSACC_SOF_DATA, /**< Framing bit not transmitted nor expected on rx */ - IX_HSSACC_SOF_MAX /**< Delimiter for error checks */ -} IxHssAccSOFType; - -/** - * @enum IxHssAccDataEnable - * @brief IxHssAccDataEnable is used to determine whether or not to drive - * the data pins - * - */ -typedef enum -{ - IX_HSSACC_DE_TRI_STATE, /**< TRI-State the data pins */ - IX_HSSACC_DE_DATA, /**< Push data out the data pins */ - IX_HSSACC_DE_MAX /**< Delimiter for error checks */ -} IxHssAccDataEnable; - -/** - * @enum IxHssAccTxSigType - * @brief IxHssAccTxSigType is used to determine how to drive the data pins - * - */ -typedef enum -{ - IX_HSSACC_TXSIG_LOW, /**< Drive the data pins low */ - IX_HSSACC_TXSIG_HIGH, /**< Drive the data pins high */ - IX_HSSACC_TXSIG_HIGH_IMP, /**< Drive the data pins with high impedance */ - IX_HSSACC_TXSIG_MAX /**< Delimiter for error checks */ -} IxHssAccTxSigType; - -/** - * @enum IxHssAccFbType - * @brief IxHssAccFbType determines how to drive the Fbit - * - * @warning This will only be used for T1 @ 1.544MHz - * - */ -typedef enum -{ - IX_HSSACC_FB_FIFO, /**< Fbit is dictated in FIFO */ - IX_HSSACC_FB_HIGH_IMP, /**< Fbit is high impedance */ - IX_HSSACC_FB_MAX /**< Delimiter for error checks */ -} IxHssAccFbType; - -/** - * @enum IxHssAcc56kEndianness - * @brief 56k data endianness when using the 56k type - * - */ -typedef enum -{ - IX_HSSACC_56KE_BIT_7_UNUSED, /**< High bit is unused */ - IX_HSSACC_56KE_BIT_0_UNUSED, /**< Low bit is unused */ - IX_HSSACC_56KE_MAX /**< Delimiter for error checks */ -} IxHssAcc56kEndianness; - -/** - * @enum IxHssAcc56kSel - * @brief 56k data transmission type when using the 56k type - * - */ -typedef enum -{ - IX_HSSACC_56KS_32_8_DATA, /**< 32/8 bit data */ - IX_HSSACC_56KS_56K_DATA, /**< 56K data */ - IX_HSSACC_56KS_MAX /**< Delimiter for error checks */ -} IxHssAcc56kSel; - - -/** - * @enum IxHssAccClkSpeed - * @brief IxHssAccClkSpeed represents the HSS clock speeds available - * - */ -typedef enum -{ - IX_HSSACC_CLK_SPEED_512KHZ, /**< 512KHz */ - IX_HSSACC_CLK_SPEED_1536KHZ, /**< 1.536MHz */ - IX_HSSACC_CLK_SPEED_1544KHZ, /**< 1.544MHz */ - IX_HSSACC_CLK_SPEED_2048KHZ, /**< 2.048MHz */ - IX_HSSACC_CLK_SPEED_4096KHZ, /**< 4.096MHz */ - IX_HSSACC_CLK_SPEED_8192KHZ, /**< 8.192MHz */ - IX_HSSACC_CLK_SPEED_MAX /**< Delimiter for error checking */ -} IxHssAccClkSpeed; - -/** - * @enum IxHssAccPktStatus - * @brief Indicates the status of packets passed to the client - * - */ -typedef enum -{ - IX_HSSACC_PKT_OK, /**< Error free.*/ - IX_HSSACC_STOP_SHUTDOWN_ERROR, /**< Errored due to stop or shutdown - occurrance.*/ - IX_HSSACC_HDLC_ALN_ERROR, /**< HDLC alignment error */ - IX_HSSACC_HDLC_FCS_ERROR, /**< HDLC Frame Check Sum error.*/ - IX_HSSACC_RXFREE_Q_EMPTY_ERROR, /**< RxFree Q became empty - while receiving this packet.*/ - IX_HSSACC_HDLC_MAX_FRAME_SIZE_EXCEEDED, /**< HDLC frame size - received is greater than - max specified at connect.*/ - IX_HSSACC_HDLC_ABORT_ERROR, /**< HDLC frame received is invalid due to an - abort sequence received.*/ - IX_HSSACC_DISCONNECT_IN_PROGRESS /**< Packet returned - because a disconnect is in progress */ -} IxHssAccPktStatus; - - -/** - * @enum IxHssAccPktCrcType - * @brief HDLC CRC type - * - */ -typedef enum -{ - IX_HSSACC_PKT_16_BIT_CRC = 16, /**< 16 bit CRC is being used */ - IX_HSSACC_PKT_32_BIT_CRC = 32 /**< 32 bit CRC is being used */ -} IxHssAccPktCrcType; - -/** - * @enum IxHssAccPktHdlcIdleType - * @brief HDLC idle transmission type - * - */ -typedef enum -{ - IX_HSSACC_HDLC_IDLE_ONES, /**< idle tx/rx will be a succession of ones */ - IX_HSSACC_HDLC_IDLE_FLAGS /**< idle tx/rx will be repeated flags */ -} IxHssAccPktHdlcIdleType; - -/** - * @brief Structure containing HSS port configuration parameters - * - * Note: All of these are used for TX. Only some are specific to RX. - * - */ -typedef struct -{ - IxHssAccFrmSyncType frmSyncType; /**< frame sync pulse type (tx/rx) */ - IxHssAccFrmSyncEnable frmSyncIO; /**< how the frame sync pulse is - used (tx/rx) */ - IxHssAccClkEdge frmSyncClkEdge; /**< frame sync clock edge type - (tx/rx) */ - IxHssAccClkEdge dataClkEdge; /**< data clock edge type (tx/rx) */ - IxHssAccClkDir clkDirection; /**< clock direction (tx/rx) */ - IxHssAccFrmPulseUsage frmPulseUsage; /**< whether to use the frame sync - pulse or not (tx/rx) */ - IxHssAccDataRate dataRate; /**< data rate in relation to the - clock (tx/rx) */ - IxHssAccDataPolarity dataPolarity; /**< data polarity type (tx/rx) */ - IxHssAccBitEndian dataEndianness; /**< data endianness (tx/rx) */ - IxHssAccDrainMode drainMode; /**< tx pin open drain mode (tx) */ - IxHssAccSOFType fBitUsage; /**< start of frame types (tx/rx) */ - IxHssAccDataEnable dataEnable; /**< whether or not to drive the data - pins (tx) */ - IxHssAccTxSigType voice56kType; /**< how to drive the data pins for - voice56k type (tx) */ - IxHssAccTxSigType unassignedType; /**< how to drive the data pins for - unassigned type (tx) */ - IxHssAccFbType fBitType; /**< how to drive the Fbit (tx) */ - IxHssAcc56kEndianness voice56kEndian;/**< 56k data endianness when using - the 56k type (tx) */ - IxHssAcc56kSel voice56kSel; /**< 56k data transmission type when - using the 56k type (tx) */ - unsigned frmOffset; /**< frame pulse offset in bits wrt - the first timeslot (0-1023) (tx/rx) */ - unsigned maxFrmSize; /**< frame size in bits (1-1024) - (tx/rx) */ -} IxHssAccPortConfig; - -/** - * @brief Structure containing HSS configuration parameters - * - */ -typedef struct -{ - IxHssAccPortConfig txPortConfig; /**< HSS tx port configuration */ - IxHssAccPortConfig rxPortConfig; /**< HSS rx port configuration */ - unsigned numChannelised; /**< The number of channelised - timeslots (0-32) */ - unsigned hssPktChannelCount; /**< The number of packetised - clients (0 - 4) */ - UINT8 channelisedIdlePattern; /**< The byte to be transmitted on - channelised service when there - is no client data to tx */ - BOOL loopback; /**< The HSS loopback state */ - unsigned packetizedIdlePattern; /**< The data to be transmitted on - packetised service when there is - no client data to tx */ - IxHssAccClkSpeed clkSpeed; /**< The HSS clock speed */ -} IxHssAccConfigParams; - -/** - * @brief This structure contains 56Kbps, HDLC-mode configuration parameters - * - */ -typedef struct -{ - BOOL hdlc56kMode; /**< 56kbps(TRUE)/64kbps(FALSE) HDLC */ - IxHssAcc56kEndianness hdlc56kEndian; /**< 56kbps data endianness - - ignored if hdlc56kMode is FALSE*/ - BOOL hdlc56kUnusedBitPolarity0; /**< The polarity '0'(TRUE)/'1'(FALSE) of the unused - bit while in 56kbps mode - - ignored if hdlc56kMode is FALSE*/ -} IxHssAccHdlcMode; - -/** - * @brief This structure contains information required by the NPE to - * configure the HDLC co-processor - * - */ -typedef struct -{ - IxHssAccPktHdlcIdleType hdlcIdleType; /**< What to transmit when a HDLC port is idle */ - IxHssAccBitEndian dataEndian; /**< The HDLC data endianness */ - IxHssAccPktCrcType crcType; /**< The CRC type to be used for this HDLC port */ -} IxHssAccPktHdlcFraming; - -/** - * @typedef UINT32 IxHssAccPktUserId - * - * @brief The client supplied value which will be supplied as a parameter - * with a given callback. - * - * This value will be passed into the ixHssAccPktPortConnect function once each - * with given callbacks. This value will then be passed back to the client - * as one of the parameters to each of these callbacks, - * when these callbacks are called. - */ -typedef UINT32 IxHssAccPktUserId; - - -/** - * @typedef IxHssAccLastErrorCallback - * @brief Prototype of the clients function to accept notification of the - * last error - * - * This function is registered through the config. The client will initiate - * the last error retrieval. The HssAccess component will send a message to - * the NPE through the NPE Message Handler. When a response to the read is - * received, the NPE Message Handler will callback the HssAccess component - * which will execute this function in the same IxNpeMh context. The client - * will be passed the last error and the related service port (packetised - * 0-3, channelised 0) - * - * @param lastHssError unsigned [in] - The last Hss error registered that - * has been registered. - * @param servicePort unsigned [in] - This is the service port number. - * (packetised 0-3, channelised 0) - * - * @return void - */ -typedef void (*IxHssAccLastErrorCallback) (unsigned lastHssError, - unsigned servicePort); - -/** - * @typedef IxHssAccPktRxCallback - * @brief Prototype of the clients function to accept notification of - * packetised rx - * - * This function is registered through the ixHssAccPktPortConnect. hssPktAcc will pass - * received data in the form of mbufs to the client. The mbuf passed back - * to the client could contain a chain of buffers, depending on the packet - * size received. - * - * @param *buffer @ref IX_OSAL_MBUF [in] - This is the mbuf which contains the - * payload received. - * @param numHssErrs unsigned [in] - This is the number of hssErrors - * the Npe has received - * @param pktStatus @ref IxHssAccPktStatus [in] - This is the status of the - * mbuf that has been received. - * @param rxUserId @ref IxHssAccPktUserId [in] - This is the client supplied value - * passed in at ixHssAccPktPortConnect time which is now returned to the client. - * - * @return void - */ -typedef void (*IxHssAccPktRxCallback) (IX_OSAL_MBUF *buffer, - unsigned numHssErrs, - IxHssAccPktStatus pktStatus, - IxHssAccPktUserId rxUserId); - -/** - * @typedef IxHssAccPktRxFreeLowCallback - * @brief Prototype of the clients function to accept notification of - * requirement of more Rx Free buffers - * - * The client can choose to register a callback of this type when - * calling a connecting. This function is registered through the ixHssAccPktPortConnect. - * If defined, the access layer will provide the trigger for - * this callback. The callback will be responsible for supplying mbufs to - * the access layer for use on the receive path from the HSS using - * ixHssPktAccFreeBufReplenish. - * - * @return void - */ -typedef void (*IxHssAccPktRxFreeLowCallback) (IxHssAccPktUserId rxFreeLowUserId); - -/** - * @typedef IxHssAccPktTxDoneCallback - * @brief Prototype of the clients function to accept notification of - * completion with Tx buffers - * - * This function is registered through the ixHssAccPktPortConnect. It enables - * the hssPktAcc to pass buffers back to the client - * when transmission is complete. - * - * @param *buffer @ref IX_OSAL_MBUF [in] - This is the mbuf which contained - * the payload that was for Tx. - * @param numHssErrs unsigned [in] - This is the number of hssErrors - * the Npe has received - * @param pktStatus @ref IxHssAccPktStatus [in] - This is the status of the - * mbuf that has been transmitted. - * @param txDoneUserId @ref IxHssAccPktUserId [in] - This is the client supplied value - * passed in at ixHssAccPktPortConnect time which is now returned to the client. - * - * @return void - */ -typedef void (*IxHssAccPktTxDoneCallback) (IX_OSAL_MBUF *buffer, - unsigned numHssErrs, - IxHssAccPktStatus pktStatus, - IxHssAccPktUserId txDoneUserId); - -/** - * @typedef IxHssAccChanRxCallback - * @brief Prototype of the clients function to accept notification of - * channelised rx - * - * This callback, if defined by the client in the connect, will get called - * in the context of an IRQ. The IRQ will be triggered when the hssSyncQMQ - * is not empty. The queued entry will be dequeued and this function will - * be executed. - * - * @param hssPortId @ref IxHssAccHssPort - The HSS port Id. There are two - * identical ports (0-1). - * @param txOffset unsigned [in] - an offset indicating from where within - * the txPtrList the NPE is currently transmitting from. - * @param rxOffset unsigned [in] - an offset indicating where within the - * receive buffers the NPE has just written the received data to. - * @param numHssErrs unsigned [in] - This is the number of hssErrors - * the Npe has received - * - * @return void - */ -typedef void (*IxHssAccChanRxCallback) (IxHssAccHssPort hssPortId, - unsigned rxOffset, - unsigned txOffset, - unsigned numHssErrs); - -/* - * Prototypes for interface functions. - */ - -/** - * - * @ingroup IxHssAccAPI - * - * @fn IX_STATUS ixHssAccPortInit (IxHssAccHssPort hssPortId, - IxHssAccConfigParams *configParams, - IxHssAccTdmSlotUsage *tdmMap, - IxHssAccLastErrorCallback lastHssErrorCallback) - * - * @brief Initialise a HSS port. No channelised or packetised connections - * should exist in the HssAccess layer while this interface is being called. - * - * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two - * identical ports (0-1). - * @param *configParams @ref IxHssAccConfigParams [in] - A pointer to the HSS - * configuration structure - * @param *tdmMap @ref IxHssAccTdmSlotUsage [in] - A pointer to an array of size - * IX_HSSACC_TSLOTS_PER_HSS_PORT, defining the slot usage over the HSS port - * @param lastHssErrorCallback @ref IxHssAccLastErrorCallback [in] - Client - * callback to report last error - * - * @return - * - IX_SUCCESS The function executed successfully - * - IX_FAIL The function did not execute successfully - * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a - * parameter error - */ -PUBLIC IX_STATUS -ixHssAccPortInit (IxHssAccHssPort hssPortId, - IxHssAccConfigParams *configParams, - IxHssAccTdmSlotUsage *tdmMap, - IxHssAccLastErrorCallback lastHssErrorCallback); - -/** - * - * @ingroup IxHssAccAPI - * - * @fn IX_STATUS ixHssAccLastErrorRetrievalInitiate ( - IxHssAccHssPort hssPortId) - * - * @brief Initiate the retrieval of the last HSS error. The HSS port - * should be configured before attempting to call this interface. - * - * @param hssPortId @ref IxHssAccHssPort [in] - the HSS port ID - * - * @return - * - IX_SUCCESS The function executed successfully - * - IX_FAIL The function did not execute successfully - * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a - * parameter error - */ -PUBLIC IX_STATUS -ixHssAccLastErrorRetrievalInitiate (IxHssAccHssPort hssPortId); - - -/** - * - * @ingroup IxHssAccAPI - * - * @fn IX_STATUS ixHssAccInit () - * - * @brief This function is responsible for initialising resources for use - * by the packetised and channelised clients. It should be called after - * HSS NPE image has been downloaded into NPE-A and before any other - * HssAccess interface is called. - * No other HssAccPacketised interface should be called while this interface - * is being processed. - * - * @return - * - IX_SUCCESS The function executed successfully - * - IX_FAIL The function did not execute successfully - * - IX_HSSACC_RESOURCE_ERR The function did not execute successfully due - * to a resource error - */ -PUBLIC IX_STATUS -ixHssAccInit (void); - - -/** - * - * @ingroup IxHssAccAPI - * - * @fn ixHssAccPktPortConnect (IxHssAccHssPort hssPortId, - IxHssAccHdlcPort hdlcPortId, - BOOL hdlcFraming, - IxHssAccHdlcMode hdlcMode, - BOOL hdlcBitInvert, - unsigned blockSizeInWords, - UINT32 rawIdleBlockPattern, - IxHssAccPktHdlcFraming hdlcTxFraming, - IxHssAccPktHdlcFraming hdlcRxFraming, - unsigned frmFlagStart, - IxHssAccPktRxCallback rxCallback, - IxHssAccPktUserId rxUserId, - IxHssAccPktRxFreeLowCallback rxFreeLowCallback, - IxHssAccPktUserId rxFreeLowUserId, - IxHssAccPktTxDoneCallback txDoneCallback, - IxHssAccPktUserId txDoneUserId) - * - * @brief This function is responsible for connecting a client to one of - * the 4 available HDLC ports. The HSS port should be configured before - * attempting a connect. No other HssAccPacketised interface should be - * called while this connect is being processed. - * - * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two - * identical ports (0-1). - * @param hdlcPortId @ref IxHssAccHdlcPort [in] - This is the number of the HDLC port and - * it corresponds to the physical E1/T1 trunk i.e. 0, 1, 2, 3 - * @param hdlcFraming BOOL [in] - This value determines whether the service - * will use HDLC data or the debug, raw data type i.e. no HDLC processing - * @param hdlcMode @ref IxHssAccHdlcMode [in] - This structure contains 56Kbps, HDLC-mode - * configuration parameters - * @param hdlcBitInvert BOOL [in] - This value determines whether bit inversion - * will occur between HDLC and HSS co-processors i.e. post-HDLC processing for - * transmit and pre-HDLC processing for receive, for the specified HDLC Termination - * Point - * @param blockSizeInWords unsigned [in] - The max tx/rx block size - * @param rawIdleBlockPattern UINT32 [in] - Tx idle pattern in raw mode - * @param hdlcTxFraming @ref IxHssAccPktHdlcFraming [in] - This structure contains - * the following information required by the NPE to configure the HDLC - * co-processor for TX - * @param hdlcRxFraming @ref IxHssAccPktHdlcFraming [in] - This structure contains - * the following information required by the NPE to configure the HDLC - * co-processor for RX - * @param frmFlagStart unsigned - Number of flags to precede to - * transmitted flags (0-2). - * @param rxCallback @ref IxHssAccPktRxCallback [in] - Pointer to - * the clients packet receive function. - * @param rxUserId @ref IxHssAccPktUserId [in] - The client supplied rx value - * to be passed back as an argument to the supplied rxCallback - * @param rxFreeLowCallback @ref IxHssAccPktRxFreeLowCallback [in] - Pointer to - * the clients Rx free buffer request function. If NULL, assume client will - * trigger independently. - * @param rxFreeLowUserId @ref IxHssAccPktUserId [in] - The client supplied RxFreeLow value - * to be passed back as an argument to the supplied rxFreeLowCallback - * @param txDoneCallback @ref IxHssAccPktTxDoneCallback [in] - Pointer to the - * clients Tx done callback function - * @param txDoneUserId @ref IxHssAccPktUserId [in] - The client supplied txDone value - * to be passed back as an argument to the supplied txDoneCallback - * - * @return - * - IX_SUCCESS The function executed successfully - * - IX_FAIL The function did not execute successfully - * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a - * parameter error - * - IX_HSSACC_RESOURCE_ERR The function did not execute successfully due - * to a resource error - */ -PUBLIC IX_STATUS -ixHssAccPktPortConnect (IxHssAccHssPort hssPortId, - IxHssAccHdlcPort hdlcPortId, - BOOL hdlcFraming, - IxHssAccHdlcMode hdlcMode, - BOOL hdlcBitInvert, - unsigned blockSizeInWords, - UINT32 rawIdleBlockPattern, - IxHssAccPktHdlcFraming hdlcTxFraming, - IxHssAccPktHdlcFraming hdlcRxFraming, - unsigned frmFlagStart, - IxHssAccPktRxCallback rxCallback, - IxHssAccPktUserId rxUserId, - IxHssAccPktRxFreeLowCallback rxFreeLowCallback, - IxHssAccPktUserId rxFreeLowUserId, - IxHssAccPktTxDoneCallback txDoneCallback, - IxHssAccPktUserId txDoneUserId); - -/** - * - * @ingroup IxHssAccAPI - * - * @fn IX_STATUS ixHssAccPktPortEnable (IxHssAccHssPort hssPortId, - IxHssAccHdlcPort hdlcPortId) - * - * @brief This function is responsible for enabling a packetised service - * for the specified HSS/HDLC port combination. It enables the RX flow. The - * client must have already connected to a packetised service and is responsible - * for ensuring an adequate amount of RX mbufs have been supplied to the access - * component before enabling the packetised service. This function must be called - * on a given port before any call to ixHssAccPktPortTx on the same port. - * No other HssAccPacketised interface should be called while this interface is - * being processed. - * - * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two - * identical ports (0-1). - * @param hdlcPortId @ref IxHssAccHdlcPort [in] - The port id (0,1,2,3) to enable the service - * on. - * - * @return - * - IX_SUCCESS The function executed successfully - * - IX_FAIL The function did not execute successfully - * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a - * parameter error - */ -PUBLIC IX_STATUS -ixHssAccPktPortEnable (IxHssAccHssPort hssPortId, - IxHssAccHdlcPort hdlcPortId); - -/** - * @fn IX_STATUS ixHssAccPktPortDisable (IxHssAccHssPort hssPortId, - IxHssAccHdlcPort hdlcPortId) - * - * @brief This function is responsible for disabling a packetised service - * for the specified HSS/HDLC port combination. It disables the RX flow. - * The client must have already connected to and enabled a packetised service - * for the specified HDLC port. This disable interface can be called before a - * disconnect, but is not required to. - * - * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two - * identical ports (0-1). - * @param hdlcPortId @ref IxHssAccHdlcPort [in] - The port id (0,1,2,3) to disable - * the service on. - * - * @return - * - IX_SUCCESS The function executed successfully - * - IX_FAIL The function did not execute successfully - * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a - * parameter error - */ -PUBLIC IX_STATUS -ixHssAccPktPortDisable (IxHssAccHssPort hssPortId, - IxHssAccHdlcPort hdlcPortId); - -/** - * - * @ingroup IxHssAccAPI - * - * @fn IX_STATUS ixHssAccPktPortDisconnect (IxHssAccHssPort hssPortId, - IxHssAccHdlcPort hdlcPortId) - * - * @brief This function is responsible for disconnecting a client from one - * of the 4 available HDLC ports. It is not required that the Rx Flow - * has been disabled before calling this function. If the RX Flow has not been - * disabled, the disconnect will disable it before proceeding with the - * disconnect. No other HssAccPacketised - * interface should be called while this interface is being processed. - * - * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two - * identical ports (0-1). - * @param hdlcPortId @ref IxHssAccHdlcPort [in] - This is the number of the HDLC port - * to disconnect and it corresponds to the physical E1/T1 trunk i.e. 0, 1, 2, 3 - * - * @return - * - IX_SUCCESS The function executed successfully - * - IX_FAIL The function did not execute successfully - * - IX_HSSACC_PKT_DISCONNECTING The function has initiated the disconnecting - * procedure but it has not completed yet. - */ -PUBLIC IX_STATUS -ixHssAccPktPortDisconnect (IxHssAccHssPort hssPortId, - IxHssAccHdlcPort hdlcPortId); - -/** - * - * @ingroup IxHssAccAPI - * - * @fn BOOL ixHssAccPktPortIsDisconnectComplete (IxHssAccHssPort hssPortId, - IxHssAccHdlcPort hdlcPortId) - * - * @brief This function is called to check if a given HSS/HDLC port - * combination is in a connected state or not. This function may be called - * at any time to determine a ports state. No other HssAccPacketised - * interface should be called while this interface is being processed. - * - * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two - * identical ports (0-1). - * @param hdlcPortId @ref IxHssAccHdlcPort [in] - This is the number of the HDLC port - * to disconnect and it corresponds to the physical E1/T1 trunk i.e. 0, 1, 2, 3 - * - * @return - * - TRUE The state of this HSS/HDLC port combination is disconnected, - * so if a disconnect was called, it is now completed. - * - FALSE The state of this HSS/HDLC port combination is connected, - * so if a disconnect was called, it is not yet completed. - */ -PUBLIC BOOL -ixHssAccPktPortIsDisconnectComplete (IxHssAccHssPort hssPortId, - IxHssAccHdlcPort hdlcPortId); - - -/** - * - * @ingroup IxHssAccAPI - * - * @fn IX_STATUS ixHssAccPktPortRxFreeReplenish (IxHssAccHssPort hssPortId, - IxHssAccHdlcPort hdlcPortId, - IX_OSAL_MBUF *buffer) - * - * @brief Function which the client calls at regular intervals to provide - * mbufs to the access component for RX. A connection should exist for - * the specified hssPortId/hdlcPortId combination before attempting to call this - * interface. Also, the connection should not be in a disconnecting state. - * - * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two - * identical ports (0-1). - * @param hdlcPortId @ref IxHssAccHdlcPort [in] - This is the number of the HDLC port - * and it corresponds to the physical E1/T1 trunk i.e. 0, 1, 2, 3 - * @param *buffer @ref IX_OSAL_MBUF [in] - A pointer to a free mbuf to filled with payload. - * - * @return - * - IX_SUCCESS The function executed successfully - * - IX_FAIL The function did not execute successfully - * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a - * parameter error - * - IX_HSSACC_RESOURCE_ERR The function did not execute successfully due - * to a resource error - * - IX_HSSACC_Q_WRITE_OVERFLOW The function did not succeed due to a Q - * overflow - */ -PUBLIC IX_STATUS -ixHssAccPktPortRxFreeReplenish (IxHssAccHssPort hssPortId, - IxHssAccHdlcPort hdlcPortId, - IX_OSAL_MBUF *buffer); - -/** - * - * @ingroup IxHssAccAPI - * - * @fn IX_STATUS ixHssAccPktPortTx (IxHssAccHssPort hssPortId, - IxHssAccHdlcPort hdlcPortId, - IX_OSAL_MBUF *buffer) - * - * @brief Function which the client calls when it wants to transmit - * packetised data. An enabled connection should exist on the specified - * hssPortId/hdlcPortId combination before attempting to call this interface. - * No other HssAccPacketised - * interface should be called while this interface is being processed. - * - * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two - * identical ports (0-1). - * @param hdlcPortId @ref IxHssAccHdlcPort [in] - This is the number of the HDLC port - * and it corresponds to the physical E1/T1 trunk i.e. 0, 1, 2, 3 - * @param *buffer @ref IX_OSAL_MBUF [in] - A pointer to a chain of mbufs which the - * client has filled with the payload - * - * @return - * - IX_SUCCESS The function executed successfully - * - IX_FAIL The function did not execute successfully - * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a - * parameter error - * - IX_HSSACC_RESOURCE_ERR The function did not execute successfully due - * to a resource error. See note. - * - IX_HSSACC_Q_WRITE_OVERFLOW The function did not succeed due to a Q - * overflow - * - * @note IX_HSSACC_RESOURCE_ERR is returned when a free descriptor cannot be - * obtained to send the chain of mbufs to the NPE. This is a normal scenario. - * HssAcc has a pool of descriptors and this error means that they are currently - * all in use. - * The recommended approach to this is to retry until a descriptor becomes free - * and the packet is successfully transmitted. - * Alternatively, the user could wait until the next IxHssAccPktTxDoneCallback - * callback is triggered, and then retry, as it is this event that causes a - * transmit descriptor to be freed. - */ -PUBLIC IX_STATUS -ixHssAccPktPortTx (IxHssAccHssPort hssPortId, - IxHssAccHdlcPort hdlcPortId, - IX_OSAL_MBUF *buffer); - -/** - * - * @ingroup IxHssAccAPI - * - * @fn IX_STATUS ixHssAccChanConnect (IxHssAccHssPort hssPortId, - unsigned bytesPerTSTrigger, - UINT8 *rxCircular, - unsigned numRxBytesPerTS, - UINT32 *txPtrList, - unsigned numTxPtrLists, - unsigned numTxBytesPerBlk, - IxHssAccChanRxCallback rxCallback) - * - * @brief This function allows the client to connect to the Tx/Rx NPE - * Channelised Service. There can only be one client per HSS port. The - * client is responsible for ensuring that the HSS port is configured - * appropriately before its connect request. No other HssAccChannelised - * interface should be called while this interface is being processed. - * - * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two - * identical ports (0-1). - * @param bytesPerTSTrigger unsigned [in] - The NPE will trigger the access - * component after bytesPerTSTrigger have been received for all trunk - * timeslots. This figure is a multiple of 8 e.g. 8 for 1ms trigger, 16 for - * 2ms trigger. - * @param *rxCircular UINT8 [in] - A pointer to memory allocated by the - * client to be filled by data received. The buffer at this address is part - * of a pool of buffers to be accessed in a circular fashion. This address - * will be written to by the NPE. Therefore, it needs to be a physical address. - * @param numRxBytesPerTS unsigned [in] - The number of bytes allocated per - * timeslot within the receive memory. This figure will depend on the - * latency of the system. It needs to be deep enough for data to be read by - * the client before the NPE re-writes over that memory e.g. if the client - * samples at a rate of 40bytes per timeslot, numRxBytesPerTS may need to - * be 40bytes * 3. This would give the client 3 * 5ms of time before - * received data is over-written. - * @param *txPtrList UINT32 [in] - The address of an area of contiguous - * memory allocated by the client to be populated with pointers to data for - * transmission. Each pointer list contains a pointer per active channel. - * The txPtrs will point to data to be transmitted by the NPE. Therefore, - * they must point to physical addresses. - * @param numTxPtrLists unsigned [in] - The number of pointer lists in - * txPtrList. This figure is dependent on jitter. - * @param numTxBytesPerBlk unsigned [in] - The size of the Tx data, in - * bytes, that each pointer within the PtrList points to. - * @param rxCallback @ref IxHssAccChanRxCallback [in] - A client function - * pointer to be called back to handle the actual tx/rx of channelised - * data. If this is not NULL, an ISR will call this function. If this - * pointer is NULL, it implies that the client will use a polling mechanism - * to detect when the tx and rx of channelised data is to occur. The client - * will use hssChanAccStatus for this. - * - * @return - * - IX_SUCCESS The function executed successfully - * - IX_FAIL The function did not execute successfully - * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a - * parameter error - */ - -PUBLIC IX_STATUS -ixHssAccChanConnect (IxHssAccHssPort hssPortId, - unsigned bytesPerTSTrigger, - UINT8 *rxCircular, - unsigned numRxBytesPerTS, - UINT32 *txPtrList, - unsigned numTxPtrLists, - unsigned numTxBytesPerBlk, - IxHssAccChanRxCallback rxCallback); - -/** - * - * @ingroup IxHssAccAPI - * - * @fn IX_STATUS ixHssAccChanPortEnable (IxHssAccHssPort hssPortId) - * - * @brief This function is responsible for enabling a channelised service - * for the specified HSS port. It enables the NPE RX flow. The client must - * have already connected to a channelised service before enabling the - * channelised service. No other HssAccChannelised - * interface should be called while this interface is being processed. - * - * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two - * identical ports (0-1). - * - * @return - * - IX_SUCCESS The function executed successfully - * - IX_FAIL The function did not execute successfully - * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a - * parameter error - */ -PUBLIC IX_STATUS -ixHssAccChanPortEnable (IxHssAccHssPort hssPortId); - -/** - * - * @ingroup IxHssAccAPI - * - * @fn IX_STATUS ixHssAccChanPortDisable (IxHssAccHssPort hssPortId) - * - * @brief This function is responsible for disabling a channelised service - * for the specified HSS port. It disables the NPE RX flow. The client must - * have already connected to and enabled a channelised service for the - * specified HSS port. This disable interface can be called before a - * disconnect, but is not required to. No other HssAccChannelised - * interface should be called while this interface is being processed. - * - * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two - * identical ports (0-1). - * - * @return - * - IX_SUCCESS The function executed successfully - * - IX_FAIL The function did not execute successfully - * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a - * parameter error - */ -PUBLIC IX_STATUS -ixHssAccChanPortDisable (IxHssAccHssPort hssPortId); - -/** - * - * @ingroup IxHssAccAPI - * - * @fn IX_STATUS ixHssAccChanDisconnect (IxHssAccHssPort hssPortId) - * - * @brief This function allows the client to Disconnect from a channelised - * service. If the NPE RX Flow has not been disabled, the disconnect will - * disable it before proceeding with other disconnect functionality. - * No other HssAccChannelised interface should be called while this - * interface is being processed. - * - * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two - * identical ports (0-1). - * - * @return - * - IX_SUCCESS The function executed successfully - * - IX_FAIL The function did not execute successfully - * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a - * parameter error - */ -PUBLIC IX_STATUS -ixHssAccChanDisconnect (IxHssAccHssPort hssPortId); - -/** - * - * @ingroup IxHssAccAPI - * - * @fn IX_STATUS ixHssAccChanStatusQuery (IxHssAccHssPort hssPortId, - BOOL *dataRecvd, - unsigned *rxOffset, - unsigned *txOffset, - unsigned *numHssErrs) - * - * @brief This function is called by the client to query whether or not - * channelised data has been received. If there is, hssChanAcc will return - * the details in the output parameters. An enabled connection should - * exist on the specified hssPortId before attempting to call this interface. - * No other HssAccChannelised interface should be called while this - * interface is being processed. - * - * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two - * identical ports (0-1). - * @param *dataRecvd BOOL [out] - This BOOL indicates to the client whether - * or not the access component has read any data for the client. If - * FALSE, the other output parameters will not have been written to. - * @param *rxOffset unsigned [out] - An offset to indicate to the client - * where within the receive buffers the NPE has just written the received - * data to. - * @param *txOffset unsigned [out] - An offset to indicate to the client - * from where within the txPtrList the NPE is currently transmitting from - * @param *numHssErrs unsigned [out] - The total number of HSS port errors - * since initial port configuration - * - * - * @return - * - IX_SUCCESS The function executed successfully - * - IX_FAIL The function did not execute successfully - * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a - * parameter error - */ -PUBLIC IX_STATUS -ixHssAccChanStatusQuery (IxHssAccHssPort hssPortId, - BOOL *dataRecvd, - unsigned *rxOffset, - unsigned *txOffset, - unsigned *numHssErrs); - -/** - * - * @ingroup IxHssAccAPI - * - * @fn void ixHssAccShow (void) - * - * @brief This function will display the current state of the IxHssAcc - * component. The output is sent to stdout. - * - * @return void - */ -PUBLIC void -ixHssAccShow (void); - -/** - * - * @ingroup IxHssAccAPI - * - * @fn void ixHssAccStatsInit (void) - * - * @brief This function will reset the IxHssAcc statistics. - * - * @return void - */ -PUBLIC void -ixHssAccStatsInit (void); - -#endif /* IXHSSACC_H */ - -/** - * @} defgroup IxHssAcc - */ diff --git a/cpu/ixp/npe/include/IxI2cDrv.h b/cpu/ixp/npe/include/IxI2cDrv.h deleted file mode 100644 index 92c6b24b46..0000000000 --- a/cpu/ixp/npe/include/IxI2cDrv.h +++ /dev/null @@ -1,867 +0,0 @@ -/** - * @file IxI2cDrv.h - * - * @brief Header file for the IXP400 I2C Driver (IxI2cDrv) - * - * @version $Revision: 0.1 $ - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -/** - * @defgroup IxI2cDrv IXP400 I2C Driver(IxI2cDrv) API - * - * @brief IXP400 I2C Driver Public API - * - * @{ - */ -#ifndef IXI2CDRV_H -#define IXI2CDRV_H - -#ifdef __ixp46X -#include "IxOsal.h" - -/* - * Section for #define - */ - -/** - * @ingroup IxI2cDrv - * @brief The interval of micro/mili seconds the IXP will wait before it polls for - * status from the ixI2cIntrXferStatus; Every 20us is 1 byte @ - * 400Kbps and 4 bytes @ 100Kbps. This is dependent on delay type selected - * through the API ixI2cDrvDelayTypeSelect. - */ -#define IX_I2C_US_POLL_FOR_XFER_STATUS 20 - -/** - * @ingroup IxI2cDrv - * @brief The number of tries that will be attempted to call a callback - * function if the callback does not or is unable to resolve the - * issue it is called to resolve - */ -#define IX_I2C_NUM_OF_TRIES_TO_CALL_CALLBACK_FUNC 10 - - -/** - * @ingroup IxI2cDrv - * @brief Number of tries slave will poll the IDBR Rx full bit before it - * gives up - */ -#define IX_I2C_NUM_TO_POLL_IDBR_RX_FULL 0x100 - -/** - * @ingroup IxI2cDrv - * @brief Number of tries slave will poll the IDBR Tx empty bit before it - * gives up - */ -#define IX_I2C_NUM_TO_POLL_IDBR_TX_EMPTY 0x100 - -/* - * Section for enum - */ - -/** - * @ingroup IxI2cDrv - * - * @enum IxI2cMasterStatus - * - * @brief The master status - transfer complete, bus error or arbitration loss - */ -typedef enum -{ - IX_I2C_MASTER_XFER_COMPLETE = IX_SUCCESS, - IX_I2C_MASTER_XFER_BUS_ERROR, - IX_I2C_MASTER_XFER_ARB_LOSS -} IxI2cMasterStatus; - - -/** - * @ingroup IxI2cDrv - * - * @enum IX_I2C_STATUS - * - * @brief The status that can be returned in a I2C driver initialization - */ -typedef enum -{ - IX_I2C_SUCCESS = IX_SUCCESS, /**< Success status */ - IX_I2C_FAIL, /**< Fail status */ - IX_I2C_NOT_SUPPORTED, /**< hardware does not have dedicated I2C hardware */ - IX_I2C_NULL_POINTER, /**< parameter passed in is NULL */ - IX_I2C_INVALID_SPEED_MODE_ENUM_VALUE, /**< speed mode selected is invalid */ - IX_I2C_INVALID_FLOW_MODE_ENUM_VALUE, /**< flow mode selected is invalid */ - IX_I2C_SLAVE_ADDR_CB_MISSING, /**< slave callback is NULL */ - IX_I2C_GEN_CALL_CB_MISSING, /**< general callback is NULL */ - IX_I2C_INVALID_SLAVE_ADDR, /**< invalid slave address specified */ - IX_I2C_INT_BIND_FAIL, /**< interrupt bind fail */ - IX_I2C_INT_UNBIND_FAIL, /**< interrupt unbind fail */ - IX_I2C_NOT_INIT, /**< I2C is not initialized yet */ - IX_I2C_MASTER_BUS_BUSY, /**< master detected a I2C bus busy */ - IX_I2C_MASTER_ARB_LOSS, /**< master experienced arbitration loss */ - IX_I2C_MASTER_XFER_ERROR, /**< master experienced a transfer error */ - IX_I2C_MASTER_BUS_ERROR, /**< master detected a I2C bus error */ - IX_I2C_MASTER_NO_BUFFER, /**< no buffer provided for master transfer */ - IX_I2C_MASTER_INVALID_XFER_MODE, /**< xfer mode selected is invalid */ - IX_I2C_SLAVE_ADDR_NOT_DETECTED, /**< polled slave addr not detected */ - IX_I2C_GEN_CALL_ADDR_DETECTED, /**< polling detected general call */ - IX_I2C_SLAVE_READ_DETECTED, /**< polling detected slave read request */ - IX_I2C_SLAVE_WRITE_DETECTED, /**< polling detected slave write request */ - IX_I2C_SLAVE_NO_BUFFER, /**< no buffer provided for slave transfers */ - IX_I2C_DATA_SIZE_ZERO, /**< data size transfer is zero - invalid */ - IX_I2C_SLAVE_WRITE_BUFFER_EMPTY, /**< slave buffer is used till empty */ - IX_I2C_SLAVE_WRITE_ERROR, /**< slave write experienced an error */ - IX_I2C_SLAVE_OR_GEN_READ_BUFFER_FULL, /**< slave buffer is filled up */ - IX_I2C_SLAVE_OR_GEN_READ_ERROR /**< slave read experienced an error */ -} IX_I2C_STATUS; - -/** - * @ingroup IxI2cDrv - * - * @enum IxI2cSpeedMode - * - * @brief Type of speed modes supported by the I2C hardware. - */ -typedef enum -{ - IX_I2C_NORMAL_MODE = 0x0, - IX_I2C_FAST_MODE -} IxI2cSpeedMode; - -/** - * @ingroup IxI2cDrv - * - * @enum IxI2cXferMode - * - * @brief Used for indicating it is a repeated start or normal transfer - */ -typedef enum -{ - IX_I2C_NORMAL = 0x0, - IX_I2C_REPEATED_START -} IxI2cXferMode; - -/** - * @ingroup IxI2cDrv - * - * @enum IxI2cFlowMode - * - * @brief Used for indicating it is a poll or interrupt mode - */ -typedef enum -{ - IX_I2C_POLL_MODE = 0x0, - IX_I2C_INTERRUPT_MODE -} IxI2cFlowMode; - -/** - * @ingroup IxI2cDrv - * - * @enum IxI2cDelayMode - * - * @brief Used for selecting looping delay or OS scheduler delay - */ -typedef enum -{ - IX_I2C_LOOP_DELAY = 1, /**< delay in microseconds */ - IX_I2C_SCHED_DELAY /**< delay in miliseconds */ -} IxI2cDelayMode; - -/** - * @ingroup IxI2cDrv - * - * @brief The pointer to the function that will be called when the master - * has completed its receive. The parameter that is passed will - * provide the status of the read (success, arb loss, or bus - * error), the transfer mode (normal or repeated start, the - * buffer pointer and number of bytes transferred. - */ -typedef void (*IxI2cMasterReadCallbackP)(IxI2cMasterStatus, IxI2cXferMode, char*, UINT32); - -/** - * @ingroup IxI2cDrv - * - * @brief The pointer to the function that will be called when the master - * has completed its transmit. The parameter that is passed will - * provide the status of the write (success, arb loss, or buss - * error), the transfer mode (normal or repeated start), the - * buffer pointer and number of bytes transferred. - */ -typedef void (*IxI2cMasterWriteCallbackP)(IxI2cMasterStatus, IxI2cXferMode, char*, UINT32); - -/** - * @ingroup IxI2cDrv - * - * @brief The pointer to the function that will be called when a slave - * address detected in interrupt mode for a read. The parameters - * that is passed will provide the read status, buffer pointer, - * buffer size, and the bytes received. When a start of a read - * is initiated there will be no buffer allocated and this callback - * will be called to request for a buffer. While receiving, if the - * buffer gets filled, this callback will be called to request for - * a new buffer while sending the filled buffer's pointer and size, - * and data size received. When the receive is complete, this - * callback will be called to process the data and free the memory - * by passing the buffer's pointer and size, and data size received. - */ -typedef void (*IxI2cSlaveReadCallbackP)(IX_I2C_STATUS, char*, UINT32, UINT32); - -/** - * @ingroup IxI2cDrv - * - * @brief The pointer to the function that will be called when a slave - * address detected in interrupt mode for a write. The parameters - * that is passed will provide the write status, buffer pointer, - * buffer size, and the bytes received. When a start of a write is - * initiated there will be no buffer allocated and this callback - * will be called to request for a buffer and to fill it with data. - * While transmitting, if the data in the buffer empties, this - * callback will be called to request for more data to be filled in - * the same or new buffer. When the transmit is complete, this - * callback will be called to free the memory or other actions to - * be taken. - */ -typedef void (*IxI2cSlaveWriteCallbackP)(IX_I2C_STATUS, char*, UINT32, UINT32); - -/** - * @ingroup IxI2cDrv - * - * @brief The pointer to the function that will be called when a general - * call detected in interrupt mode for a read. The parameters that - * is passed will provide the read status, buffer pointer, buffer - * size, and the bytes received. When a start of a read is - * initiated there will be no buffer allocated and this callback - * will be called to request for a buffer. While receiving, if the - * buffer gets filled, this callback will be called to request for - * a new buffer while sending the filled buffer's pointer and size, - * and data size received. When the receive is complete, this - * callback will be called to process the data and free the memory - * by passing the buffer's pointer and size, and data size received. - */ -typedef void (*IxI2cGenCallCallbackP)(IX_I2C_STATUS, char*, UINT32, UINT32); - -/* - * Section for struct - */ - -/** - * @brief contains all the variables required to initialize the I2C unit - * - * Structure to be filled and used for calling initialization - */ -typedef struct -{ - IxI2cSpeedMode I2cSpeedSelect; /** - * NOTE: 1) An individual callback is to be registered for each Slave and Master - * Auxiliary Time Stamp registers. Thus to register for both Master and Slave time - * stamp interrupts either the same callback or two separate callbacks the API has - * to be invoked twice. - * 2) On the IXDP465 Development Platform, the Auxiliary Timestamp signal for - * slave mode is tied to GPIO 8 pin. This signal is software routed by default to - * PCI for backwards compatibility with the IXDP425 Development Platform. This - * routing must be disabled for the auxiliary slave time stamp register to work - * properly. The following commands may be used to accomplish this. However, refer - * to the IXDP465 Development Platform Users Guide or the BSP/LSP documentation for - * more specific information. - * - * For Linux (at the Redboot prompt i.e., before loading zImage): - * mfill -b 0x54100000 -1 -l 1 -p 8 - * mfill -b 0x54100001 -1 -l 1 -p 0x7f - * For vxWorks, at the prompt: - * intDisable(25) - * ixdp400FpgaIODetach(8) - * - * - * @li Re-entrant : no - * @li ISR Callable : no - * - * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful - * @li IX_TIMESYNCACC_INVALIDPARAM - Null parameter passed for callback or - invalid auxiliary snapshot mode - * @li IX_TIMESYNCACC_FAILED - Internal error occurred - */ -PUBLIC IxTimeSyncAccStatus -ixTimeSyncAccAuxTimeInterruptEnable(IxTimeSyncAccAuxMode auxMode, - IxTimeSyncAccAuxTimeCallback auxTimeCallback); - -/** - * @ingroup IxTimeSyncAcc - * - * @fn IxTimeSyncAccStatus ixTimeSyncAccAuxTimeInterruptDisable( - IxTimeSyncAccAuxMode auxMode) - * - * @brief Disables the interrupt for the indicated mode of Auxiliary Time Stamp - * in the IEEE 1588 hardware assist block - * - * @param auxMode [in] - Auxiliary time stamp mode (slave or master) using which - * the interrupt will be disabled. - * - * This API will disable the Auxiliary Time Stamp Interrupt (Master or Slave) - * - * @li Re-entrant : yes - * @li ISR Callable : no - * - * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful - * @li IX_TIMESYNCACC_INVALIDPARAM - Invalid parameters passed - * @li IX_TIMESYNCACC_FAILED - Internal error occurred - */ -PUBLIC IxTimeSyncAccStatus -ixTimeSyncAccAuxTimeInterruptDisable(IxTimeSyncAccAuxMode auxMode); - -/** - * @ingroup IxTimeSyncAcc - * - * @fn IxTimeSyncAccStatus ixTimeSyncAccAuxTimePoll( - IxTimeSyncAccAuxMode auxMode, - BOOL *auxPollFlag, - IxTimeSyncAccTimeValue *auxTime) - * - * @brief Poll for the Auxiliary Time Stamp captured for the mode indicated - * (Master or Slave) - * - * @param auxMode [in] - Auxiliary Snapshot Register (Slave or Master) to be checked - * @param auxPollFlag [out] - TRUE if the time stamp captured in auxiliary - snapshot register - * FALSE if the time stamp not captured in - auxiliary snapshot register - * @param auxTime [out] - Copy the current Auxiliary Snapshot Register value into the - * client provided buffer - * - * Polls for the Time stamp in the appropriate Auxiliary Snapshot Registers based - * on the mode specified. Return true and the contents of the Auxiliary snapshot, - * if it is available else return false. - * - * Please refer to the note #2 of the API @ref ixTimeSyncAccAuxTimeInterruptEnable - * for more information for Auxiliary Slave mode. - * - * @li Re-entrant : yes - * @li ISR Callable : no - * - * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful - * @li IX_TIMESYNCACC_INVALIDPARAM - Null parameter passed for auxPollFlag, - callback or invalid auxiliary snapshot mode - * @li IX_TIMESYNCACC_FAILED - Internal error occurred - * @li IX_TIMESYNCACC_INTERRUPTMODEINUSE - Interrupt mode in use - */ -PUBLIC IxTimeSyncAccStatus -ixTimeSyncAccAuxTimePoll(IxTimeSyncAccAuxMode auxMode, - BOOL *auxPollFlag, - IxTimeSyncAccTimeValue *auxTime); - -/** - * @ingroup IxTimeSyncAcc - * - * @fn IxTimeSyncAccStatus ixTimeSyncAccReset(void) - * - * @brief Resets the IEEE 1588 hardware assist block - * - * Sets the reset bit in the IEEE1588 silicon which fully resets the silicon block - * - * @li Reentrant : yes - * @li ISR Callable : no - * - * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful - * @li IX_TIMESYNCACC_FAILED - Internal error occurred - */ -PUBLIC IxTimeSyncAccStatus -ixTimeSyncAccReset(void); - -/** - * @ingroup IxTimeSyncAcc - * - * @fn IxTimeSyncAccStatus ixTimeSyncAccStatsGet(IxTimeSyncAccStats - *timeSyncStats) - * - * @brief Returns the IxTimeSyncAcc Statistics in the client supplied buffer - * - * @param timeSyncStats [out] - TimeSync statistics counter values - * - * This API will return the statistics of the received or transmitted messages. - * - * NOTE: 1) These counters are updated only when the client polls for the time - * stamps or interrupt are enabled. This is because the IxTimeSyncAcc module - * does not either transmit or receive messages and does only run the code - * when explicit requests received by client application. - * - * 2) These statistics reflect the number of valid PTP messages exchanged - * in Master and Slave modes but includes all the messages (including valid - * non-PTP messages) while operating in the Any mode. - * - * @li Reentrant : no - * @li ISR Callable : no - * - * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful - * @li IX_TIMESYNCACC_INVALIDPARAM - NULL parameter passed - * @li IX_TIMESYNCACC_FAILED - Internal error occurred - */ -PUBLIC IxTimeSyncAccStatus -ixTimeSyncAccStatsGet(IxTimeSyncAccStats *timeSyncStats); - -/** - * @ingroup IxTimeSyncAcc - * - * @fn void ixTimeSyncAccStatsReset(void) - * - * @brief Reset Time Sync statistics - * - * This API will reset the statistics counters of the TimeSync access layer. - * - * @li Reentrant : yes - * @li ISR Callable: no - * - * @return @li None - */ -PUBLIC void -ixTimeSyncAccStatsReset(void); - -/** - * @ingroup IxTimeSyncAcc - * - * @fn IxTimeSyncAccStatus ixTimeSyncAccShow(void) - * - * @brief Displays the Time Sync current status - * - * This API will display status on the current configuration of the IEEE - * 1588 hardware assist block, contents of the various time stamp registers, - * outstanding interrupts and/or events. - * - * Note that this is intended for debug only, and in contrast to the other - * functions, it does not clear the any of the status bits associated with - * active timestamps and so is passive in its nature. - * - * @li Reentrant : yes - * @li ISR Callable : no - * - * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful - * @li IX_TIMESYNCACC_FAILED - Internal error occurred - */ -PUBLIC IxTimeSyncAccStatus -ixTimeSyncAccShow(void); - -#endif /* __ixp46X */ -#endif /* IXTIMESYNCACC_H */ - -/** - * @} defgroup IxTimeSyncAcc - */ - diff --git a/cpu/ixp/npe/include/IxTimerCtrl.h b/cpu/ixp/npe/include/IxTimerCtrl.h deleted file mode 100644 index 669dd3ef28..0000000000 --- a/cpu/ixp/npe/include/IxTimerCtrl.h +++ /dev/null @@ -1,263 +0,0 @@ -/** - * @file IxTimerCtrl.h - * @brief - * This is the header file for the Timer Control component. - * - * The timer callback control component provides a mechanism by which different - * client components can start a timer and have a supplied callback function - * invoked when the timer expires. - * The callbacks are all dispatched from one thread inside this component. - * Any component that needs to be called periodically should use this facility - * rather than create its own task with a sleep loop. - * - * @par - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- -*/ - -/** - * @defgroup IxTimerCtrl IXP400 Timer Control (IxTimerCtrl) API - * - * @brief The public API for the IXP400 Timer Control Component. - * - * @{ - */ - -#ifndef IxTimerCtrl_H -#define IxTimerCtrl_H - - -#include "IxTypes.h" -/* #include "Ossl.h" */ - -/* - * #defines and macros used in this file. - */ - -/** - * @ingroup IxTimerCtrl - * - * @def IX_TIMERCTRL_NO_FREE_TIMERS - * - * @brief Timer schedule return code. - * - * Indicates that the request to start a timer failed because - * all available timer resources are used. - */ -#define IX_TIMERCTRL_NO_FREE_TIMERS 2 - - -/** - * @ingroup IxTimerCtrl - * - * @def IX_TIMERCTRL_PARAM_ERROR - * - * @brief Timer schedule return code. - * - * Indicates that the request to start a timer failed because - * the client has supplied invalid parameters. - */ -#define IX_TIMERCTRL_PARAM_ERROR 3 - - -/* - * Typedefs whose scope is limited to this file. - */ - -/** - * @ingroup IxTimerCtrl - * - * @brief A typedef for a pointer to a timer callback function. - * @para void * - This parameter is supplied by the client when the - * timer is started and passed back to the client in the callback. - * @note in general timer callback functions should not block or - * take longer than 100ms. This constraint is required to ensure that - * higher priority callbacks are not held up. - * All callbacks are called from the same thread. - * This thread is a shared resource. - * The parameter passed is provided when the timer is scheduled. - */ -typedef void (*IxTimerCtrlTimerCallback)(void *userParam); - - -/** - * @ingroup IxTimerCtrl - * - * @brief List used to identify the users of timers. - * @note The order in this list indicates priority. Components appearing - * higher in the list will be given priority over components lower in the - * list. When adding components, please insert at an appropriate position - * for priority ( i.e values should be less than IxTimerCtrlMaxPurpose ) . - */ -typedef enum -{ - IxTimerCtrlAdslPurpose, - /* Insert new purposes above this line only - */ - IxTimerCtrlMaxPurpose -} -IxTimerCtrlPurpose; - - -/* - * Function definition - */ - -/** - * @ingroup IxTimerCtrl - * - * @fn ixTimerCtrlSchedule(IxTimerCtrlTimerCallback func, - void *userParam, - IxTimerCtrlPurpose purpose, - UINT32 relativeTime, - unsigned *timerId ) - * - * @brief Schedules a callback function to be called after a period of "time". - * The callback function should not block or run for more than 100ms. - * This function - * - * @param func @ref IxTimerCtrlTimerCallback [in] - the callback function to be called. - * @param userParam void [in] - a parameter to send to the callback function, can be NULL. - * @param purpose @ref IxTimerCtrlPurpose [in] - the purpose of the callback, internally this component will - * decide the priority of callbacks with different purpose. - * @param relativeTime UINT32 [in] - time relative to now in milliseconds after which the callback - * will be called. The time must be greater than the duration of one OS tick. - * @param *timerId unsigned [out] - An id for the callback scheduled. - * This id can be used to cancel the callback. - * @return - * @li IX_SUCCESS - The timer was started successfully. - * @li IX_TIMERCTRL_NO_FREE_TIMERS - The timer was not started because the maximum number - * of running timers has been exceeded. - * @li IX_TIMERCTRL_PARAM_ERROR - The timer was not started because the client has supplied - * a NULL callback func, or the requested timeout is less than one OS tick. - * @note This function is re-entrant. The function accesses a list of running timers - * and may suspend the calling thread if this list is being accesed by another thread. - */ -PUBLIC IX_STATUS -ixTimerCtrlSchedule(IxTimerCtrlTimerCallback func, - void *userParam, - IxTimerCtrlPurpose purpose, - UINT32 relativeTime, - unsigned *timerId ); - - -/** - * @ingroup IxTimerCtrl - * - * @fn ixTimerCtrlScheduleRepeating(IxTimerCtrlTimerCallback func, - void *param, - IxTimerCtrlPurpose purpose, - UINT32 interval, - unsigned *timerId ) - * - * @brief Schedules a callback function to be called after a period of "time". - * The callback function should not block or run for more than 100ms. - * - * @param func @ref IxTimerCtrlTimerCallback [in] - the callback function to be called. - * @param userParam void [in] - a parameter to send to the callback function, can be NULL. - * @param purpose @ref IxTimerCtrlPurpose [in] - the purpose of the callback, internally this component will - * decide the priority of callbacks with different purpose. - * @param interval UINT32 [in] - the interval in milliseconds between calls to func. - * @param timerId unsigned [out] - An id for the callback scheduled. - * This id can be used to cancel the callback. - * @return - * @li IX_SUCCESS - The timer was started successfully. - * @li IX_TIMERCTRL_NO_FREE_TIMERS - The timer was not started because the maximum number - * of running timers has been exceeded. - * @li IX_TIMERCTRL_PARAM_ERROR - The timer was not started because the client has supplied - * a NULL callback func, or the requested timeout is less than one OS tick. - * @note This function is re-entrant. The function accesses a list of running timers - * and may suspend the calling thread if this list is being accesed by another thread. - */ -PUBLIC IX_STATUS -ixTimerCtrlScheduleRepeating(IxTimerCtrlTimerCallback func, - void *param, - IxTimerCtrlPurpose purpose, - UINT32 interval, - unsigned *timerId ); - -/** - * @ingroup IxTimerCtrl - * - * @fn ixTimerCtrlCancel (unsigned id) - * - * @brief Cancels a scheduled callback. - * - * @param id unsigned [in] - the id of the callback to be cancelled. - * @return - * @li IX_SUCCESS - The timer was successfully stopped. - * @li IX_FAIL - The id parameter did not corrrespond to any running timer.. - * @note This function is re-entrant. The function accesses a list of running timers - * and may suspend the calling thread if this list is being accesed by another thread. - */ -PUBLIC IX_STATUS -ixTimerCtrlCancel (unsigned id); - -/** - * @ingroup IxTimerCtrl - * - * @fn ixTimerCtrlInit(void) - * - * @brief Initialise the Timer Control Component. - * @return - * @li IX_SUCCESS - The timer control component initialized successfully. - * @li IX_FAIL - The timer control component initialization failed, - * or the component was already initialized. - * @note This must be done before any other API function is called. - * This function should be called once only and is not re-entrant. - */ -PUBLIC IX_STATUS -ixTimerCtrlInit(void); - - -/** - * @ingroup IxTimerCtrl - * - * @fn ixTimerCtrlShow( void ) - * - * @brief Display the status of the Timer Control Component. - * @return void - * @note Displays a list of running timers. - * This function is not re-entrant. This function does not suspend the calling thread. - */ -PUBLIC void -ixTimerCtrlShow( void ); - -#endif /* IXTIMERCTRL_H */ - diff --git a/cpu/ixp/npe/include/IxTypes.h b/cpu/ixp/npe/include/IxTypes.h deleted file mode 100644 index c4c5a2d267..0000000000 --- a/cpu/ixp/npe/include/IxTypes.h +++ /dev/null @@ -1,86 +0,0 @@ -/** - * @file IxTypes.h (Replaced by OSAL) - * - * @date 28-NOV-2001 - - * @brief This file contains basic types used by the IXP400 software - * - * Design Notes: - * This file shall only include fundamental types and definitions to be - * shared by all the IXP400 components. - * Please DO NOT add component-specific types here. - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -/** - * @defgroup IxTypes IXP400 Types (IxTypes) - * - * @brief Basic data types used by the IXP400 project - * - * @{ - */ - -#ifndef IxTypes_H - -#ifndef __doxygen_HIDE - -#define IxTypes_H - -#endif /* __doxygen_HIDE */ - - -/* WR51880: Undefined data types workaround for backward compatibility */ -#ifdef __linux -#ifndef __INCvxTypesOldh -typedef int (*FUNCPTR)(void); -typedef int STATUS; -#define OK (0) -#define ERROR (-1) -#endif -#endif - -#include "IxOsalBackward.h" - -#endif /* IxTypes_H */ - -/** - * @} addtogroup IxTypes - */ diff --git a/cpu/ixp/npe/include/IxUART.h b/cpu/ixp/npe/include/IxUART.h deleted file mode 100644 index 03a44441c5..0000000000 --- a/cpu/ixp/npe/include/IxUART.h +++ /dev/null @@ -1,458 +0,0 @@ -/** - * @file IxUART.h - * - * @date 12-OCT-01 - * - * @brief Public header for the Intel IXP400 internal UART, generic driver. - * - * Design Notes: - * This driver allows you to perform the following functions: - * Device Initialization, - * send/receive characters. - * - * Perform Uart IOCTL for the following: - * Set/Get the current baud rate, - * set parity, - * set the number of Stop bits, - * set the character Length (5,6,7,8), - * enable/disable Hardware flow control. - * - * Only Polled mode is supported for now. - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- -*/ - -/** - * @defgroup IxUARTAccAPI IXP400 UART Access (IxUARTAcc) API - * - * @brief IXP400 UARTAcc Driver Public API - * - * @{ - */ - - -/* Defaults */ - -/** - * @defgroup DefaultDefines Defines for Default Values - * - * @brief Default values which can be used for UART configuration - * - * @sa ixUARTDev - */ - -/** - * @def IX_UART_DEF_OPTS - * - * @brief The default hardware options to set the UART to - - * no flow control, 8 bit word, 1 stop bit, no parity - * - * @ingroup DefaultDefines - */ -#define IX_UART_DEF_OPTS (CLOCAL | CS8) - -/** - * @def IX_UART_DEF_XMIT - * - * @brief The default UART FIFO size - must be no bigger than 64 - * - * @ingroup DefaultDefines - */ -#define IX_UART_DEF_XMIT 64 - -/** - * @def IX_UART_DEF_BAUD - * - * @brief The default UART baud rate - 9600 - * - * @ingroup DefaultDefines - */ -#define IX_UART_DEF_BAUD 9600 - -/** - * @def IX_UART_MIN_BAUD - * - * @brief The minimum UART baud rate - 9600 - * - * @ingroup DefaultDefines - */ -#define IX_UART_MIN_BAUD 9600 - -/** - * @def IX_UART_MAX_BAUD - * - * @brief The maximum UART baud rate - 926100 - * - * @ingroup DefaultDefines - */ -#define IX_UART_MAX_BAUD 926100 - -/** - * @def IX_UART_XTAL - * - * @brief The UART clock speed - * - * @ingroup DefaultDefines - */ -#define IX_UART_XTAL 14745600 - - - -/* IOCTL commands (Request codes) */ - -/** - * @defgroup IoctlCommandDefines Defines for IOCTL Commands - * - * @brief IOCTL Commands (Request codes) which can be used - * with @ref ixUARTIoctl - */ - - -/** - * @ingroup IoctlCommandDefines - * - * @def IX_BAUD_SET - * - * @brief Set the baud rate - */ -#define IX_BAUD_SET 0 - -/** - * @ingroup IoctlCommandDefines - * - * @def IX_BAUD_GET - * - * @brief Get the baud rate - */ -#define IX_BAUD_GET 1 - -/** - * @ingroup IoctlCommandDefines - * @def IX_MODE_SET - * @brief Set the UART mode of operation - */ -#define IX_MODE_SET 2 - -/** - * @ingroup IoctlCommandDefines - * - * @def IX_MODE_GET - * - * @brief Get the current UART mode of operation - */ -#define IX_MODE_GET 3 - -/** - * @ingroup IoctlCommandDefines - * - * @def IX_OPTS_SET - * - * @brief Set the UART device options - */ -#define IX_OPTS_SET 4 - -/** - * @ingroup IoctlCommandDefines - * - * @def IX_OPTS_GET - * - * @brief Get the UART device options - */ -#define IX_OPTS_GET 5 - -/** - * @ingroup IoctlCommandDefines - * - * @def IX_STATS_GET - * - * @brief Get the UART statistics - */ -#define IX_STATS_GET 6 - - -/* POSIX style ioctl arguments */ - -/** - * @defgroup IoctlArgDefines Defines for IOCTL Arguments - * - * @brief POSIX style IOCTL arguments which can be used - * with @ref ixUARTIoctl - * - * @sa ixUARTMode - */ - - -/** - * @ingroup IoctlArgDefines - * - * @def CLOCAL - * - * @brief Software flow control - */ -#ifdef CLOCAL -#undef CLOCAL -#endif -#define CLOCAL 0x1 - -/** - * @ingroup IoctlArgDefines - * - * @def CREAD - * - * @brief Enable interrupt receiver - */ -#ifdef CREAD -#undef CREAD -#endif -#define CREAD 0x2 - -/** - * @ingroup IoctlArgDefines - * - * @def CSIZE - * - * @brief Characters size - */ -#ifdef CSIZE -#undef CSIZE -#endif -#define CSIZE 0xc - -/** - * @ingroup IoctlArgDefines - * - * @def CS5 - * - * @brief 5 bits - */ -#ifdef CS5 -#undef CS5 -#endif -#define CS5 0x0 - -/** - * @ingroup IoctlArgDefines - * - * @def CS6 - * - * @brief 6 bits - */ -#ifdef CS6 -#undef CS6 -#endif -#define CS6 0x4 - -/** - * @ingroup IoctlArgDefines - * - * @def CS7 - * - * @brief 7 bits - */ -#ifdef CS7 -#undef CS7 -#endif -#define CS7 0x8 - -/** - * @ingroup IoctlArgDefines - * - * @def CS8 - * - * @brief 8 bits - */ -#ifdef CS8 -#undef CS8 -#endif -#define CS8 0xc - -/** - * @ingroup IoctlArgDefines - * - * @def STOPB - * - * @brief Send two stop bits (else one) - */ -#define STOPB 0x20 - -/** - * @ingroup IoctlArgDefines - * - * @def PARENB - * - * @brief Parity detection enabled (else disabled) - */ -#ifdef PARENB -#undef PARENB -#endif -#define PARENB 0x40 - -/** - * @ingroup IoctlArgDefines - * - * @def PARODD - * - * @brief Odd parity (else even) - */ -#ifdef PARODD -#undef PARODD -#endif -#define PARODD 0x80 - -/** - * @enum ixUARTMode - * @brief The mode to set to UART to. - */ -typedef enum -{ - INTERRUPT=0, /**< Interrupt mode */ - POLLED, /**< Polled mode */ - LOOPBACK /**< Loopback mode */ -} ixUARTMode; - -/** - * @struct ixUARTStats - * @brief Statistics for the UART. - */ -typedef struct -{ - UINT32 rxCount; - UINT32 txCount; - UINT32 overrunErr; - UINT32 parityErr; - UINT32 framingErr; - UINT32 breakErr; -} ixUARTStats; - -/** - * @struct ixUARTDev - * @brief Device descriptor for the UART. - */ -typedef struct -{ - UINT8 *addr; /**< device base address */ - ixUARTMode mode; /**< interrupt, polled or loopback */ - int baudRate; /**< baud rate */ - int freq; /**< UART clock frequency */ - int options; /**< hardware options */ - int fifoSize; /**< FIFO xmit size */ - - ixUARTStats stats; /**< device statistics */ -} ixUARTDev; - -/** - * @ingroup IxUARTAccAPI - * - * @fn IX_STATUS ixUARTInit(ixUARTDev* pUART) - * - * @param pUART @ref ixUARTDev [in] - pointer to UART structure describing our device. - * - * @brief Initialise the UART. This puts the chip in a quiescent state. - * - * @pre The base address for the UART must contain a valid value. - * Also the baud rate and hardware options must contain sensible values - * otherwise the defaults will be used as defined in ixUART.h - * - * @post UART is initialized and ready to send and receive data. - * - * @note This function should only be called once per device. - * - * @retval IX_SUCCESS - UART device successfully initialised. - * @retval IX_FAIL - Critical error, device not initialised. - ***************************************************************************/ -PUBLIC IX_STATUS ixUARTInit(ixUARTDev* pUART); - -/** - * @ingroup IxUARTAccAPI - * - * @fn IX_STATUS ixUARTPollOutput(ixUARTDev* pUART, int outChar) - * - * @param pUART @ref ixUARTDev [out] - pointer to UART structure describing our device. - * @param outChar int [out] - character to transmit. - * - * @brief Transmit a character in polled mode. - * - * @pre UART device must be initialised. - * - * @retval IX_SUCCESS - character was successfully transmitted. - * @retval IX_FAIL - output buffer is full (try again). - ***************************************************************************/ -PUBLIC IX_STATUS ixUARTPollOutput(ixUARTDev* pUART, int outChar); - -/** - * @ingroup IxUARTAccAPI - * - * @fn IX_STATUS ixUARTPollInput(ixUARTDev* pUART, char *inChar) - * - * @param pUART @ref ixUARTDev [in] - pointer to UART structure describing our device. - * @param *inChar char [in] - character read from the device. - * - * @brief Receive a character in polled mode. - * - * @pre UART device must be initialised. - * - * @retval IX_SUCCESS - character was successfully read. - * @retval IX_FAIL - input buffer empty (try again). - ***************************************************************************/ -PUBLIC IX_STATUS ixUARTPollInput(ixUARTDev* pUART, char *inChar); - -/** - * @ingroup IxUARTAccAPI - * - * @fn IX_STATUS ixUARTIoctl(ixUARTDev* pUART, int cmd, void* arg) - * - * @param pUART @ref ixUARTDev [in] - pointer to UART structure describing our device. - * @param cmd int [in] - an ioctl request code. - * @param arg void* [in] - optional argument used to set the device mode, - * baud rate, and hardware options. - * - * @brief Perform I/O control routines on the device. - * - * @retval IX_SUCCESS - requested feature was set/read successfully. - * @retval IX_FAIL - error setting/reading the requested feature. - * - * @sa IoctlCommandDefines - * @sa IoctlArgDefines - ***************************************************************************/ -PUBLIC IX_STATUS ixUARTIoctl(ixUARTDev* pUART, int cmd, void* arg); - -/** - * @} defgroup IxUARTAcc - */ diff --git a/cpu/ixp/npe/include/IxVersionId.h b/cpu/ixp/npe/include/IxVersionId.h deleted file mode 100644 index 27796ede84..0000000000 --- a/cpu/ixp/npe/include/IxVersionId.h +++ /dev/null @@ -1,155 +0,0 @@ -/** - * @file IxVersionId.h - * - * @date 22-Aug-2002 - * - * @brief This file contains the IXP400 Software version identifier - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -/** - * @defgroup IxVersionId IXP400 Version ID (IxVersionId) - * - * @brief Version Identifiers - * - * @{ - */ - -#ifndef IXVERSIONID_H -#define IXVERSIONID_H - -/** - * @brief Version Identifier String - * - * This string will be updated with each customer release of the IXP400 - * Software. - */ -#define IX_VERSION_ID "2_0" - -/** - * This string will be updated with each customer release of the IXP400 - * ADSL driver package. - */ -#define IX_VERSION_ADSL_ID "1_12" - - -/** - * This string will be updated with each customer release of the IXP400 - * USB Client driver package. - */ -#define IX_VERSION_USBRNDIS_ID "1_9" - -/** - * This string will be updated with each customer release of the IXP400 - * I2C Linux driver package. - */ -#define IX_VERSION_I2C_LINUX_ID "1_0" - -/** - * @brief Linux Ethernet Driver Patch Version Identifier String - * - * This string will be updated with each release of Linux Ethernet Patch - */ -#define LINUX_ETHERNET_DRIVER_PATCH_ID "1_4" - -/** - * @brief Linux Integration Patch Version Identifier String - * - * This String will be updated with each release of Linux Integration Patch - */ -#define LINUX_INTEGRATION_PATCH_ID "1_3" - -/** - * @brief Linux Ethernet Readme version Identifier String - * - * This string will be updated with each release of Linux Ethernet Readme - */ -#define LINUX_ETHERNET_README_ID "1_3" - -/** - * @brief Linux Integration Readme version Identifier String - * - * This string will be updated with each release of Linux Integration Readme - */ - -#define LINUX_INTEGRATION_README_ID "1_3" - -/** - * @brief Linux I2C driver Readme version Identifier String - * - * This string will be updated with each release of Linux I2C Driver Readme - */ -#define LINUX_I2C_DRIVER_README_ID "1_0" - -/** - * @brief ixp425_eth_update_nf_bridge.patch version Identifier String - * - * This string will be updated with each release of ixp425_eth_update_nf_bridge. -patch - * - */ - -#define IXP425_ETH_UPDATE_NF_BRIDGE_ID "1_3" - -/** - * @brief Internal Release Identifier String - * - * This string will be updated with each internal release (SQA drop) - * of the IXP400 Software. - */ -#define IX_VERSION_INTERNAL_ID "SQA3_5" - -/** - * @brief Compatible Tornado Version Identifier - */ -#define IX_VERSION_COMPATIBLE_TORNADO "Tornado2_2_1-PNE2_0" - -/** - * @brief Compatible Linux Version Identifier - */ -#define IX_VERSION_COMPATIBLE_LINUX "MVL3_1" - - -#endif /* IXVERSIONID_H */ - -/** - * @} addtogroup IxVersionId - */ diff --git a/cpu/ixp/npe/include/ix_error.h b/cpu/ixp/npe/include/ix_error.h deleted file mode 100644 index d32ace20b5..0000000000 --- a/cpu/ixp/npe/include/ix_error.h +++ /dev/null @@ -1,66 +0,0 @@ -/** - * ============================================================================ - * = COPYRIGHT - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - * = PRODUCT - * Intel(r) IXP425 Software Release - * - * = FILENAME - * ix_error.h (Replaced by OSAL) - * - * = DESCRIPTION - * This file will describe the basic error type and support functions that - * will be used by the IXA SDK Framework API. - * - * = AUTHOR - * Intel Corporation - * - * = CHANGE HISTORY - * 4/22/2002 4:19:03 PM - creation time - * ============================================================================ - */ - -#if !defined(__IX_ERROR_H__) -#define __IX_ERROR_H__ - -#include "IxOsalBackward.h" - -#endif /* end !defined(__IX_ERROR_H__) */ - diff --git a/cpu/ixp/npe/include/ix_macros.h b/cpu/ixp/npe/include/ix_macros.h deleted file mode 100644 index 53f5942f97..0000000000 --- a/cpu/ixp/npe/include/ix_macros.h +++ /dev/null @@ -1,266 +0,0 @@ -/** - * ============================================================================ - * = COPYRIGHT - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - * = PRODUCT - * Intel(r) IXP425 Software Release - * - * = FILENAME - * ix_macros.h - * - * = DESCRIPTION - * This file will define the basic preprocessor macros that are going to be used - * the IXA SDK Framework API. - * - * = AUTHOR - * Intel Corporation - * - * = CHANGE HISTORY - * 4/22/2002 4:41:05 PM - creation time - * ============================================================================ - */ - -#if !defined(__IX_MACROS_H__) -#define __IX_MACROS_H__ - - -#if defined(__cplusplus) -extern "C" -{ -#endif /* end defined(__cplusplus) */ - - -/** - * MACRO NAME: IX_BIT_FIELD_MASK16 - * - * DESCRIPTION: Builds the mask required to extract the bit field from a 16 bit unsigned integer value. - * - * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant - * bit of the bit field. - * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant - * bit of the bit field. - * - * @Return: Returns a 16 bit mask that will extract the bit field from a 16 bit unsigned integer value. - */ -#define IX_BIT_FIELD_MASK16( \ - arg_FieldLSBBit, \ - arg_FieldMSBBit \ - ) \ - ((ix_bit_mask16)((((ix_uint16)1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - \ - (ix_uint16)1) << arg_FieldLSBBit)) - - - -/** - * MACRO NAME: IX_GET_BIT_FIELD16 - * - * DESCRIPTION: Extracts a bit field from 16 bit unsigned integer. The returned value is normalized in - * in the sense that will be right aligned. - * - * @Param: - IN arg_PackedData16 a 16 bit unsigned integer that contains the bit field of interest. - * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant - * bit of the bit field. - * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant - * bit of the bit field. - * - * @Return: Returns the value of the bit field. The value can be from 0 to (1 << (arg_FieldMSBBit + 1 - - * arg_FieldLSBBit)) - 1. - */ -#define IX_GET_BIT_FIELD16( \ - arg_PackedData16, \ - arg_FieldLSBBit, \ - arg_FieldMSBBit \ - ) \ - (((ix_uint16)(arg_PackedData16) & IX_BIT_FIELD_MASK16(arg_FieldLSBBit, arg_FieldMSBBit)) >> \ - arg_FieldLSBBit) - - -/** - * MACRO NAME: IX_MAKE_BIT_FIELD16 - * - * DESCRIPTION: This macro will create a temporary 16 bit value with the bit field - * desired set to the desired value. - * - * @Param: - IN arg_BitFieldValue is the new value of the bit field. The value can be from 0 to - * (1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - 1. - * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant - * bit of the bit field. - * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant - * bit of the bit field. - * - * @Return: Returns a temporary ix_uint16 value that has the bit field set to the appropriate value. - */ -#define IX_MAKE_BIT_FIELD16( \ - arg_BitFieldValue, \ - arg_FieldLSBBit, \ - arg_FieldMSBBit \ - ) \ - (((ix_uint16)(arg_BitFieldValue) << arg_FieldLSBBit) & \ - IX_BIT_FIELD_MASK16(arg_FieldLSBBit, arg_FieldMSBBit)) - -/** - * MACRO NAME: IX_SET_BIT_FIELD16 - * - * DESCRIPTION: Sets a new value for a bit field from a 16 bit unsigned integer. - * - * @Param: - IN arg_PackedData16 a 16 bit unsigned integer that contains the bit field of interest. - * @Param: - IN arg_BitFieldValue is the new vale of the bit field. The value can be from 0 to - * (1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - 1. - * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant - * bit of the bit field. - * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant - * bit of the bit field. - * - * @Return: Returns the updated value of arg_PackedData16. - */ -#define IX_SET_BIT_FIELD16( \ - arg_PackedData16, \ - arg_BitFieldValue, \ - arg_FieldLSBBit, \ - arg_FieldMSBBit \ - ) \ - (arg_PackedData16 = (((ix_uint16)(arg_PackedData16) & \ - ~(IX_BIT_FIELD_MASK16(arg_FieldLSBBit, arg_FieldMSBBit))) | \ - IX_MAKE_BIT_FIELD16(arg_BitFieldValue, arg_FieldLSBBit, arg_FieldMSBBit))) - - -/** - * MACRO NAME: IX_BIT_FIELD_MASK32 - * - * DESCRIPTION: Builds the mask required to extract the bit field from a 32 bit unsigned integer value. - * - * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant - * bit of the bit field. - * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant - * bit of the bit field. - * - * @Return: Returns a 32 bit mask that will extract the bit field from a 32 bit unsigned integer value. - */ -#define IX_BIT_FIELD_MASK32( \ - arg_FieldLSBBit, \ - arg_FieldMSBBit \ - ) \ - ((ix_bit_mask32)((((ix_uint32)1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - \ - (ix_uint32)1) << arg_FieldLSBBit)) - - - -/** - * MACRO NAME: IX_GET_BIT_FIELD32 - * - * DESCRIPTION: Extracts a bit field from 32 bit unsigned integer. The returned value is normalized in - * in the sense that will be right aligned. - * - * @Param: - IN arg_PackedData32 a 32 bit unsigned integer that contains the bit field of interest. - * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant - * bit of the bit field. - * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant - * bit of the bit field. - * - * @Return: Returns the value of the bit field. The value can be from 0 to (1 << (arg_FieldMSBBit + 1 - - * arg_FieldLSBBit)) - 1. - */ -#define IX_GET_BIT_FIELD32( \ - arg_PackedData32, \ - arg_FieldLSBBit, \ - arg_FieldMSBBit \ - ) \ - (((ix_uint32)(arg_PackedData32) & IX_BIT_FIELD_MASK32(arg_FieldLSBBit, arg_FieldMSBBit)) >> \ - arg_FieldLSBBit) - - - - -/** - * MACRO NAME: IX_MAKE_BIT_FIELD32 - * - * DESCRIPTION: This macro will create a temporary 32 bit value with the bit field - * desired set to the desired value. - * - * @Param: - IN arg_BitFieldValue is the new value of the bit field. The value can be from 0 to - * (1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - 1. - * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant - * bit of the bit field. - * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant - * bit of the bit field. - * - * @Return: Returns a temporary ix_uint32 value that has the bit field set to the appropriate value. - */ -#define IX_MAKE_BIT_FIELD32( \ - arg_BitFieldValue, \ - arg_FieldLSBBit, \ - arg_FieldMSBBit \ - ) \ - (((ix_uint32)(arg_BitFieldValue) << arg_FieldLSBBit) & \ - IX_BIT_FIELD_MASK32(arg_FieldLSBBit, arg_FieldMSBBit)) - - -/** - * MACRO NAME: IX_SET_BIT_FIELD32 - * - * DESCRIPTION: Sets a new value for a bit field from a 32 bit unsigned integer. - * - * @Param: - IN arg_PackedData32 a 32 bit unsigned integer that contains the bit field of interest. - * @Param: - IN arg_BitFieldValue is the new value of the bit field. The value can be from 0 to - * (1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - 1. - * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant - * bit of the bit field. - * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant - * bit of the bit field. - * - * @Return: Returns the updated value of arg_PackedData32. - */ -#define IX_SET_BIT_FIELD32( \ - arg_PackedData32, \ - arg_BitFieldValue, \ - arg_FieldLSBBit, \ - arg_FieldMSBBit \ - ) \ - (arg_PackedData32 = (((ix_uint32)(arg_PackedData32) & \ - ~(IX_BIT_FIELD_MASK32(arg_FieldLSBBit, arg_FieldMSBBit))) | \ - IX_MAKE_BIT_FIELD32(arg_BitFieldValue, arg_FieldLSBBit, arg_FieldMSBBit))) - - - -#if defined(__cplusplus) -} -#endif /* end defined(__cplusplus) */ - -#endif /* end !defined(__IX_MACROS_H__) */ diff --git a/cpu/ixp/npe/include/ix_os_type.h b/cpu/ixp/npe/include/ix_os_type.h deleted file mode 100644 index 8575096722..0000000000 --- a/cpu/ixp/npe/include/ix_os_type.h +++ /dev/null @@ -1,65 +0,0 @@ -/** - * ============================================================================ - * = COPYRIGHT - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - * = PRODUCT - * Intel(r) IXP425 Software Release - * - * = FILENAME - * ix_os_type.h (Replaced by OSAL) - * - * = DESCRIPTION - * This file provides protable symbol definitions for the current OS type. - * - * = AUTHOR - * Intel Corporation - * - * = CHANGE HISTORY - * 4/22/2002 4:43:30 PM - creation time - * ============================================================================ - */ - -#if !defined(__IX_OS_TYPE_H__) -#define __IX_OS_TYPE_H__ - -#include "IxOsalBackward.h" - -#endif /* end !defined(__IX_OS_TYPE_H__) */ - diff --git a/cpu/ixp/npe/include/ix_ossl.h b/cpu/ixp/npe/include/ix_ossl.h deleted file mode 100644 index b59f7d0873..0000000000 --- a/cpu/ixp/npe/include/ix_ossl.h +++ /dev/null @@ -1,160 +0,0 @@ -/** - * ============================================================================ - * = COPYRIGHT - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - * = PRODUCT - * Intel(r) IXP425 Software Release - * - * = LIBRARY - * OSSL - Operating System Services Library - * - * = MODULE - * OSSL Abstraction layer header file - * - * = FILENAME - * ix_ossl.h (Replaced by OSAL) - * - * = DESCRIPTION - * This file contains the prototypes of OS-independent wrapper - * functions which allow the programmer not to be tied to a specific - * operating system. The OSSL functions can be divided into three classes: - * - * 1) synchronization-related wrapper functions around thread system calls - * 2) thread-related wrapper functions around thread calls - * 3) transactor/workbench osapi calls -- defined in osApi.h - * - * Both 1 and 2 classes of functions provide Thread Management, Thread - * Synchronization, Mutual Exclusion and Timer primitives. Namely, - * creation and deletion functions as well as the standard "wait" and - * "exit". Additionally, a couple of utility functions which enable to - * pause the execution of a thread are also provided. - * - * The 3rd class provides a slew of other OSAPI functions to handle - * Transactor/WorkBench OS calls. - * - * - * OSSL Thread APIs: - * The OSSL thread functions that allow for thread creation, - * get thread id, thread deletion and set thread priroity. - * - * ix_ossl_thread_create - * ix_ossl_thread_get_id - * ix_ossl_thread_exit - * ix_ossl_thread_kill - * ix_ossl_thread_set_priority - * ix_ossl_thread__delay - * - * OSSL Semaphore APIs: - * The OSSL semaphore functions that allow for initialization, - * posting, waiting and deletion of semaphores. - * - * ix_ossl_sem_init - * ix_ossl_sem_fini - * ix_ossl_sem_take - * ix_ossl_sem_give - * ix_ossl_sem_flush - * - * OSSL Mutex APIs: - * The OSSL wrapper functions that allow for initialization, - * posting, waiting and deletion of mutexes. - * - * ix_ossl_mutex_init - * ix_ossl_mutex_fini - * ix_ossl_mutex_lock - * ix_ossl_mutex_unlock - * - * OSSL Timer APIs: - * The timer APIs provide sleep and get time functions. - * - * ix_ossl_sleep - * ix_ossl_sleep_tick - * ix_ossl_time_get - * - * OSAPIs for Transactor/WorkBench: - * These OSAPI functions are used for transator OS calls. - * They are defined in osApi.h. - * - * Sem_Init - * Sem_Destroy - * Sem_Wait - * Sem_Wait - * Thread_Create - * Thread_Cancel - * Thread_SetPriority - * delayMs - * delayTick - * - * - * - ********************************************************************** - * - * - * = AUTHOR - * Intel Corporation - * - * = ACKNOWLEDGEMENTS - * - * - * = CREATION TIME - * 1/8/2002 1:53:42 PM - * - * = CHANGE HISTORY - * 02/22/2002 : Renamed osapi.h os_api.h - * Moved OS header file includes from OSSL.h to os_api.h - * Moved OS specific datatypes to os_api.h - * Modified data types, macros and functions as per - * 'C' coding guidelines. - * - * - * ============================================================================ - */ - -#ifndef _IX_OSSL_H -#ifndef __doxygen_hide -#define _IX_OSSL_H -#endif /* __doxygen_hide */ - -#include "IxOsalBackward.h" - -#endif /* _IX_OSSL_H */ - -/** - * @} defgroup IxOSSL - */ diff --git a/cpu/ixp/npe/include/ix_symbols.h b/cpu/ixp/npe/include/ix_symbols.h deleted file mode 100644 index f7bb029d66..0000000000 --- a/cpu/ixp/npe/include/ix_symbols.h +++ /dev/null @@ -1,106 +0,0 @@ -/** - * ============================================================================ - * = COPYRIGHT - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - * = PRODUCT - * Intel(r) IXP425 Software Release - * - * = FILENAME - * ix_symbols.h - * - * = DESCRIPTION - * This file declares all the global preprocessor symbols required by - * the IXA SDK Framework API. - * - * = AUTHOR - * Intel Corporation - * - * = CHANGE HISTORY - * 4/23/2002 10:41:13 AM - creation time - * ============================================================================ - */ - -#if !defined(__IX_SYMBOLS_H__) -#define __IX_SYMBOLS_H__ - - -#if defined(__cplusplus) -extern "C" -{ -#endif /* end defined(__cplusplus) */ - -/** - * The IX_EXPORT_FUNCTION symbol will be used for compilation on different platforms. - * We are planning to provide a simulation version of the library that should work - * with the Transactor rather than the hardware. This implementation will be done on - * WIN32 in the form of a DLL that will need to export functions and symbols. - */ -#if (_IX_OS_TYPE_ == _IX_OS_WIN32_) -# if defined(_IX_LIB_INTERFACE_IMPLEMENTATION_) -# define IX_EXPORT_FUNCTION __declspec( dllexport ) -# elif defined(_IX_LIB_INTERFACE_IMPORT_DLL_) -# define IX_EXPORT_FUNCTION __declspec( dllimport ) -# else -# define IX_EXPORT_FUNCTION extern -# endif -#elif (_IX_OS_TYPE_ == _IX_OS_WINCE_) -# define IX_EXPORT_FUNCTION __declspec(dllexport) -#else -# define IX_EXPORT_FUNCTION extern -#endif - - -/** - * This symbols should be defined when we want to build for a multithreaded environment - */ -#define _IX_MULTI_THREADED_ 1 - - -/** - * This symbol should be defined in the case we to buils for a multithreaded environment - * but we want that our modules to work as if they are used in a single threaded environment. - */ -/* #define _IX_RM_EXPLICIT_SINGLE_THREADED_ 1 */ - -#if defined(__cplusplus) -} -#endif /* end defined(__cplusplus) */ - -#endif /* end !defined(__IX_SYMBOLS_H__) */ diff --git a/cpu/ixp/npe/include/ix_types.h b/cpu/ixp/npe/include/ix_types.h deleted file mode 100644 index fc7b1e993a..0000000000 --- a/cpu/ixp/npe/include/ix_types.h +++ /dev/null @@ -1,208 +0,0 @@ -/** - * ============================================================================ - * = COPYRIGHT - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - * = PRODUCT - * Intel(r) IXP425 Software Release - * - * = FILENAME - * ix_types.h - * - * = DESCRIPTION - * This file will define generic types that will guarantee the protability - * between different architectures and compilers. It should be used the entire - * IXA SDK Framework API. - * - * = AUTHOR - * Intel Corporation - * - * = CHANGE HISTORY - * 4/22/2002 4:44:17 PM - creation time - * ============================================================================ - */ - -#if !defined(__IX_TYPES_H__) -#define __IX_TYPES_H__ - - -#if defined(__cplusplus) -extern "C" -{ -#endif /* end defined(__cplusplus) */ - - -/** - * Define generic integral data types that will guarantee the size. - */ - -/** - * TYPENAME: ix_int8 - * - * DESCRIPTION: This type defines an 8 bit signed integer value. - * - */ -typedef signed char ix_int8; - - -/** - * TYPENAME: ix_uint8 - * - * DESCRIPTION: This type defines an 8 bit unsigned integer value. - * - */ -typedef unsigned char ix_uint8; - - -/** - * TYPENAME: ix_int16 - * - * DESCRIPTION: This type defines an 16 bit signed integer value. - * - */ -typedef signed short int ix_int16; - - -/** - * TYPENAME: ix_uint16 - * - * DESCRIPTION: This type defines an 16 bit unsigned integer value. - * - */ -typedef unsigned short int ix_uint16; - - -/** - * TYPENAME: ix_int32 - * - * DESCRIPTION: This type defines an 32 bit signed integer value. - * - */ -typedef signed int ix_int32; - - -/** - * TYPENAME: ix_uint32 - * - * DESCRIPTION: This type defines an 32 bit unsigned integer value. - * - */ -#ifndef __wince -typedef unsigned int ix_uint32; -#else -typedef unsigned long ix_uint32; -#endif - -/** - * TYPENAME: ix_int64 - * - * DESCRIPTION: This type defines an 64 bit signed integer value. - * - */ -#ifndef __wince -__extension__ typedef signed long long int ix_int64; -#endif - -/** - * TYPENAME: ix_uint64 - * - * DESCRIPTION: This type defines an 64 bit unsigned integer value. - * - */ -#ifndef __wince -__extension__ typedef unsigned long long int ix_uint64; -#endif - - -/** - * TYPENAME: ix_bit_mask8 - * - * DESCRIPTION: This is a generic type for a 8 bit mask. - */ -typedef ix_uint8 ix_bit_mask8; - - -/** - * TYPENAME: ix_bit_mask16 - * - * DESCRIPTION: This is a generic type for a 16 bit mask. - */ -typedef ix_uint16 ix_bit_mask16; - - -/** - * TYPENAME: ix_bit_mask32 - * - * DESCRIPTION: This is a generic type for a 32 bit mask. - */ -typedef ix_uint32 ix_bit_mask32; - - -/** - * TYPENAME: ix_bit_mask64 - * - * DESCRIPTION: This is a generic type for a 64 bit mask. - */ -#ifndef __wince -typedef ix_uint64 ix_bit_mask64; -#endif - - -/** - * TYPENAME: ix_handle - * - * DESCRIPTION: This type defines a generic handle. - * - */ -typedef ix_uint32 ix_handle; - - - -/** - * DESCRIPTION: This symbol defines a NULL handle - * - */ -#define IX_NULL_HANDLE ((ix_handle)0) - - -#if defined(__cplusplus) -} -#endif /* end defined(__cplusplus) */ - -#endif /* end !defined(__IX_TYPES_H__) */ diff --git a/cpu/ixp/npe/include/npe.h b/cpu/ixp/npe/include/npe.h deleted file mode 100644 index 3d6f727476..0000000000 --- a/cpu/ixp/npe/include/npe.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * (C) Copyright 2005 - * Stefan Roese, DENX Software Engineering, sr@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#ifndef NPE_H -#define NPE_H - -/* - * defines... - */ -#define CONFIG_SYS_NPE_NUMS 1 -#ifdef CONFIG_HAS_ETH1 -#undef CONFIG_SYS_NPE_NUMS -#define CONFIG_SYS_NPE_NUMS 2 -#endif - -#define NPE_NUM_PORTS 3 -#define ACTIVE_PORTS 1 - -#define NPE_PKT_SIZE 1600 - -#define CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS 64 -#define CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS 2 - -#define NPE_MBUF_POOL_SIZE \ - ((CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS + \ - CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS) * \ - sizeof(IX_OSAL_MBUF) * ACTIVE_PORTS) - -#define NPE_PKT_POOL_SIZE \ - ((CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS + \ - CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS) * \ - NPE_PKT_SIZE * ACTIVE_PORTS) - -#define NPE_MEM_POOL_SIZE (NPE_MBUF_POOL_SIZE + NPE_PKT_POOL_SIZE) - -#define PHY_AUTONEGOTIATE_TIMEOUT 4000 /* 4000 ms autonegotiate timeout */ - -/* - * structs... - */ -struct npe { - u8 active; /* NPE active */ - u8 eth_id; /* IX_ETH_PORT_1 or IX_ETH_PORT_2 */ - u8 phy_no; /* which PHY (0 - 31) */ - u8 mac_address[6]; - - IX_OSAL_MBUF *rxQHead; - IX_OSAL_MBUF *txQHead; - - u8 *tx_pkts; - u8 *rx_pkts; - IX_OSAL_MBUF *rx_mbufs; - IX_OSAL_MBUF *tx_mbufs; - - int print_speed; - - int rx_read; - int rx_write; - int rx_len[PKTBUFSRX]; -}; - -/* - * prototypes... - */ -extern int npe_miiphy_read (char *devname, unsigned char addr, - unsigned char reg, unsigned short *value); -extern int npe_miiphy_write (char *devname, unsigned char addr, - unsigned char reg, unsigned short value); - -#endif /* ifndef NPE_H */ diff --git a/cpu/ixp/npe/include/os_datatypes.h b/cpu/ixp/npe/include/os_datatypes.h deleted file mode 100644 index 4387b2a052..0000000000 --- a/cpu/ixp/npe/include/os_datatypes.h +++ /dev/null @@ -1,82 +0,0 @@ -/** - * ============================================================================ - * = COPYRIGHT - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - * = PRODUCT - * Intel(r) IXP425 Software Release - * - * = LIBRARY - * OSSL - Operating System Services Library - * - * = MODULE - * OS Specific Data Types header file - * - * = FILENAME - * OSSL.h (Replaced by OSAL) - * - * = DESCRIPTION - * This file contains definitions and encapsulations for OS specific data types. These - * encapsulated data types are used by OSSL header files and OS API functions. - * - * - ********************************************************************** - * - * - * = AUTHOR - * Intel Corporation - * - * = AKNOWLEDGEMENTS - * - * - * = CREATION TIME - * 1/8/2002 1:53:42 PM - * - * = CHANGE HISTORY - - * ============================================================================ - */ - -#ifndef _OS_DATATYPES_H -#define _OS_DATATYPES_H - -#include "IxOsalBackward.h" - -#endif /* _OS_DATATYPES_H */ - diff --git a/cpu/ixp/npe/miiphy.c b/cpu/ixp/npe/miiphy.c deleted file mode 100644 index b208c51eae..0000000000 --- a/cpu/ixp/npe/miiphy.c +++ /dev/null @@ -1,120 +0,0 @@ -/*-----------------------------------------------------------------------------+ - | This source code is dual-licensed. You may use it under the terms of the - | GNU General Public License version 2, or under the license below. - | - | This source code has been made available to you by IBM on an AS-IS - | basis. Anyone receiving this source is licensed under IBM - | copyrights to use it in any way he or she deems fit, including - | copying it, modifying it, compiling it, and redistributing it either - | with or without modifications. No license under IBM patents or - | patent applications is to be implied by the copyright license. - | - | Any user of this software should understand that IBM cannot provide - | technical support for this software and will not be responsible for - | any consequences resulting from the use of this software. - | - | Any person who transfers this source code or any derivative work - | must include the IBM copyright notice, this paragraph, and the - | preceding two paragraphs in the transferred software. - | - | COPYRIGHT I B M CORPORATION 1995 - | LICENSED MATERIAL - PROGRAM PROPERTY OF I B M - +-----------------------------------------------------------------------------*/ -/*-----------------------------------------------------------------------------+ - | - | File Name: miiphy.c - | - | Function: This module has utilities for accessing the MII PHY through - | the EMAC3 macro. - | - | Author: Mark Wisner - | - | Change Activity- - | - | Date Description of Change BY - | --------- --------------------- --- - | 05-May-99 Created MKW - | 01-Jul-99 Changed clock setting of sta_reg from 66MHz to 50MHz to - | better match OPB speed. Also modified delay times. JWB - | 29-Jul-99 Added Full duplex support MKW - | 24-Aug-99 Removed printf from dp83843_duplex() JWB - | 19-Jul-00 Ported to esd cpci405 sr - | 23-Dec-03 Ported from miiphy.c to 440GX Travis Sawyer TBS - | - | - +-----------------------------------------------------------------------------*/ - -#include -#include -#include "IxOsal.h" -#include "IxEthAcc.h" -#include "IxEthAcc_p.h" -#include "IxEthAccMac_p.h" -#include "IxEthAccMii_p.h" - -/***********************************************************/ -/* Dump out to the screen PHY regs */ -/***********************************************************/ - -void miiphy_dump (char *devname, unsigned char addr) -{ - unsigned long i; - unsigned short data; - - - for (i = 0; i < 0x1A; i++) { - if (miiphy_read (devname, addr, i, &data)) { - printf ("read error for reg %lx\n", i); - return; - } - printf ("Phy reg %lx ==> %4x\n", i, data); - - /* jump to the next set of regs */ - if (i == 0x07) - i = 0x0f; - - } /* end for loop */ -} /* end dump */ - - -/***********************************************************/ -/* (Re)start autonegotiation */ -/***********************************************************/ -int phy_setup_aneg (char *devname, unsigned char addr) -{ - unsigned short ctl, adv; - - /* Setup standard advertise */ - miiphy_read (devname, addr, PHY_ANAR, &adv); - adv |= (PHY_ANLPAR_ACK | PHY_ANLPAR_RF | PHY_ANLPAR_T4 | - PHY_ANLPAR_TXFD | PHY_ANLPAR_TX | PHY_ANLPAR_10FD | - PHY_ANLPAR_10); - miiphy_write (devname, addr, PHY_ANAR, adv); - - /* Start/Restart aneg */ - miiphy_read (devname, addr, PHY_BMCR, &ctl); - ctl |= (PHY_BMCR_AUTON | PHY_BMCR_RST_NEG); - miiphy_write (devname, addr, PHY_BMCR, ctl); - - return 0; -} - - -int npe_miiphy_read (char *devname, unsigned char addr, - unsigned char reg, unsigned short *value) -{ - u16 val; - - ixEthAccMiiReadRtn(addr, reg, &val); - *value = val; - - return 0; -} /* phy_read */ - - -int npe_miiphy_write (char *devname, unsigned char addr, - unsigned char reg, unsigned short value) -{ - ixEthAccMiiWriteRtn(addr, reg, value); - return 0; -} /* phy_write */ diff --git a/cpu/ixp/npe/npe.c b/cpu/ixp/npe/npe.c deleted file mode 100644 index 2e6868960a..0000000000 --- a/cpu/ixp/npe/npe.c +++ /dev/null @@ -1,676 +0,0 @@ -/* - * (C) Copyright 2005-2006 - * Stefan Roese, DENX Software Engineering, sr@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#if 0 -#define DEBUG /* define for debug output */ -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -static IxQMgrDispatcherFuncPtr qDispatcherFunc = NULL; -static int npe_exists[NPE_NUM_PORTS]; -static int npe_used[NPE_NUM_PORTS]; - -/* A little extra so we can align to cacheline. */ -static u8 npe_alloc_pool[NPE_MEM_POOL_SIZE + CONFIG_SYS_CACHELINE_SIZE - 1]; -static u8 *npe_alloc_end; -static u8 *npe_alloc_free; - -static void *npe_alloc(int size) -{ - static int count = 0; - void *p = NULL; - - size = (size + (CONFIG_SYS_CACHELINE_SIZE-1)) & ~(CONFIG_SYS_CACHELINE_SIZE-1); - count++; - - if ((npe_alloc_free + size) < npe_alloc_end) { - p = npe_alloc_free; - npe_alloc_free += size; - } else { - printf("npe_alloc: failed (count=%d, size=%d)!\n", count, size); - } - return p; -} - -/* Not interrupt safe! */ -static void mbuf_enqueue(IX_OSAL_MBUF **q, IX_OSAL_MBUF *new) -{ - IX_OSAL_MBUF *m = *q; - - IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(new) = NULL; - - if (m) { - while(IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m)) - m = IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m); - IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m) = new; - } else - *q = new; -} - -/* Not interrupt safe! */ -static IX_OSAL_MBUF *mbuf_dequeue(IX_OSAL_MBUF **q) -{ - IX_OSAL_MBUF *m = *q; - if (m) - *q = IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m); - return m; -} - -static void reset_tx_mbufs(struct npe* p_npe) -{ - IX_OSAL_MBUF *m; - int i; - - p_npe->txQHead = NULL; - - for (i = 0; i < CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS; i++) { - m = &p_npe->tx_mbufs[i]; - - memset(m, 0, sizeof(*m)); - - IX_OSAL_MBUF_MDATA(m) = (void *)&p_npe->tx_pkts[i * NPE_PKT_SIZE]; - IX_OSAL_MBUF_MLEN(m) = IX_OSAL_MBUF_PKT_LEN(m) = NPE_PKT_SIZE; - mbuf_enqueue(&p_npe->txQHead, m); - } -} - -static void reset_rx_mbufs(struct npe* p_npe) -{ - IX_OSAL_MBUF *m; - int i; - - p_npe->rxQHead = NULL; - - HAL_DCACHE_INVALIDATE(p_npe->rx_pkts, NPE_PKT_SIZE * - CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS); - - for (i = 0; i < CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS; i++) { - m = &p_npe->rx_mbufs[i]; - - memset(m, 0, sizeof(*m)); - - IX_OSAL_MBUF_MDATA(m) = (void *)&p_npe->rx_pkts[i * NPE_PKT_SIZE]; - IX_OSAL_MBUF_MLEN(m) = IX_OSAL_MBUF_PKT_LEN(m) = NPE_PKT_SIZE; - - if(ixEthAccPortRxFreeReplenish(p_npe->eth_id, m) != IX_SUCCESS) { - printf("ixEthAccPortRxFreeReplenish failed for port %d\n", p_npe->eth_id); - break; - } - } -} - -static void init_rx_mbufs(struct npe* p_npe) -{ - p_npe->rxQHead = NULL; - - p_npe->rx_pkts = npe_alloc(NPE_PKT_SIZE * - CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS); - if (p_npe->rx_pkts == NULL) { - printf("alloc of packets failed.\n"); - return; - } - - p_npe->rx_mbufs = (IX_OSAL_MBUF *) - npe_alloc(sizeof(IX_OSAL_MBUF) * - CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS); - if (p_npe->rx_mbufs == NULL) { - printf("alloc of mbufs failed.\n"); - return; - } - - reset_rx_mbufs(p_npe); -} - -static void init_tx_mbufs(struct npe* p_npe) -{ - p_npe->tx_pkts = npe_alloc(NPE_PKT_SIZE * - CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS); - if (p_npe->tx_pkts == NULL) { - printf("alloc of packets failed.\n"); - return; - } - - p_npe->tx_mbufs = (IX_OSAL_MBUF *) - npe_alloc(sizeof(IX_OSAL_MBUF) * - CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS); - if (p_npe->tx_mbufs == NULL) { - printf("alloc of mbufs failed.\n"); - return; - } - - reset_tx_mbufs(p_npe); -} - -/* Convert IX_ETH_PORT_n to IX_NPEMH_NPEID_NPEx */ -static int __eth_to_npe(int eth_id) -{ - switch(eth_id) { - case IX_ETH_PORT_1: - return IX_NPEMH_NPEID_NPEB; - - case IX_ETH_PORT_2: - return IX_NPEMH_NPEID_NPEC; - - case IX_ETH_PORT_3: - return IX_NPEMH_NPEID_NPEA; - } - return 0; -} - -/* Poll the CSR machinery. */ -static void npe_poll(int eth_id) -{ - if (qDispatcherFunc != NULL) { - ixNpeMhMessagesReceive(__eth_to_npe(eth_id)); - (*qDispatcherFunc)(IX_QMGR_QUELOW_GROUP); - } -} - -/* ethAcc RX callback */ -static void npe_rx_callback(u32 cbTag, IX_OSAL_MBUF *m, IxEthAccPortId portid) -{ - struct npe* p_npe = (struct npe *)cbTag; - - if (IX_OSAL_MBUF_MLEN(m) > 0) { - mbuf_enqueue(&p_npe->rxQHead, m); - - if (p_npe->rx_write == ((p_npe->rx_read-1) & (PKTBUFSRX-1))) { - debug("Rx overflow: rx_write=%d rx_read=%d\n", - p_npe->rx_write, p_npe->rx_read); - } else { - debug("Received message #%d (len=%d)\n", p_npe->rx_write, - IX_OSAL_MBUF_MLEN(m)); - memcpy((void *)NetRxPackets[p_npe->rx_write], IX_OSAL_MBUF_MDATA(m), - IX_OSAL_MBUF_MLEN(m)); - p_npe->rx_len[p_npe->rx_write] = IX_OSAL_MBUF_MLEN(m); - p_npe->rx_write++; - if (p_npe->rx_write == PKTBUFSRX) - p_npe->rx_write = 0; - -#ifdef CONFIG_PRINT_RX_FRAMES - { - u8 *ptr = IX_OSAL_MBUF_MDATA(m); - int i; - - for (i=0; i<60; i++) { - debug("%02x ", *ptr++); - } - debug("\n"); - } -#endif - } - - m = mbuf_dequeue(&p_npe->rxQHead); - } else { - debug("Received frame with length 0!!!\n"); - m = mbuf_dequeue(&p_npe->rxQHead); - } - - /* Now return mbuf to NPE */ - IX_OSAL_MBUF_MLEN(m) = IX_OSAL_MBUF_PKT_LEN(m) = NPE_PKT_SIZE; - IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(m) = NULL; - IX_OSAL_MBUF_FLAGS(m) = 0; - - if(ixEthAccPortRxFreeReplenish(p_npe->eth_id, m) != IX_SUCCESS) { - debug("npe_rx_callback: Error returning mbuf.\n"); - } -} - -/* ethAcc TX callback */ -static void npe_tx_callback(u32 cbTag, IX_OSAL_MBUF *m) -{ - struct npe* p_npe = (struct npe *)cbTag; - - debug("%s\n", __FUNCTION__); - - IX_OSAL_MBUF_MLEN(m) = IX_OSAL_MBUF_PKT_LEN(m) = NPE_PKT_SIZE; - IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(m) = NULL; - IX_OSAL_MBUF_FLAGS(m) = 0; - - mbuf_enqueue(&p_npe->txQHead, m); -} - - -static int npe_set_mac_address(struct eth_device *dev) -{ - struct npe *p_npe = (struct npe *)dev->priv; - IxEthAccMacAddr npeMac; - - debug("%s\n", __FUNCTION__); - - /* Set MAC address */ - memcpy(npeMac.macAddress, dev->enetaddr, 6); - - if (ixEthAccPortUnicastMacAddressSet(p_npe->eth_id, &npeMac) != IX_ETH_ACC_SUCCESS) { - printf("Error setting unicast address! %02x:%02x:%02x:%02x:%02x:%02x\n", - npeMac.macAddress[0], npeMac.macAddress[1], - npeMac.macAddress[2], npeMac.macAddress[3], - npeMac.macAddress[4], npeMac.macAddress[5]); - return 0; - } - - return 1; -} - -/* Boot-time CSR library initialization. */ -static int npe_csr_load(void) -{ - int i; - - if (ixQMgrInit() != IX_SUCCESS) { - debug("Error initialising queue manager!\n"); - return 0; - } - - ixQMgrDispatcherLoopGet(&qDispatcherFunc); - - if(ixNpeMhInitialize(IX_NPEMH_NPEINTERRUPTS_YES) != IX_SUCCESS) { - printf("Error initialising NPE Message handler!\n"); - return 0; - } - - if (npe_used[IX_ETH_PORT_1] && npe_exists[IX_ETH_PORT_1] && - ixNpeDlNpeInitAndStart(IX_NPEDL_NPEIMAGE_NPEB_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS) - != IX_SUCCESS) { - printf("Error downloading firmware to NPE-B!\n"); - return 0; - } - - if (npe_used[IX_ETH_PORT_2] && npe_exists[IX_ETH_PORT_2] && - ixNpeDlNpeInitAndStart(IX_NPEDL_NPEIMAGE_NPEC_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS) - != IX_SUCCESS) { - printf("Error downloading firmware to NPE-C!\n"); - return 0; - } - - /* don't need this for U-Boot */ - ixFeatureCtrlSwConfigurationWrite(IX_FEATURECTRL_ETH_LEARNING, FALSE); - - if (ixEthAccInit() != IX_ETH_ACC_SUCCESS) { - printf("Error initialising Ethernet access driver!\n"); - return 0; - } - - for (i = 0; i < IX_ETH_ACC_NUMBER_OF_PORTS; i++) { - if (!npe_used[i] || !npe_exists[i]) - continue; - if (ixEthAccPortInit(i) != IX_ETH_ACC_SUCCESS) { - printf("Error initialising Ethernet port%d!\n", i); - } - if (ixEthAccTxSchedulingDisciplineSet(i, FIFO_NO_PRIORITY) != IX_ETH_ACC_SUCCESS) { - printf("Error setting scheduling discipline for port %d.\n", i); - } - if (ixEthAccPortRxFrameAppendFCSDisable(i) != IX_ETH_ACC_SUCCESS) { - printf("Error disabling RX FCS for port %d.\n", i); - } - if (ixEthAccPortTxFrameAppendFCSEnable(i) != IX_ETH_ACC_SUCCESS) { - printf("Error enabling TX FCS for port %d.\n", i); - } - } - - return 1; -} - -static int npe_init(struct eth_device *dev, bd_t * bis) -{ - struct npe *p_npe = (struct npe *)dev->priv; - int i; - u16 reg_short; - int speed; - int duplex; - - debug("%s: 1\n", __FUNCTION__); - - miiphy_read (dev->name, p_npe->phy_no, PHY_BMSR, ®_short); - - /* - * Wait if PHY is capable of autonegotiation and autonegotiation is not complete - */ - if ((reg_short & PHY_BMSR_AUTN_ABLE) && !(reg_short & PHY_BMSR_AUTN_COMP)) { - puts ("Waiting for PHY auto negotiation to complete"); - i = 0; - while (!(reg_short & PHY_BMSR_AUTN_COMP)) { - /* - * Timeout reached ? - */ - if (i > PHY_AUTONEGOTIATE_TIMEOUT) { - puts (" TIMEOUT !\n"); - break; - } - - if ((i++ % 1000) == 0) { - putc ('.'); - miiphy_read (dev->name, p_npe->phy_no, PHY_BMSR, ®_short); - } - udelay (1000); /* 1 ms */ - } - puts (" done\n"); - udelay (500000); /* another 500 ms (results in faster booting) */ - } - - speed = miiphy_speed (dev->name, p_npe->phy_no); - duplex = miiphy_duplex (dev->name, p_npe->phy_no); - - if (p_npe->print_speed) { - p_npe->print_speed = 0; - printf ("ENET Speed is %d Mbps - %s duplex connection\n", - (int) speed, (duplex == HALF) ? "HALF" : "FULL"); - } - - npe_alloc_end = npe_alloc_pool + sizeof(npe_alloc_pool); - npe_alloc_free = (u8 *)(((unsigned)npe_alloc_pool + - CONFIG_SYS_CACHELINE_SIZE - 1) & ~(CONFIG_SYS_CACHELINE_SIZE - 1)); - - /* initialize mbuf pool */ - init_rx_mbufs(p_npe); - init_tx_mbufs(p_npe); - - if (ixEthAccPortRxCallbackRegister(p_npe->eth_id, npe_rx_callback, - (u32)p_npe) != IX_ETH_ACC_SUCCESS) { - printf("can't register RX callback!\n"); - return -1; - } - - if (ixEthAccPortTxDoneCallbackRegister(p_npe->eth_id, npe_tx_callback, - (u32)p_npe) != IX_ETH_ACC_SUCCESS) { - printf("can't register TX callback!\n"); - return -1; - } - - npe_set_mac_address(dev); - - if (ixEthAccPortEnable(p_npe->eth_id) != IX_ETH_ACC_SUCCESS) { - printf("can't enable port!\n"); - return -1; - } - - p_npe->active = 1; - - return 0; -} - -#if 0 /* test-only: probably have to deal with it when booting linux (for a clean state) */ -/* Uninitialize CSR library. */ -static void npe_csr_unload(void) -{ - ixEthAccUnload(); - ixEthDBUnload(); - ixNpeMhUnload(); - ixQMgrUnload(); -} - -/* callback which is used by ethAcc to recover RX buffers when stopping */ -static void npe_rx_stop_callback(u32 cbTag, IX_OSAL_MBUF *m, IxEthAccPortId portid) -{ - debug("%s\n", __FUNCTION__); -} - -/* callback which is used by ethAcc to recover TX buffers when stopping */ -static void npe_tx_stop_callback(u32 cbTag, IX_OSAL_MBUF *m) -{ - debug("%s\n", __FUNCTION__); -} -#endif - -static void npe_halt(struct eth_device *dev) -{ - struct npe *p_npe = (struct npe *)dev->priv; - int i; - - debug("%s\n", __FUNCTION__); - - /* Delay to give time for recovery of mbufs */ - for (i = 0; i < 100; i++) { - npe_poll(p_npe->eth_id); - udelay(100); - } - -#if 0 /* test-only: probably have to deal with it when booting linux (for a clean state) */ - if (ixEthAccPortRxCallbackRegister(p_npe->eth_id, npe_rx_stop_callback, - (u32)p_npe) != IX_ETH_ACC_SUCCESS) { - debug("Error registering rx callback!\n"); - } - - if (ixEthAccPortTxDoneCallbackRegister(p_npe->eth_id, npe_tx_stop_callback, - (u32)p_npe) != IX_ETH_ACC_SUCCESS) { - debug("Error registering tx callback!\n"); - } - - if (ixEthAccPortDisable(p_npe->eth_id) != IX_ETH_ACC_SUCCESS) { - debug("npe_stop: Error disabling NPEB!\n"); - } - - /* Delay to give time for recovery of mbufs */ - for (i = 0; i < 100; i++) { - npe_poll(p_npe->eth_id); - udelay(10000); - } - - /* - * For U-Boot only, we are probably launching Linux or other OS that - * needs a clean slate for its NPE library. - */ -#if 0 /* test-only */ - for (i = 0; i < IX_ETH_ACC_NUMBER_OF_PORTS; i++) { - if (npe_used[i] && npe_exists[i]) - if (ixNpeDlNpeStopAndReset(__eth_to_npe(i)) != IX_SUCCESS) - printf("Failed to stop and reset NPE B.\n"); - } -#endif - -#endif - p_npe->active = 0; -} - - -static int npe_send(struct eth_device *dev, volatile void *packet, int len) -{ - struct npe *p_npe = (struct npe *)dev->priv; - u8 *dest; - int err; - IX_OSAL_MBUF *m; - - debug("%s\n", __FUNCTION__); - m = mbuf_dequeue(&p_npe->txQHead); - dest = IX_OSAL_MBUF_MDATA(m); - IX_OSAL_MBUF_PKT_LEN(m) = IX_OSAL_MBUF_MLEN(m) = len; - IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m) = NULL; - - memcpy(dest, (char *)packet, len); - - if ((err = ixEthAccPortTxFrameSubmit(p_npe->eth_id, m, IX_ETH_ACC_TX_DEFAULT_PRIORITY)) - != IX_ETH_ACC_SUCCESS) { - printf("npe_send: Can't submit frame. err[%d]\n", err); - mbuf_enqueue(&p_npe->txQHead, m); - return 0; - } - -#ifdef DEBUG_PRINT_TX_FRAMES - { - u8 *ptr = IX_OSAL_MBUF_MDATA(m); - int i; - - for (i=0; ieth_id); - - return len; -} - -static int npe_rx(struct eth_device *dev) -{ - struct npe *p_npe = (struct npe *)dev->priv; - - debug("%s\n", __FUNCTION__); - npe_poll(p_npe->eth_id); - - debug("%s: rx_write=%d rx_read=%d\n", __FUNCTION__, p_npe->rx_write, p_npe->rx_read); - while (p_npe->rx_write != p_npe->rx_read) { - debug("Reading message #%d\n", p_npe->rx_read); - NetReceive(NetRxPackets[p_npe->rx_read], p_npe->rx_len[p_npe->rx_read]); - p_npe->rx_read++; - if (p_npe->rx_read == PKTBUFSRX) - p_npe->rx_read = 0; - } - - return 0; -} - -int npe_initialize(bd_t * bis) -{ - static int virgin = 0; - struct eth_device *dev; - int eth_num = 0; - struct npe *p_npe = NULL; - uchar enetaddr[6]; - - for (eth_num = 0; eth_num < CONFIG_SYS_NPE_NUMS; eth_num++) { - - /* See if we can actually bring up the interface, otherwise, skip it */ -#ifdef CONFIG_HAS_ETH1 - if (eth_num == 1) { - if (!eth_getenv_enetaddr("eth1addr", enetaddr)) - continue; - } else -#endif - if (!eth_getenv_enetaddr("ethaddr", enetaddr)) - continue; - - /* Allocate device structure */ - dev = (struct eth_device *)malloc(sizeof(*dev)); - if (dev == NULL) { - printf ("%s: Cannot allocate eth_device %d\n", __FUNCTION__, eth_num); - return -1; - } - memset(dev, 0, sizeof(*dev)); - - /* Allocate our private use data */ - p_npe = (struct npe *)malloc(sizeof(struct npe)); - if (p_npe == NULL) { - printf("%s: Cannot allocate private hw data for eth_device %d", - __FUNCTION__, eth_num); - free(dev); - return -1; - } - memset(p_npe, 0, sizeof(struct npe)); - - p_npe->eth_id = eth_num; - memcpy(dev->enetaddr, enetaddr, 6); -#ifdef CONFIG_HAS_ETH1 - if (eth_num == 1) - p_npe->phy_no = CONFIG_PHY1_ADDR; - else -#endif - p_npe->phy_no = CONFIG_PHY_ADDR; - - sprintf(dev->name, "NPE%d", eth_num); - dev->priv = (void *)p_npe; - dev->init = npe_init; - dev->halt = npe_halt; - dev->send = npe_send; - dev->recv = npe_rx; - - p_npe->print_speed = 1; - - if (0 == virgin) { - virgin = 1; - - if (ixFeatureCtrlDeviceRead() == IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X) { - switch (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK) { - case IX_FEATURE_CTRL_SILICON_TYPE_B0: - /* - * If it is B0 Silicon, we only enable port when its corresponding - * Eth Coprocessor is available. - */ - if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) == - IX_FEATURE_CTRL_COMPONENT_ENABLED) - npe_exists[IX_ETH_PORT_1] = TRUE; - - if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) == - IX_FEATURE_CTRL_COMPONENT_ENABLED) - npe_exists[IX_ETH_PORT_2] = TRUE; - break; - case IX_FEATURE_CTRL_SILICON_TYPE_A0: - /* - * If it is A0 Silicon, we enable both as both Eth Coprocessors - * are available. - */ - npe_exists[IX_ETH_PORT_1] = TRUE; - npe_exists[IX_ETH_PORT_2] = TRUE; - break; - } - } else if (ixFeatureCtrlDeviceRead() == IX_FEATURE_CTRL_DEVICE_TYPE_IXP46X) { - if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) == - IX_FEATURE_CTRL_COMPONENT_ENABLED) - npe_exists[IX_ETH_PORT_1] = TRUE; - - if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) == - IX_FEATURE_CTRL_COMPONENT_ENABLED) - npe_exists[IX_ETH_PORT_2] = TRUE; - } - - npe_used[IX_ETH_PORT_1] = 1; - npe_used[IX_ETH_PORT_2] = 1; - - npe_alloc_end = npe_alloc_pool + sizeof(npe_alloc_pool); - npe_alloc_free = (u8 *)(((unsigned)npe_alloc_pool + - CONFIG_SYS_CACHELINE_SIZE - 1) - & ~(CONFIG_SYS_CACHELINE_SIZE - 1)); - - if (!npe_csr_load()) - return 0; - } - - eth_register(dev); - -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) - miiphy_register(dev->name, npe_miiphy_read, npe_miiphy_write); -#endif - - } /* end for each supported device */ - - return 1; -} diff --git a/cpu/ixp/start.S b/cpu/ixp/start.S deleted file mode 100644 index 5ebce5338c..0000000000 --- a/cpu/ixp/start.S +++ /dev/null @@ -1,525 +0,0 @@ -/* vi: set ts=8 sw=8 noet: */ -/* - * u-boot - Startup Code for XScale IXP - * - * Copyright (C) 2003 Kyle Harris - * - * Based on startup code example contained in the - * Intel IXP4xx Programmer's Guide and past u-boot Start.S - * samples. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -#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: b 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 - -_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 - */ - -_TEXT_BASE: - .word TEXT_BASE - -.globl _armboot_start -_armboot_start: - .word _start - -/* - * These are defined in the board-specific linker script. - */ -.globl _bss_start -_bss_start: - .word __bss_start - -.globl _bss_end -_bss_end: - .word _end - -#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 - -/****************************************************************************/ -/* */ -/* 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 */ -#if 0 - ldr r2, =IXP425_EXP_CFG0 - ldr r1, [r2] - orr r1, r1, #0x80000000 - str r1, [r2] -#endif - 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 - - /* copy */ - mov r0, #0 - mov r4, r0 - add r2, r0, #CONFIG_SYS_MONITOR_LEN - mov r1, #0x10000000 - mov r5, r1 - - 30: - ldr r3, [r0], #4 - str r3, [r1], #4 - cmp r0, r2 - bne 30b - - /* 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 - - /* move flash to 0x50000000 */ - ldr r2, =IXP425_EXP_CFG0 - ldr r1, [r2] - bic r1, r1, #0x80000000 - str r1, [r2] - - nop - nop - nop - nop - nop - nop - - /* 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 - -#ifndef CONFIG_SKIP_RELOCATE_UBOOT -relocate: /* relocate U-Boot to RAM */ - adr r0, _start /* r0 <- current position of code */ - ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ - cmp r0, r1 /* don't reloc during debug */ - beq stack_setup - - ldr r2, _armboot_start - ldr r3, _bss_start - sub r2, r3, r2 /* r2 <- size of armboot */ - add r2, r0, r2 /* r2 <- source end address */ - -copy_loop: - ldmia r0!, {r3-r10} /* copy from source address [r0] */ - stmia r1!, {r3-r10} /* copy to target address [r1] */ - cmp r0, r2 /* until source end addreee [r2] */ - ble copy_loop -#endif /* CONFIG_SKIP_RELOCATE_UBOOT */ - - /* Set up the stack */ -stack_setup: - ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ - sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */ - sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ -#ifdef CONFIG_USE_IRQ - sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) -#endif - sub sp, r0, #12 /* leave 3 words for abort-stack */ - -clear_bss: - ldr r0, _bss_start /* find start of bss segment */ - ldr r1, _bss_end /* stop here */ - mov r2, #0x00000000 /* clear */ - -clbss_l:str r2, [r0] /* clear loop... */ - add r0, r0, #4 - cmp r0, r1 - ble clbss_l - - ldr pc, _start_armboot - -_start_armboot: .word start_armboot - - -/****************************************************************************/ -/* */ -/* 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, _armboot_start - sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) - sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack - 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, _armboot_start @ setup our mode stack - sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) - sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort 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 - -#ifdef CONFIG_USE_IRQ - -.LC0: .word loops_per_jiffy - -/* - * 0 <= r0 <= 2000 - */ -.globl __udelay -__udelay: - mov r2, #0x6800 - orr r2, r2, #0x00db - mul r0, r2, r0 - ldr r2, .LC0 - ldr r2, [r2] @ max = 0x0fffffff - mov r0, r0, lsr #11 @ max = 0x00003fff - mov r2, r2, lsr #11 @ max = 0x0003ffff - mul r0, r2, r0 @ max = 2^32-1 - movs r0, r0, lsr #6 - -delay_loop: - subs r0, r0, #1 - bne delay_loop - mov pc, lr - -#endif /* CONFIG_USE_IRQ */ diff --git a/cpu/ixp/timer.c b/cpu/ixp/timer.c deleted file mode 100644 index edf341ff9f..0000000000 --- a/cpu/ixp/timer.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * (C) Copyright 2006 - * Stefan Roese, DENX Software Engineering, sr@denx.de. - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include - -#ifdef CONFIG_TIMER_IRQ - -#define FREQ 66666666 -#define CLOCK_TICK_RATE (((FREQ / CONFIG_SYS_HZ & ~IXP425_OST_RELOAD_MASK) + 1) * CONFIG_SYS_HZ) -#define LATCH ((CLOCK_TICK_RATE + CONFIG_SYS_HZ/2) / CONFIG_SYS_HZ) /* For divider */ - -/* - * When interrupts are enabled, use timer 2 for time/delay generation... - */ - -static volatile ulong timestamp; - -static void timer_isr(void *data) -{ - unsigned int *pTime = (unsigned int *)data; - - (*pTime)++; - - /* - * Reset IRQ source - */ - *IXP425_OSST = IXP425_OSST_TIMER_2_PEND; -} - -ulong get_timer (ulong base) -{ - return timestamp - base; -} - -void reset_timer (void) -{ - timestamp = 0; -} - -int timer_init (void) -{ - /* install interrupt handler for timer */ - irq_install_handler(IXP425_TIMER_2_IRQ, timer_isr, (void *)×tamp); - - /* setup the Timer counter value */ - *IXP425_OSRT2 = (LATCH & ~IXP425_OST_RELOAD_MASK) | IXP425_OST_ENABLE; - - /* enable timer irq */ - *IXP425_ICMR = (1 << IXP425_TIMER_2_IRQ); - - return 0; -} -#else -ulong get_timer (ulong base) -{ - return get_timer_masked () - base; -} - -void ixp425_udelay(unsigned long usec) -{ - /* - * This function has a max usec, but since it is called from udelay - * we should not have to worry... be happy - */ - unsigned long usecs = CONFIG_SYS_HZ/1000000L & ~IXP425_OST_RELOAD_MASK; - - *IXP425_OSST = IXP425_OSST_TIMER_1_PEND; - usecs |= IXP425_OST_ONE_SHOT | IXP425_OST_ENABLE; - *IXP425_OSRT1 = usecs; - while (!(*IXP425_OSST & IXP425_OSST_TIMER_1_PEND)); -} - -void __udelay (unsigned long usec) -{ - while (usec--) ixp425_udelay(1); -} - -static ulong reload_constant = 0xfffffff0; - -void reset_timer_masked (void) -{ - ulong reload = reload_constant | IXP425_OST_ONE_SHOT | IXP425_OST_ENABLE; - - *IXP425_OSST = IXP425_OSST_TIMER_1_PEND; - *IXP425_OSRT1 = reload; -} - -ulong get_timer_masked (void) -{ - /* - * Note that it is possible for this to wrap! - * In this case we return max. - */ - ulong current = *IXP425_OST1; - if (*IXP425_OSST & IXP425_OSST_TIMER_1_PEND) - { - return reload_constant; - } - return (reload_constant - current); -} - -int timer_init(void) -{ - return 0; -} -#endif diff --git a/cpu/ixp/u-boot.lds b/cpu/ixp/u-boot.lds deleted file mode 100644 index 85209caf74..0000000000 --- a/cpu/ixp/u-boot.lds +++ /dev/null @@ -1,56 +0,0 @@ -/* - * (C) Copyright 2000-2006 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -OUTPUT_FORMAT("elf32-bigarm", "elf32-bigarm", "elf32-bigarm") -OUTPUT_ARCH(arm) -ENTRY(_start) -SECTIONS -{ - . = 0x00000000; - - . = ALIGN(4); - .text : - { - cpu/ixp/start.o(.text) - *(.text) - } - - . = ALIGN(4); - .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } - - . = ALIGN(4); - .data : { *(.data) } - - . = ALIGN(4); - .got : { *(.got) } - - . = .; - __u_boot_cmd_start = .; - .u_boot_cmd : { *(.u_boot_cmd) } - __u_boot_cmd_end = .; - - . = ALIGN(4); - __bss_start = .; - .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } - _end = .; -} diff --git a/cpu/lh7a40x/Makefile b/cpu/lh7a40x/Makefile deleted file mode 100644 index 1b3f58abb9..0000000000 --- a/cpu/lh7a40x/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(CPU).a - -START = start.o -COBJS = cpu.o speed.o timer.o - -SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) -START := $(addprefix $(obj),$(START)) - -all: $(obj).depend $(START) $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/lh7a40x/config.mk b/cpu/lh7a40x/config.mk deleted file mode 100644 index 47b2b7b722..0000000000 --- a/cpu/lh7a40x/config.mk +++ /dev/null @@ -1,32 +0,0 @@ -# -# (C) Copyright 2002 -# Gary Jennejohn, DENX Software Engineering, -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float - -PLATFORM_CPPFLAGS += -march=armv4 -# ========================================================================= -# -# Supply options according to compiler version -# -# ======================================================================== -PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/lh7a40x/cpu.c b/cpu/lh7a40x/cpu.c deleted file mode 100644 index b193189123..0000000000 --- a/cpu/lh7a40x/cpu.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * CPU specific code - */ - -#include -#include -#include - -static void cache_flush(void); - -int cleanup_before_linux (void) -{ - /* - * this function is called just before we call linux - * it prepares the processor for linux - * - * we turn off caches etc ... - */ - - disable_interrupts (); - - /* turn off I/D-cache */ - icache_disable(); - dcache_disable(); - - /* flush I/D-cache */ - cache_flush(); - - return 0; -} - -/* flush I/D-cache */ -static void cache_flush (void) -{ - unsigned long i = 0; - - asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); -} diff --git a/cpu/lh7a40x/speed.c b/cpu/lh7a40x/speed.c deleted file mode 100644 index 333ebb504a..0000000000 --- a/cpu/lh7a40x/speed.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * (C) Copyright 2001-2004 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * (C) Copyright 2002 - * David Mueller, ELSOFT AG, d.mueller@elsoft.ch - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include - - -/* ------------------------------------------------------------------------- */ -/* NOTE: This describes the proper use of this file. - * - * CONFIG_SYS_CLK_FREQ should be defined as the input frequency of the PLL. - * - * get_FCLK(), get_HCLK(), get_PCLK() return the clock of - * the specified bus in HZ. - */ -/* ------------------------------------------------------------------------- */ - -ulong get_PLLCLK (void) -{ - return CONFIG_SYS_CLK_FREQ; -} - -/* return FCLK frequency */ -ulong get_FCLK (void) -{ - lh7a40x_csc_t* csc = LH7A40X_CSC_PTR; - ulong maindiv1, maindiv2, prediv, ps; - - /* - * from userguide 6.1.1.2 - * - * FCLK = ((MAINDIV1 +2) * (MAINDIV2 +2) * 14.7456MHz) / - * ((PREDIV+2) * (2^PS)) - */ - maindiv2 = (csc->clkset & CLKSET_MAINDIV2) >> 11; - maindiv1 = (csc->clkset & CLKSET_MAINDIV1) >> 7; - prediv = (csc->clkset & CLKSET_PREDIV) >> 2; - ps = (csc->clkset & CLKSET_PS) >> 16; - - return (((maindiv2 + 2) * (maindiv1 + 2) * CONFIG_SYS_CLK_FREQ) / - ((prediv + 2) * (1 << ps))); -} - - -/* return HCLK frequency */ -ulong get_HCLK (void) -{ - lh7a40x_csc_t* csc = LH7A40X_CSC_PTR; - - return (get_FCLK () / ((csc->clkset & CLKSET_HCLKDIV) + 1)); -} - -/* return PCLK frequency */ -ulong get_PCLK (void) -{ - lh7a40x_csc_t* csc = LH7A40X_CSC_PTR; - - return (get_HCLK () / - (1 << (((csc->clkset & CLKSET_PCLKDIV) >> 16) + 1))); -} diff --git a/cpu/lh7a40x/start.S b/cpu/lh7a40x/start.S deleted file mode 100644 index a1321b1d74..0000000000 --- a/cpu/lh7a40x/start.S +++ /dev/null @@ -1,428 +0,0 @@ -/* - * armboot - Startup Code for ARM920 CPU-core - * - * Copyright (c) 2001 Marius Gröger - * Copyright (c) 2002 Alex Züpke - * Copyright (c) 2002 Gary Jennejohn - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - - -#include -#include - - -/* - ************************************************************************* - * - * Jump vector table as in table 3.1 in [1] - * - ************************************************************************* - */ - - -.globl _start -_start: b 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 - -_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 - * - ************************************************************************* - */ - -_TEXT_BASE: - .word TEXT_BASE - -.globl _armboot_start -_armboot_start: - .word _start - -/* - * These are defined in the board-specific linker script. - */ -.globl _bss_start -_bss_start: - .word __bss_start - -.globl _bss_end -_bss_end: - .word _end - -#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 - - -/* - * the actual reset code - */ - -reset: - /* - * set the cpu to SVC32 mode - */ - mrs r0,cpsr - bic r0,r0,#0x1f - orr r0,r0,#0xd3 - msr cpsr,r0 - -#define pWDTCTL 0x80001400 /* Watchdog Timer control register */ -#define pINTENC 0x8000050C /* Interupt-Controller enable clear register */ -#define pCLKSET 0x80000420 /* clock divisor register */ - - /* disable watchdog, set watchdog control register to - * all zeros (default reset) - */ - ldr r0, =pWDTCTL - mov r1, #0x0 - str r1, [r0] - - /* - * mask all IRQs by setting all bits in the INTENC register (default) - */ - mov r1, #0xffffffff - ldr r0, =pINTENC - str r1, [r0] - - /* FCLK:HCLK:PCLK = 1:2:2 */ - /* default FCLK is 200 MHz, using 14.7456 MHz fin */ - ldr r0, =pCLKSET - ldr r1, =0x0004ee39 -@ ldr r1, =0x0005ee39 @ 1: 2: 4 - str r1, [r0] - - /* - * we do sys-critical inits only at reboot, - * not when booting from ram! - */ -#ifndef CONFIG_SKIP_LOWLEVEL_INIT - bl cpu_init_crit -#endif - -#ifndef CONFIG_SKIP_RELOCATE_UBOOT -relocate: /* relocate U-Boot to RAM */ - adr r0, _start /* r0 <- current position of code */ - ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ - cmp r0, r1 /* don't reloc during debug */ - beq stack_setup - - ldr r2, _armboot_start - ldr r3, _bss_start - sub r2, r3, r2 /* r2 <- size of armboot */ - add r2, r0, r2 /* r2 <- source end address */ - -copy_loop: - ldmia r0!, {r3-r10} /* copy from source address [r0] */ - stmia r1!, {r3-r10} /* copy to target address [r1] */ - cmp r0, r2 /* until source end addreee [r2] */ - blt copy_loop /* a 'ble' here actually copies */ - /* four bytes of bss */ -#endif /* CONFIG_SKIP_RELOCATE_UBOOT */ - - /* Set up the stack */ -stack_setup: - ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ - sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */ - sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ -#ifdef CONFIG_USE_IRQ - sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) -#endif - sub sp, r0, #12 /* leave 3 words for abort-stack */ - -clear_bss: - ldr r0, _bss_start /* find start of bss segment */ - @add r0, r0, #4 /* start at first byte of bss */ - /* why inc. 4 bytes past then? */ - ldr r1, _bss_end /* stop here */ - mov r2, #0x00000000 /* clear */ - -clbss_l:str r2, [r0] /* clear loop... */ - add r0, r0, #4 - cmp r0, r1 - ble clbss_l - - ldr pc, _start_armboot - -_start_armboot: .word start_armboot - - -/* - ************************************************************************* - * - * CPU_init_critical registers - * - * setup important registers - * setup memory timing - * - ************************************************************************* - */ - - -cpu_init_crit: - /* - * flush v4 I/D caches - */ - mov r0, #0 - mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ - mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ - - /* - * disable MMU stuff and caches - */ - mrc p15, 0, r0, c1, c0, 0 - bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) - bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) - orr r0, r0, #0x00000002 @ set bit 2 (A) Align - orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache - orr r0, r0, #0x40000000 @ set bit 30 (nF) notFastBus - mcr p15, 0, r0, c1, c0, 0 - - - /* - * before relocating, we have to setup RAM timing - * because memory timing is board-dependend, you will - * find a lowlevel_init.S in your board directory. - */ - mov ip, lr - bl lowlevel_init - mov lr, ip - - mov pc, 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 -#define I_BIT 0x80 - -/* - * use bad_save_user_regs for abort/prefetch/undef/swi ... - * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling - */ - - .macro bad_save_user_regs - sub sp, sp, #S_FRAME_SIZE - stmia sp, {r0 - r12} @ Calling r0-r12 - ldr r2, _armboot_start - sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) - sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack - ldmia r2, {r2 - r3} @ get pc, cpsr - add r0, sp, #S_FRAME_SIZE @ restore sp_SVC - - add r5, sp, #S_SP - mov r1, lr - stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr - mov r0, sp - .endm - - .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, _armboot_start @ setup our mode stack - sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) - sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort 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 - msr spsr, 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 - /* someone ought to write a more effiction fiq_save_user_regs */ - irq_save_user_regs - bl do_fiq - 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 - - .align 5 -.globl reset_cpu -reset_cpu: - bl disable_interrupts - - /* Disable watchdog */ - ldr r1, =pWDTCTL - mov r3, #0 - str r3, [r1] - - /* reset counter */ - ldr r3, =0x00001984 - str r3, [r1, #4] - - /* Enable the watchdog */ - mov r3, #1 - str r3, [r1] - -_loop_forever: - b _loop_forever diff --git a/cpu/lh7a40x/timer.c b/cpu/lh7a40x/timer.c deleted file mode 100644 index 2691315d84..0000000000 --- a/cpu/lh7a40x/timer.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include - -static ulong timer_load_val = 0; - -/* macro to read the 16 bit timer */ -static inline ulong READ_TIMER(void) -{ - lh7a40x_timers_t* timers = LH7A40X_TIMERS_PTR; - lh7a40x_timer_t* timer = &timers->timer1; - - return (timer->value & 0x0000ffff); -} - -static ulong timestamp; -static ulong lastdec; - -int timer_init (void) -{ - lh7a40x_timers_t* timers = LH7A40X_TIMERS_PTR; - lh7a40x_timer_t* timer = &timers->timer1; - - /* a periodic timer using the 508kHz source */ - timer->control = (TIMER_PER | TIMER_CLK508K); - - if (timer_load_val == 0) { - /* - * 10ms period with 508.469kHz clock = 5084 - */ - timer_load_val = CONFIG_SYS_HZ/100; - } - - /* load value for 10 ms timeout */ - lastdec = timer->load = timer_load_val; - - /* auto load, start timer */ - timer->control = timer->control | TIMER_EN; - timestamp = 0; - - return (0); -} - -/* - * timer without interrupts - */ - -void reset_timer (void) -{ - reset_timer_masked (); -} - -ulong get_timer (ulong base) -{ - return (get_timer_masked() - base); -} - -void set_timer (ulong t) -{ - timestamp = t; -} - -void __udelay (unsigned long usec) -{ - ulong tmo,tmp; - - /* normalize */ - if (usec >= 1000) { - tmo = usec / 1000; - tmo *= CONFIG_SYS_HZ; - tmo /= 1000; - } - else { - if (usec > 1) { - tmo = usec * CONFIG_SYS_HZ; - tmo /= (1000*1000); - } - else - tmo = 1; - } - - /* check for rollover during this delay */ - tmp = get_timer (0); - if ((tmp + tmo) < tmp ) - reset_timer_masked(); /* timer would roll over */ - else - tmo += tmp; - - while (get_timer_masked () < tmo); -} - -void reset_timer_masked (void) -{ - /* reset time */ - lastdec = READ_TIMER(); - timestamp = 0; -} - -ulong get_timer_masked (void) -{ - ulong now = READ_TIMER(); - - if (lastdec >= now) { - /* normal mode */ - timestamp += (lastdec - now); - } else { - /* we have an overflow ... */ - timestamp += ((lastdec + timer_load_val) - now); - } - lastdec = now; - - return timestamp; -} - -void udelay_masked (unsigned long usec) -{ - ulong tmo; - ulong endtime; - signed long diff; - - /* normalize */ - if (usec >= 1000) { - tmo = usec / 1000; - tmo *= CONFIG_SYS_HZ; - tmo /= 1000; - } else { - if (usec > 1) { - tmo = usec * CONFIG_SYS_HZ; - tmo /= (1000*1000); - } else { - tmo = 1; - } - } - - endtime = get_timer_masked () + tmo; - - do { - ulong now = get_timer_masked (); - diff = endtime - now; - } while (diff >= 0); -} - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return get_timer(0); -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk (void) -{ - ulong tbclk; - - tbclk = timer_load_val * 100; - - return tbclk; -} diff --git a/cpu/lh7a40x/u-boot.lds b/cpu/lh7a40x/u-boot.lds deleted file mode 100644 index e7543c97ce..0000000000 --- a/cpu/lh7a40x/u-boot.lds +++ /dev/null @@ -1,56 +0,0 @@ -/* - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -ENTRY(_start) -SECTIONS -{ - . = 0x00000000; - - . = ALIGN(4); - .text : - { - cpu/lh7a40x/start.o (.text) - *(.text) - } - - . = ALIGN(4); - .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } - - . = ALIGN(4); - .data : { *(.data) } - - . = ALIGN(4); - .got : { *(.got) } - - . = .; - __u_boot_cmd_start = .; - .u_boot_cmd : { *(.u_boot_cmd) } - __u_boot_cmd_end = .; - - . = ALIGN(4); - __bss_start = .; - .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } - _end = .; -} diff --git a/cpu/pxa/Makefile b/cpu/pxa/Makefile deleted file mode 100644 index 07a151a170..0000000000 --- a/cpu/pxa/Makefile +++ /dev/null @@ -1,52 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(CPU).a - -START = start.o - -COBJS += cpu.o -COBJS += i2c.o -COBJS += pxafb.o -COBJS += timer.o -COBJS += usb.o - -SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) -START := $(addprefix $(obj),$(START)) - -all: $(obj).depend $(START) $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/pxa/config.mk b/cpu/pxa/config.mk deleted file mode 100644 index a05d69ca27..0000000000 --- a/cpu/pxa/config.mk +++ /dev/null @@ -1,33 +0,0 @@ -# -# (C) Copyright 2002 -# Sysgo Real-Time Solutions, GmbH -# Marius Groeger -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float - -PLATFORM_CPPFLAGS += -march=armv5te -mtune=xscale -# ========================================================================= -# -# Supply options according to compiler version -# -# ======================================================================== -PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/pxa/cpu.c b/cpu/pxa/cpu.c deleted file mode 100644 index 800d120e71..0000000000 --- a/cpu/pxa/cpu.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * CPU specific code - */ - -#include -#include -#include -#include - -static void cache_flush(void); - -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)); -} - -#ifndef CONFIG_CPU_MONAHANS -void set_GPIO_mode(int gpio_mode) -{ - int gpio = gpio_mode & GPIO_MD_MASK_NR; - int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8; - int gafr; - - if (gpio_mode & GPIO_MD_MASK_DIR) - { - GPDR(gpio) |= GPIO_bit(gpio); - } - else - { - GPDR(gpio) &= ~GPIO_bit(gpio); - } - gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2)); - GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2)); -} -#endif /* CONFIG_CPU_MONAHANS */ diff --git a/cpu/pxa/i2c.c b/cpu/pxa/i2c.c deleted file mode 100644 index 6b72ba13a0..0000000000 --- a/cpu/pxa/i2c.c +++ /dev/null @@ -1,458 +0,0 @@ -/* - * (C) Copyright 2000 - * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it - * - * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2003 Pengutronix e.K. - * Robert Schwebel - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - * Back ported to the 8xx platform (from the 8260 platform) by - * Murray.Jensen@cmst.csiro.au, 27-Jan-01. - */ - -/* FIXME: this file is PXA255 specific! What about other XScales? */ - -#include - -#ifdef CONFIG_HARD_I2C - -/* - * - CONFIG_SYS_I2C_SPEED - * - I2C_PXA_SLAVE_ADDR - */ - -#include -#include -#include - -/*#define DEBUG_I2C 1 /###* activate local debugging output */ -#define I2C_PXA_SLAVE_ADDR 0x1 /* slave pxa unit address */ - -#if (CONFIG_SYS_I2C_SPEED == 400000) -#define I2C_ICR_INIT (ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE) -#else -#define I2C_ICR_INIT (ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE) -#endif - -#define I2C_ISR_INIT 0x7FF - -#ifdef DEBUG_I2C -#define PRINTD(x) printf x -#else -#define PRINTD(x) -#endif - - -/* Shall the current transfer have a start/stop condition? */ -#define I2C_COND_NORMAL 0 -#define I2C_COND_START 1 -#define I2C_COND_STOP 2 - -/* Shall the current transfer be ack/nacked or being waited for it? */ -#define I2C_ACKNAK_WAITACK 1 -#define I2C_ACKNAK_SENDACK 2 -#define I2C_ACKNAK_SENDNAK 4 - -/* Specify who shall transfer the data (master or slave) */ -#define I2C_READ 0 -#define I2C_WRITE 1 - -/* All transfers are described by this data structure */ -struct i2c_msg { - u8 condition; - u8 acknack; - u8 direction; - u8 data; -}; - - -/** - * i2c_pxa_reset: - reset the host controller - * - */ - -static void i2c_reset( void ) -{ - ICR &= ~ICR_IUE; /* disable unit */ - ICR |= ICR_UR; /* reset the unit */ - udelay(100); - ICR &= ~ICR_IUE; /* disable unit */ -#ifdef CONFIG_CPU_MONAHANS - CKENB |= (CKENB_4_I2C); /* | CKENB_1_PWM1 | CKENB_0_PWM0); */ -#else /* CONFIG_CPU_MONAHANS */ - CKEN |= CKEN14_I2C; /* set the global I2C clock on */ -#endif - ISAR = I2C_PXA_SLAVE_ADDR; /* set our slave address */ - ICR = I2C_ICR_INIT; /* set control register values */ - ISR = I2C_ISR_INIT; /* set clear interrupt bits */ - ICR |= ICR_IUE; /* enable unit */ - udelay(100); -} - - -/** - * i2c_isr_set_cleared: - wait until certain bits of the I2C status register - * are set and cleared - * - * @return: 1 in case of success, 0 means timeout (no match within 10 ms). - */ -static int i2c_isr_set_cleared( unsigned long set_mask, unsigned long cleared_mask ) -{ - int timeout = 10000; - - while( ((ISR & set_mask)!=set_mask) || ((ISR & cleared_mask)!=0) ){ - udelay( 10 ); - if( timeout-- < 0 ) return 0; - } - - return 1; -} - - -/** - * i2c_transfer: - Transfer one byte over the i2c bus - * - * This function can tranfer a byte over the i2c bus in both directions. - * It is used by the public API functions. - * - * @return: 0: transfer successful - * -1: message is empty - * -2: transmit timeout - * -3: ACK missing - * -4: receive timeout - * -5: illegal parameters - * -6: bus is busy and couldn't be aquired - */ -int i2c_transfer(struct i2c_msg *msg) -{ - int ret; - - if (!msg) - goto transfer_error_msg_empty; - - switch(msg->direction) { - - case I2C_WRITE: - - /* check if bus is not busy */ - if (!i2c_isr_set_cleared(0,ISR_IBB)) - goto transfer_error_bus_busy; - - /* start transmission */ - ICR &= ~ICR_START; - ICR &= ~ICR_STOP; - IDBR = msg->data; - if (msg->condition == I2C_COND_START) ICR |= ICR_START; - if (msg->condition == I2C_COND_STOP) ICR |= ICR_STOP; - if (msg->acknack == I2C_ACKNAK_SENDNAK) ICR |= ICR_ACKNAK; - if (msg->acknack == I2C_ACKNAK_SENDACK) ICR &= ~ICR_ACKNAK; - ICR &= ~ICR_ALDIE; - ICR |= ICR_TB; - - /* transmit register empty? */ - if (!i2c_isr_set_cleared(ISR_ITE,0)) - goto transfer_error_transmit_timeout; - - /* clear 'transmit empty' state */ - ISR |= ISR_ITE; - - /* wait for ACK from slave */ - if (msg->acknack == I2C_ACKNAK_WAITACK) - if (!i2c_isr_set_cleared(0,ISR_ACKNAK)) - goto transfer_error_ack_missing; - break; - - case I2C_READ: - - /* check if bus is not busy */ - if (!i2c_isr_set_cleared(0,ISR_IBB)) - goto transfer_error_bus_busy; - - /* start receive */ - ICR &= ~ICR_START; - ICR &= ~ICR_STOP; - if (msg->condition == I2C_COND_START) ICR |= ICR_START; - if (msg->condition == I2C_COND_STOP) ICR |= ICR_STOP; - if (msg->acknack == I2C_ACKNAK_SENDNAK) ICR |= ICR_ACKNAK; - if (msg->acknack == I2C_ACKNAK_SENDACK) ICR &= ~ICR_ACKNAK; - ICR &= ~ICR_ALDIE; - ICR |= ICR_TB; - - /* receive register full? */ - if (!i2c_isr_set_cleared(ISR_IRF,0)) - goto transfer_error_receive_timeout; - - msg->data = IDBR; - - /* clear 'receive empty' state */ - ISR |= ISR_IRF; - - break; - - default: - - goto transfer_error_illegal_param; - - } - - return 0; - -transfer_error_msg_empty: - PRINTD(("i2c_transfer: error: 'msg' is empty\n")); - ret = -1; goto i2c_transfer_finish; - -transfer_error_transmit_timeout: - PRINTD(("i2c_transfer: error: transmit timeout\n")); - ret = -2; goto i2c_transfer_finish; - -transfer_error_ack_missing: - PRINTD(("i2c_transfer: error: ACK missing\n")); - ret = -3; goto i2c_transfer_finish; - -transfer_error_receive_timeout: - PRINTD(("i2c_transfer: error: receive timeout\n")); - ret = -4; goto i2c_transfer_finish; - -transfer_error_illegal_param: - PRINTD(("i2c_transfer: error: illegal parameters\n")); - ret = -5; goto i2c_transfer_finish; - -transfer_error_bus_busy: - PRINTD(("i2c_transfer: error: bus is busy\n")); - ret = -6; goto i2c_transfer_finish; - -i2c_transfer_finish: - PRINTD(("i2c_transfer: ISR: 0x%04x\n",ISR)); - i2c_reset(); - return ret; - -} - -/* ------------------------------------------------------------------------ */ -/* API Functions */ -/* ------------------------------------------------------------------------ */ - -void i2c_init(int speed, int slaveaddr) -{ -#ifdef CONFIG_SYS_I2C_INIT_BOARD - /* call board specific i2c bus reset routine before accessing the */ - /* environment, which might be in a chip on that bus. For details */ - /* about this problem see doc/I2C_Edge_Conditions. */ - i2c_init_board(); -#endif -} - - -/** - * i2c_probe: - Test if a chip answers for a given i2c address - * - * @chip: address of the chip which is searched for - * @return: 0 if a chip was found, -1 otherwhise - */ - -int i2c_probe(uchar chip) -{ - struct i2c_msg msg; - - i2c_reset(); - - msg.condition = I2C_COND_START; - msg.acknack = I2C_ACKNAK_WAITACK; - msg.direction = I2C_WRITE; - msg.data = (chip << 1) + 1; - if (i2c_transfer(&msg)) return -1; - - msg.condition = I2C_COND_STOP; - msg.acknack = I2C_ACKNAK_SENDNAK; - msg.direction = I2C_READ; - msg.data = 0x00; - if (i2c_transfer(&msg)) return -1; - - return 0; -} - - -/** - * i2c_read: - Read multiple bytes from an i2c device - * - * The higher level routines take into account that this function is only - * called with len < page length of the device (see configuration file) - * - * @chip: address of the chip which is to be read - * @addr: i2c data address within the chip - * @alen: length of the i2c data address (1..2 bytes) - * @buffer: where to write the data - * @len: how much byte do we want to read - * @return: 0 in case of success - */ - -int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) -{ - struct i2c_msg msg; - u8 addr_bytes[3]; /* lowest...highest byte of data address */ - int ret; - - PRINTD(("i2c_read(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len)); - - i2c_reset(); - - /* dummy chip address write */ - PRINTD(("i2c_read: dummy chip address write\n")); - msg.condition = I2C_COND_START; - msg.acknack = I2C_ACKNAK_WAITACK; - msg.direction = I2C_WRITE; - msg.data = (chip << 1); - msg.data &= 0xFE; - if ((ret=i2c_transfer(&msg))) return -1; - - /* - * send memory address bytes; - * alen defines how much bytes we have to send. - */ - /*addr &= ((1 << CONFIG_SYS_EEPROM_PAGE_WRITE_BITS)-1); */ - addr_bytes[0] = (u8)((addr >> 0) & 0x000000FF); - addr_bytes[1] = (u8)((addr >> 8) & 0x000000FF); - addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF); - - while (--alen >= 0) { - - PRINTD(("i2c_read: send memory word address byte %1d\n",alen)); - msg.condition = I2C_COND_NORMAL; - msg.acknack = I2C_ACKNAK_WAITACK; - msg.direction = I2C_WRITE; - msg.data = addr_bytes[alen]; - if ((ret=i2c_transfer(&msg))) return -1; - } - - - /* start read sequence */ - PRINTD(("i2c_read: start read sequence\n")); - msg.condition = I2C_COND_START; - msg.acknack = I2C_ACKNAK_WAITACK; - msg.direction = I2C_WRITE; - msg.data = (chip << 1); - msg.data |= 0x01; - if ((ret=i2c_transfer(&msg))) return -1; - - /* read bytes; send NACK at last byte */ - while (len--) { - - if (len==0) { - msg.condition = I2C_COND_STOP; - msg.acknack = I2C_ACKNAK_SENDNAK; - } else { - msg.condition = I2C_COND_NORMAL; - msg.acknack = I2C_ACKNAK_SENDACK; - } - - msg.direction = I2C_READ; - msg.data = 0x00; - if ((ret=i2c_transfer(&msg))) return -1; - - *buffer = msg.data; - PRINTD(("i2c_read: reading byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer)); - buffer++; - - } - - i2c_reset(); - - return 0; -} - - -/** - * i2c_write: - Write multiple bytes to an i2c device - * - * The higher level routines take into account that this function is only - * called with len < page length of the device (see configuration file) - * - * @chip: address of the chip which is to be written - * @addr: i2c data address within the chip - * @alen: length of the i2c data address (1..2 bytes) - * @buffer: where to find the data to be written - * @len: how much byte do we want to read - * @return: 0 in case of success - */ - -int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) -{ - struct i2c_msg msg; - u8 addr_bytes[3]; /* lowest...highest byte of data address */ - - PRINTD(("i2c_write(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len)); - - i2c_reset(); - - /* chip address write */ - PRINTD(("i2c_write: chip address write\n")); - msg.condition = I2C_COND_START; - msg.acknack = I2C_ACKNAK_WAITACK; - msg.direction = I2C_WRITE; - msg.data = (chip << 1); - msg.data &= 0xFE; - if (i2c_transfer(&msg)) return -1; - - /* - * send memory address bytes; - * alen defines how much bytes we have to send. - */ - addr_bytes[0] = (u8)((addr >> 0) & 0x000000FF); - addr_bytes[1] = (u8)((addr >> 8) & 0x000000FF); - addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF); - - while (--alen >= 0) { - - PRINTD(("i2c_write: send memory word address\n")); - msg.condition = I2C_COND_NORMAL; - msg.acknack = I2C_ACKNAK_WAITACK; - msg.direction = I2C_WRITE; - msg.data = addr_bytes[alen]; - if (i2c_transfer(&msg)) return -1; - } - - /* write bytes; send NACK at last byte */ - while (len--) { - - PRINTD(("i2c_write: writing byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer)); - - if (len==0) - msg.condition = I2C_COND_STOP; - else - msg.condition = I2C_COND_NORMAL; - - msg.acknack = I2C_ACKNAK_WAITACK; - msg.direction = I2C_WRITE; - msg.data = *(buffer++); - - if (i2c_transfer(&msg)) return -1; - - } - - i2c_reset(); - - return 0; - -} - -#endif /* CONFIG_HARD_I2C */ diff --git a/cpu/pxa/pxafb.c b/cpu/pxa/pxafb.c deleted file mode 100644 index d56c5f099f..0000000000 --- a/cpu/pxa/pxafb.c +++ /dev/null @@ -1,471 +0,0 @@ -/* - * PXA LCD Controller - * - * (C) Copyright 2001-2002 - * Wolfgang Denk, DENX Software Engineering -- wd@denx.de - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/************************************************************************/ -/* ** HEADER FILES */ -/************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* #define DEBUG */ - -#ifdef CONFIG_LCD - -/*----------------------------------------------------------------------*/ -/* - * Define panel bpp, LCCR0, LCCR3 and panel_info video struct for - * your display. - */ - -#ifdef CONFIG_PXA_VGA -/* LCD outputs connected to a video DAC */ -# define LCD_BPP LCD_COLOR8 - -/* you have to set lccr0 and lccr3 (including pcd) */ -# define REG_LCCR0 0x003008f8 -# define REG_LCCR3 0x0300FF01 - -/* 640x480x16 @ 61 Hz */ -vidinfo_t panel_info = { - vl_col: 640, - vl_row: 480, - vl_width: 640, - vl_height: 480, - vl_clkp: CONFIG_SYS_HIGH, - vl_oep: CONFIG_SYS_HIGH, - vl_hsp: CONFIG_SYS_HIGH, - vl_vsp: CONFIG_SYS_HIGH, - vl_dp: CONFIG_SYS_HIGH, - vl_bpix: LCD_BPP, - vl_lbw: 0, - vl_splt: 0, - vl_clor: 0, - vl_tft: 1, - vl_hpw: 40, - vl_blw: 56, - vl_elw: 56, - vl_vpw: 20, - vl_bfw: 8, - vl_efw: 8, -}; -#endif /* CONFIG_PXA_VIDEO */ - -/*----------------------------------------------------------------------*/ -#ifdef CONFIG_SHARP_LM8V31 - -# define LCD_BPP LCD_COLOR8 -# define LCD_INVERT_COLORS /* Needed for colors to be correct, but why? */ - -/* you have to set lccr0 and lccr3 (including pcd) */ -# define REG_LCCR0 0x0030087C -# define REG_LCCR3 0x0340FF08 - -vidinfo_t panel_info = { - vl_col: 640, - vl_row: 480, - vl_width: 157, - vl_height: 118, - vl_clkp: CONFIG_SYS_HIGH, - vl_oep: CONFIG_SYS_HIGH, - vl_hsp: CONFIG_SYS_HIGH, - vl_vsp: CONFIG_SYS_HIGH, - vl_dp: CONFIG_SYS_HIGH, - vl_bpix: LCD_BPP, - vl_lbw: 0, - vl_splt: 1, - vl_clor: 1, - vl_tft: 0, - vl_hpw: 1, - vl_blw: 3, - vl_elw: 3, - vl_vpw: 1, - vl_bfw: 0, - vl_efw: 0, -}; -#endif /* CONFIG_SHARP_LM8V31 */ - -/*----------------------------------------------------------------------*/ -#ifdef CONFIG_HITACHI_SX14 -/* Hitachi SX14Q004-ZZA color STN LCD */ -#define LCD_BPP LCD_COLOR8 - -/* you have to set lccr0 and lccr3 (including pcd) */ -#define REG_LCCR0 0x00301079 -#define REG_LCCR3 0x0340FF20 - -vidinfo_t panel_info = { - vl_col: 320, - vl_row: 240, - vl_width: 167, - vl_height: 109, - vl_clkp: CONFIG_SYS_HIGH, - vl_oep: CONFIG_SYS_HIGH, - vl_hsp: CONFIG_SYS_HIGH, - vl_vsp: CONFIG_SYS_HIGH, - vl_dp: CONFIG_SYS_HIGH, - vl_bpix: LCD_BPP, - vl_lbw: 1, - vl_splt: 0, - vl_clor: 1, - vl_tft: 0, - vl_hpw: 1, - vl_blw: 1, - vl_elw: 1, - vl_vpw: 7, - vl_bfw: 0, - vl_efw: 0, -}; -#endif /* CONFIG_HITACHI_SX14 */ - -/*----------------------------------------------------------------------*/ - -#if LCD_BPP == LCD_COLOR8 -void lcd_setcolreg (ushort regno, ushort red, ushort green, ushort blue); -#endif -#if LCD_BPP == LCD_MONOCHROME -void lcd_initcolregs (void); -#endif - -#ifdef NOT_USED_SO_FAR -void lcd_disable (void); -void lcd_getcolreg (ushort regno, ushort *red, ushort *green, ushort *blue); -#endif /* NOT_USED_SO_FAR */ - -void lcd_ctrl_init (void *lcdbase); -void lcd_enable (void); - -int lcd_line_length; -int lcd_color_fg; -int lcd_color_bg; - -void *lcd_base; /* Start of framebuffer memory */ -void *lcd_console_address; /* Start of console buffer */ - -short console_col; -short console_row; - -static int pxafb_init_mem (void *lcdbase, vidinfo_t *vid); -static void pxafb_setup_gpio (vidinfo_t *vid); -static void pxafb_enable_controller (vidinfo_t *vid); -static int pxafb_init (vidinfo_t *vid); -/************************************************************************/ - -/************************************************************************/ -/* --------------- PXA chipset specific functions ------------------- */ -/************************************************************************/ - -void lcd_ctrl_init (void *lcdbase) -{ - pxafb_init_mem(lcdbase, &panel_info); - pxafb_init(&panel_info); - pxafb_setup_gpio(&panel_info); - pxafb_enable_controller(&panel_info); -} - -/*----------------------------------------------------------------------*/ -#ifdef NOT_USED_SO_FAR -void -lcd_getcolreg (ushort regno, ushort *red, ushort *green, ushort *blue) -{ -} -#endif /* NOT_USED_SO_FAR */ - -/*----------------------------------------------------------------------*/ -#if LCD_BPP == LCD_COLOR8 -void -lcd_setcolreg (ushort regno, ushort red, ushort green, ushort blue) -{ - struct pxafb_info *fbi = &panel_info.pxa; - unsigned short *palette = (unsigned short *)fbi->palette; - u_int val; - - if (regno < fbi->palette_size) { - val = ((red << 8) & 0xf800); - val |= ((green << 4) & 0x07e0); - val |= (blue & 0x001f); - -#ifdef LCD_INVERT_COLORS - palette[regno] = ~val; -#else - palette[regno] = val; -#endif - } - - debug ("setcolreg: reg %2d @ %p: R=%02X G=%02X B=%02X => %04X\n", - regno, &palette[regno], - red, green, blue, - palette[regno]); -} -#endif /* LCD_COLOR8 */ - -/*----------------------------------------------------------------------*/ -#if LCD_BPP == LCD_MONOCHROME -void lcd_initcolregs (void) -{ - struct pxafb_info *fbi = &panel_info.pxa; - cmap = (ushort *)fbi->palette; - ushort regno; - - for (regno = 0; regno < 16; regno++) { - cmap[regno * 2] = 0; - cmap[(regno * 2) + 1] = regno & 0x0f; - } -} -#endif /* LCD_MONOCHROME */ - -/*----------------------------------------------------------------------*/ -void lcd_enable (void) -{ -} - -/*----------------------------------------------------------------------*/ -#ifdef NOT_USED_SO_FAR -static void lcd_disable (void) -{ -} -#endif /* NOT_USED_SO_FAR */ - -/*----------------------------------------------------------------------*/ - -/************************************************************************/ -/* ** PXA255 specific routines */ -/************************************************************************/ - -/* - * Calculate fb size for VIDEOLFB_ATAG. Size returned contains fb, - * descriptors and palette areas. - */ -ulong calc_fbsize (void) -{ - ulong size; - int line_length = (panel_info.vl_col * NBITS (panel_info.vl_bpix)) / 8; - - size = line_length * panel_info.vl_row; - size += PAGE_SIZE; - - return size; -} - -static int pxafb_init_mem (void *lcdbase, vidinfo_t *vid) -{ - u_long palette_mem_size; - struct pxafb_info *fbi = &vid->pxa; - int fb_size = vid->vl_row * (vid->vl_col * NBITS (vid->vl_bpix)) / 8; - - fbi->screen = (u_long)lcdbase; - - fbi->palette_size = NBITS(vid->vl_bpix) == 8 ? 256 : 16; - palette_mem_size = fbi->palette_size * sizeof(u16); - - debug("palette_mem_size = 0x%08lx\n", (u_long) palette_mem_size); - /* locate palette and descs at end of page following fb */ - fbi->palette = (u_long)lcdbase + fb_size + PAGE_SIZE - palette_mem_size; - - return 0; -} - -static void pxafb_setup_gpio (vidinfo_t *vid) -{ - u_long lccr0; - - /* - * setup is based on type of panel supported - */ - - lccr0 = vid->pxa.reg_lccr0; - - /* 4 bit interface */ - if ((lccr0 & LCCR0_CMS) && (lccr0 & LCCR0_SDS) && !(lccr0 & LCCR0_DPD)) - { - debug("Setting GPIO for 4 bit data\n"); - /* bits 58-61 */ - GPDR1 |= (0xf << 26); - GAFR1_U = (GAFR1_U & ~(0xff << 20)) | (0xaa << 20); - - /* bits 74-77 */ - GPDR2 |= (0xf << 10); - GAFR2_L = (GAFR2_L & ~(0xff << 20)) | (0xaa << 20); - } - - /* 8 bit interface */ - else if (((lccr0 & LCCR0_CMS) && ((lccr0 & LCCR0_SDS) || (lccr0 & LCCR0_DPD))) || - (!(lccr0 & LCCR0_CMS) && !(lccr0 & LCCR0_PAS) && !(lccr0 & LCCR0_SDS))) - { - debug("Setting GPIO for 8 bit data\n"); - /* bits 58-65 */ - GPDR1 |= (0x3f << 26); - GPDR2 |= (0x3); - - GAFR1_U = (GAFR1_U & ~(0xfff << 20)) | (0xaaa << 20); - GAFR2_L = (GAFR2_L & ~0xf) | (0xa); - - /* bits 74-77 */ - GPDR2 |= (0xf << 10); - GAFR2_L = (GAFR2_L & ~(0xff << 20)) | (0xaa << 20); - } - - /* 16 bit interface */ - else if (!(lccr0 & LCCR0_CMS) && ((lccr0 & LCCR0_SDS) || (lccr0 & LCCR0_PAS))) - { - debug("Setting GPIO for 16 bit data\n"); - /* bits 58-77 */ - GPDR1 |= (0x3f << 26); - GPDR2 |= 0x00003fff; - - GAFR1_U = (GAFR1_U & ~(0xfff << 20)) | (0xaaa << 20); - GAFR2_L = (GAFR2_L & 0xf0000000) | 0x0aaaaaaa; - } - else - { - printf("pxafb_setup_gpio: unable to determine bits per pixel\n"); - } -} - -static void pxafb_enable_controller (vidinfo_t *vid) -{ - debug("Enabling LCD controller\n"); - - /* Sequence from 11.7.10 */ - LCCR3 = vid->pxa.reg_lccr3; - LCCR2 = vid->pxa.reg_lccr2; - LCCR1 = vid->pxa.reg_lccr1; - LCCR0 = vid->pxa.reg_lccr0 & ~LCCR0_ENB; - FDADR0 = vid->pxa.fdadr0; - FDADR1 = vid->pxa.fdadr1; - LCCR0 |= LCCR0_ENB; - - CKEN |= CKEN16_LCD; - - debug("FDADR0 = 0x%08x\n", (unsigned int)FDADR0); - debug("FDADR1 = 0x%08x\n", (unsigned int)FDADR1); - debug("LCCR0 = 0x%08x\n", (unsigned int)LCCR0); - debug("LCCR1 = 0x%08x\n", (unsigned int)LCCR1); - debug("LCCR2 = 0x%08x\n", (unsigned int)LCCR2); - debug("LCCR3 = 0x%08x\n", (unsigned int)LCCR3); -} - -static int pxafb_init (vidinfo_t *vid) -{ - struct pxafb_info *fbi = &vid->pxa; - - debug("Configuring PXA LCD\n"); - - fbi->reg_lccr0 = REG_LCCR0; - fbi->reg_lccr3 = REG_LCCR3; - - debug("vid: vl_col=%d hslen=%d lm=%d rm=%d\n", - vid->vl_col, vid->vl_hpw, - vid->vl_blw, vid->vl_elw); - debug("vid: vl_row=%d vslen=%d um=%d bm=%d\n", - vid->vl_row, vid->vl_vpw, - vid->vl_bfw, vid->vl_efw); - - fbi->reg_lccr1 = - LCCR1_DisWdth(vid->vl_col) + - LCCR1_HorSnchWdth(vid->vl_hpw) + - LCCR1_BegLnDel(vid->vl_blw) + - LCCR1_EndLnDel(vid->vl_elw); - - fbi->reg_lccr2 = - LCCR2_DisHght(vid->vl_row) + - LCCR2_VrtSnchWdth(vid->vl_vpw) + - LCCR2_BegFrmDel(vid->vl_bfw) + - LCCR2_EndFrmDel(vid->vl_efw); - - fbi->reg_lccr3 = REG_LCCR3 & ~(LCCR3_HSP | LCCR3_VSP); - fbi->reg_lccr3 |= (vid->vl_hsp ? LCCR3_HorSnchL : LCCR3_HorSnchH) - | (vid->vl_vsp ? LCCR3_VrtSnchL : LCCR3_VrtSnchH); - - - /* setup dma descriptors */ - fbi->dmadesc_fblow = (struct pxafb_dma_descriptor *)((unsigned int)fbi->palette - 3*16); - fbi->dmadesc_fbhigh = (struct pxafb_dma_descriptor *)((unsigned int)fbi->palette - 2*16); - fbi->dmadesc_palette = (struct pxafb_dma_descriptor *)((unsigned int)fbi->palette - 1*16); - - #define BYTES_PER_PANEL ((fbi->reg_lccr0 & LCCR0_SDS) ? \ - (vid->vl_col * vid->vl_row * NBITS(vid->vl_bpix) / 8 / 2) : \ - (vid->vl_col * vid->vl_row * NBITS(vid->vl_bpix) / 8)) - - /* populate descriptors */ - fbi->dmadesc_fblow->fdadr = (u_long)fbi->dmadesc_fblow; - fbi->dmadesc_fblow->fsadr = fbi->screen + BYTES_PER_PANEL; - fbi->dmadesc_fblow->fidr = 0; - fbi->dmadesc_fblow->ldcmd = BYTES_PER_PANEL; - - fbi->fdadr1 = (u_long)fbi->dmadesc_fblow; /* only used in dual-panel mode */ - - fbi->dmadesc_fbhigh->fsadr = fbi->screen; - fbi->dmadesc_fbhigh->fidr = 0; - fbi->dmadesc_fbhigh->ldcmd = BYTES_PER_PANEL; - - fbi->dmadesc_palette->fsadr = fbi->palette; - fbi->dmadesc_palette->fidr = 0; - fbi->dmadesc_palette->ldcmd = (fbi->palette_size * 2) | LDCMD_PAL; - - if( NBITS(vid->vl_bpix) < 12) - { - /* assume any mode with <12 bpp is palette driven */ - fbi->dmadesc_palette->fdadr = (u_long)fbi->dmadesc_fbhigh; - fbi->dmadesc_fbhigh->fdadr = (u_long)fbi->dmadesc_palette; - /* flips back and forth between pal and fbhigh */ - fbi->fdadr0 = (u_long)fbi->dmadesc_palette; - } - else - { - /* palette shouldn't be loaded in true-color mode */ - fbi->dmadesc_fbhigh->fdadr = (u_long)fbi->dmadesc_fbhigh; - fbi->fdadr0 = (u_long)fbi->dmadesc_fbhigh; /* no pal just fbhigh */ - } - - debug("fbi->dmadesc_fblow = 0x%lx\n", (u_long)fbi->dmadesc_fblow); - debug("fbi->dmadesc_fbhigh = 0x%lx\n", (u_long)fbi->dmadesc_fbhigh); - debug("fbi->dmadesc_palette = 0x%lx\n", (u_long)fbi->dmadesc_palette); - - debug("fbi->dmadesc_fblow->fdadr = 0x%lx\n", fbi->dmadesc_fblow->fdadr); - debug("fbi->dmadesc_fbhigh->fdadr = 0x%lx\n", fbi->dmadesc_fbhigh->fdadr); - debug("fbi->dmadesc_palette->fdadr = 0x%lx\n", fbi->dmadesc_palette->fdadr); - - debug("fbi->dmadesc_fblow->fsadr = 0x%lx\n", fbi->dmadesc_fblow->fsadr); - debug("fbi->dmadesc_fbhigh->fsadr = 0x%lx\n", fbi->dmadesc_fbhigh->fsadr); - debug("fbi->dmadesc_palette->fsadr = 0x%lx\n", fbi->dmadesc_palette->fsadr); - - debug("fbi->dmadesc_fblow->ldcmd = 0x%lx\n", fbi->dmadesc_fblow->ldcmd); - debug("fbi->dmadesc_fbhigh->ldcmd = 0x%lx\n", fbi->dmadesc_fbhigh->ldcmd); - debug("fbi->dmadesc_palette->ldcmd = 0x%lx\n", fbi->dmadesc_palette->ldcmd); - - return 0; -} - -/************************************************************************/ -/************************************************************************/ - -#endif /* CONFIG_LCD */ diff --git a/cpu/pxa/start.S b/cpu/pxa/start.S deleted file mode 100644 index 63ab0c591a..0000000000 --- a/cpu/pxa/start.S +++ /dev/null @@ -1,498 +0,0 @@ -/* - * armboot - Startup Code for XScale - * - * Copyright (C) 1998 Dan Malek - * Copyright (C) 1999 Magnus Damm - * Copyright (C) 2000 Wolfgang Denk - * Copyright (C) 2001 Alex Zuepke - * Copyright (C) 2002 Kyle Harris - * Copyright (C) 2003 Robert Schwebel - * Copyright (C) 2003 Kai-Uwe Bloem - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -.globl _start -_start: b 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 - -_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 RAM! - * - relocate armboot to RAM - * - setup stack - * - jump to second stage - */ - -_TEXT_BASE: - .word TEXT_BASE - -.globl _armboot_start -_armboot_start: - .word _start - -/* - * These are defined in the board-specific linker script. - */ -.globl _bss_start -_bss_start: - .word __bss_start - -.globl _bss_end -_bss_end: - .word _end - -#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 /* CONFIG_USE_IRQ */ - - -/****************************************************************************/ -/* */ -/* the actual reset code */ -/* */ -/****************************************************************************/ - -reset: - mrs r0,cpsr /* set the CPU to SVC32 mode */ - bic r0,r0,#0x1f /* (superviser mode, M=10011) */ - orr r0,r0,#0x13 - msr cpsr,r0 - - /* - * we do sys-critical inits only at reboot, - * not when booting from RAM! - */ -#ifndef CONFIG_SKIP_LOWLEVEL_INIT - bl cpu_init_crit /* we do sys-critical inits */ -#endif /* !CONFIG_SKIP_LOWLEVEL_INIT */ - -#ifndef CONFIG_SKIP_RELOCATE_UBOOT -relocate: /* relocate U-Boot to RAM */ - adr r0, _start /* r0 <- current position of code */ - ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ - cmp r0, r1 /* don't reloc during debug */ - beq stack_setup - - ldr r2, _armboot_start - ldr r3, _bss_start - sub r2, r3, r2 /* r2 <- size of armboot */ - add r2, r0, r2 /* r2 <- source end address */ - -copy_loop: - ldmia r0!, {r3-r10} /* copy from source address [r0] */ - stmia r1!, {r3-r10} /* copy to target address [r1] */ - cmp r0, r2 /* until source end address [r2] */ - ble copy_loop -#endif /* !CONFIG_SKIP_RELOCATE_UBOOT */ - - /* Set up the stack */ -stack_setup: - ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ - sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */ - sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ -#ifdef CONFIG_USE_IRQ - sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) -#endif /* CONFIG_USE_IRQ */ - sub sp, r0, #12 /* leave 3 words for abort-stack */ - -clear_bss: - ldr r0, _bss_start /* find start of bss segment */ - ldr r1, _bss_end /* stop here */ - mov r2, #0x00000000 /* clear */ - -clbss_l:str r2, [r0] /* clear loop... */ - add r0, r0, #4 - cmp r0, r1 - ble clbss_l - - ldr pc, _start_armboot - -_start_armboot: .word start_armboot - - -/****************************************************************************/ -/* */ -/* CPU_init_critical registers */ -/* */ -/* - setup important registers */ -/* - setup memory timing */ -/* */ -/****************************************************************************/ -/* mk@tbd: Fix this! */ -#undef RCSR -#undef ICMR -#undef OSMR3 -#undef OSCR -#undef OWER -#undef OIER -#undef CCCR - -/* Interrupt-Controller base address */ -IC_BASE: .word 0x40d00000 -#define ICMR 0x04 - -/* Reset-Controller */ -RST_BASE: .word 0x40f00030 -#define RCSR 0x00 - -/* Operating System Timer */ -OSTIMER_BASE: .word 0x40a00000 -#define OSMR3 0x0C -#define OSCR 0x10 -#define OWER 0x18 -#define OIER 0x1C - -/* Clock Manager Registers */ -#ifdef CONFIG_CPU_MONAHANS -# ifndef CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO -# error "You have to define CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO!!" -# endif /* !CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO */ -# ifndef CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO -# define CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO 0x1 -# endif /* !CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO */ -#else /* !CONFIG_CPU_MONAHANS */ -#ifdef CONFIG_SYS_CPUSPEED -CC_BASE: .word 0x41300000 -#define CCCR 0x00 -cpuspeed: .word CONFIG_SYS_CPUSPEED -#else /* !CONFIG_SYS_CPUSPEED */ -#error "You have to define CONFIG_SYS_CPUSPEED!!" -#endif /* CONFIG_SYS_CPUSPEED */ -#endif /* CONFIG_CPU_MONAHANS */ - - /* takes care the CP15 update has taken place */ - .macro CPWAIT reg - mrc p15,0,\reg,c2,c0,0 - mov \reg,\reg - sub pc,pc,#4 - .endm - -cpu_init_crit: - - /* mask all IRQs */ -#ifndef CONFIG_CPU_MONAHANS - ldr r0, IC_BASE - mov r1, #0x00 - str r1, [r0, #ICMR] -#else /* CONFIG_CPU_MONAHANS */ - /* Step 1 - Enable CP6 permission */ - mrc p15, 0, r1, c15, c1, 0 @ read CPAR - orr r1, r1, #0x40 - mcr p15, 0, r1, c15, c1, 0 - CPWAIT r1 - - /* Step 2 - Mask ICMR & ICMR2 */ - mov r1, #0 - mcr p6, 0, r1, c1, c0, 0 @ ICMR - mcr p6, 0, r1, c7, c0, 0 @ ICMR2 - - /* turn off all clocks but the ones we will definitly require */ - ldr r1, =CKENA - ldr r2, =(CKENA_22_FFUART | CKENA_10_SRAM | CKENA_9_SMC | CKENA_8_DMC) - str r2, [r1] - ldr r1, =CKENB - ldr r2, =(CKENB_6_IRQ) - str r2, [r1] -#endif /* !CONFIG_CPU_MONAHANS */ - - /* set clock speed */ -#ifdef CONFIG_CPU_MONAHANS - ldr r0, =ACCR - ldr r1, =(((CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO<<8) & ACCR_XN_MASK) | (CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO & ACCR_XL_MASK)) - str r1, [r0] -#else /* !CONFIG_CPU_MONAHANS */ -#ifdef CONFIG_SYS_CPUSPEED - ldr r0, CC_BASE - ldr r1, cpuspeed - str r1, [r0, #CCCR] - mov r0, #2 - mcr p14, 0, r0, c6, c0, 0 - -setspeed_done: - -#endif /* CONFIG_SYS_CPUSPEED */ -#endif /* CONFIG_CPU_MONAHANS */ - - /* - * before relocating, we have to setup RAM timing - * because memory timing is board-dependend, you will - * find a lowlevel_init.S in your board directory. - */ - mov ip, lr - bl lowlevel_init - mov lr, ip - - /* Memory interfaces are working. Disable MMU and enable I-cache. */ - /* mk: hmm, this is not in the monahans docs, leave it now but - * check here if it doesn't work :-) */ - - ldr r0, =0x2001 /* enable access to all coproc. */ - mcr p15, 0, r0, c15, c1, 0 - CPWAIT r0 - - mcr p15, 0, r0, c7, c10, 4 /* drain the write & fill buffers */ - CPWAIT r0 - - mcr p15, 0, r0, c7, c7, 0 /* flush Icache, Dcache and BTB */ - CPWAIT r0 - - mcr p15, 0, r0, c8, c7, 0 /* flush instuction and data TLBs */ - CPWAIT r0 - - /* Enable the Icache */ -/* - mrc p15, 0, r0, c1, c0, 0 - orr r0, r0, #0x1800 - mcr p15, 0, r0, c1, c0, 0 - CPWAIT -*/ - mov pc, 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, _armboot_start - sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) - sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack - 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, _armboot_start @ setup our mode stack - sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) - sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort 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 /* !CONFIG_USE_IRQ */ - - .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 /* CONFIG_USE_IRQ */ - -/****************************************************************************/ -/* */ -/* Reset function: the PXA250 doesn't have a reset function, so we have to */ -/* perform a watchdog timeout for a soft reset. */ -/* */ -/****************************************************************************/ - - .align 5 -.globl reset_cpu - - /* FIXME: this code is PXA250 specific. How is this handled on */ - /* other XScale processors? */ - -reset_cpu: - - /* We set OWE:WME (watchdog enable) and wait until timeout happens */ - - ldr r0, OSTIMER_BASE - ldr r1, [r0, #OWER] - orr r1, r1, #0x0001 /* bit0: WME */ - str r1, [r0, #OWER] - - /* OS timer does only wrap every 1165 seconds, so we have to set */ - /* the match register as well. */ - - ldr r1, [r0, #OSCR] /* read OS timer */ - add r1, r1, #0x800 /* let OSMR3 match after */ - add r1, r1, #0x800 /* 4096*(1/3.6864MHz)=1ms */ - str r1, [r0, #OSMR3] - -reset_endless: - - b reset_endless diff --git a/cpu/pxa/timer.c b/cpu/pxa/timer.c deleted file mode 100644 index 8d0f82679b..0000000000 --- a/cpu/pxa/timer.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -#ifdef CONFIG_USE_IRQ -#error: interrupts not implemented yet -#endif - -#if defined(CONFIG_PXA27X) || defined(CONFIG_CPU_MONAHANS) -#define TIMER_FREQ_HZ 3250000 -#elif defined(CONFIG_PXA250) -#define TIMER_FREQ_HZ 3686400 -#else -#error "Timer frequency unknown - please config PXA CPU type" -#endif - -static inline unsigned long long tick_to_time(unsigned long long tick) -{ - tick *= CONFIG_SYS_HZ; - do_div(tick, TIMER_FREQ_HZ); - return tick; -} - -static inline unsigned long long us_to_tick(unsigned long long us) -{ - us = us * TIMER_FREQ_HZ + 999999; - do_div(us, 1000000); - return us; -} - -int timer_init (void) -{ - reset_timer(); - - return 0; -} - -void reset_timer (void) -{ - reset_timer_masked (); -} - -ulong get_timer (ulong base) -{ - return get_timer_masked () - base; -} - -void set_timer (ulong t) -{ - /* nop */ -} - -void __udelay (unsigned long usec) -{ - udelay_masked (usec); -} - - -void reset_timer_masked (void) -{ - OSCR = 0; -} - -ulong get_timer_masked (void) -{ - return tick_to_time(get_ticks()); -} - -void udelay_masked (unsigned long usec) -{ - unsigned long long tmp; - ulong tmo; - - tmo = us_to_tick(usec); - tmp = get_ticks() + tmo; /* get current timestamp */ - - while (get_ticks() < tmp) /* loop till event */ - /*NOP*/; - -} - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return OSCR; -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk (void) -{ - ulong tbclk; - tbclk = TIMER_FREQ_HZ; - return tbclk; -} diff --git a/cpu/pxa/u-boot.lds b/cpu/pxa/u-boot.lds deleted file mode 100644 index 77ab3c902b..0000000000 --- a/cpu/pxa/u-boot.lds +++ /dev/null @@ -1,56 +0,0 @@ -/* - * (C) Copyright 2000-2005 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -ENTRY(_start) -SECTIONS -{ - . = 0x00000000; - - . = ALIGN(4); - .text : - { - cpu/pxa/start.o (.text) - *(.text) - } - - . = ALIGN(4); - .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } - - . = ALIGN(4); - .data : { *(.data) } - - . = ALIGN(4); - .got : { *(.got) } - - . = .; - __u_boot_cmd_start = .; - .u_boot_cmd : { *(.u_boot_cmd) } - __u_boot_cmd_end = .; - - . = ALIGN(4); - __bss_start = .; - .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } - _end = .; -} diff --git a/cpu/pxa/usb.c b/cpu/pxa/usb.c deleted file mode 100644 index bd718a6fff..0000000000 --- a/cpu/pxa/usb.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * (C) Copyright 2006 - * Markus Klotzbuecher, DENX Software Engineering - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include - -#if defined(CONFIG_USB_OHCI_NEW) && defined(CONFIG_SYS_USB_OHCI_CPU_INIT) -# if defined(CONFIG_CPU_MONAHANS) || defined(CONFIG_PXA27X) - -#include -#include - -int usb_cpu_init(void) -{ -#if defined(CONFIG_CPU_MONAHANS) - /* Enable USB host clock. */ - CKENA |= (CKENA_2_USBHOST | CKENA_20_UDC); - udelay(100); -#endif -#if defined(CONFIG_PXA27X) - /* Enable USB host clock. */ - CKEN |= CKEN10_USBHOST; -#endif - -#if defined(CONFIG_CPU_MONAHANS) - /* Configure Port 2 for Host (USB Client Registers) */ - UP2OCR = 0x3000c; -#endif - - UHCHR |= UHCHR_FHR; - wait_ms(11); - UHCHR &= ~UHCHR_FHR; - - UHCHR |= UHCHR_FSBIR; - while (UHCHR & UHCHR_FSBIR) - udelay(1); - -#if defined(CONFIG_CPU_MONAHANS) - UHCHR &= ~UHCHR_SSEP0; -#endif -#if defined(CONFIG_PXA27X) - UHCHR &= ~UHCHR_SSEP2; -#endif - UHCHR &= ~UHCHR_SSEP1; - UHCHR &= ~UHCHR_SSE; - - return 0; -} - -int usb_cpu_stop(void) -{ - UHCHR |= UHCHR_FHR; - udelay(11); - UHCHR &= ~UHCHR_FHR; - - UHCCOMS |= 1; - udelay(10); - -#if defined(CONFIG_CPU_MONAHANS) - UHCHR |= UHCHR_SSEP0; -#endif -#if defined(CONFIG_PXA27X) - UHCHR |= UHCHR_SSEP2; -#endif - UHCHR |= UHCHR_SSEP1; - UHCHR |= UHCHR_SSE; - - return 0; -} - -int usb_cpu_init_fail(void) -{ - UHCHR |= UHCHR_FHR; - udelay(11); - UHCHR &= ~UHCHR_FHR; - - UHCCOMS |= 1; - udelay(10); - -#if defined(CONFIG_CPU_MONAHANS) - UHCHR |= UHCHR_SSEP0; -#endif -#if defined(CONFIG_PXA27X) - UHCHR |= UHCHR_SSEP2; -#endif - UHCHR |= UHCHR_SSEP1; - UHCHR |= UHCHR_SSE; - - return 0; -} - -# endif /* defined(CONFIG_CPU_MONAHANS) || defined(CONFIG_PXA27X) */ -#endif /* defined(CONFIG_USB_OHCI) && defined(CONFIG_SYS_USB_OHCI_CPU_INIT) */ diff --git a/cpu/s3c44b0/Makefile b/cpu/s3c44b0/Makefile deleted file mode 100644 index 6da2016f66..0000000000 --- a/cpu/s3c44b0/Makefile +++ /dev/null @@ -1,50 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(CPU).a - -START = start.o - -COBJS += cache.o -COBJS += cpu.o -COBJS += timer.o - -SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) -START := $(addprefix $(obj),$(START)) - -all: $(obj).depend $(START) $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/s3c44b0/cache.c b/cpu/s3c44b0/cache.c deleted file mode 100644 index 66974f61a6..0000000000 --- a/cpu/s3c44b0/cache.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * (C) Copyright 2004 - * DAVE Srl - * http://www.dave-tech.it - * http://www.wawnet.biz - * mailto:info@wawnet.biz - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -static void s3c44b0_flush_cache(void) -{ - volatile int i; - /* flush cycle */ - for(i=0x10002000;i<0x10004800;i+=16) - { - *((int *)i)=0x0; - } -} - -void icache_enable (void) -{ - ulong reg; - - s3c44b0_flush_cache(); - - /* - Init cache - Non-cacheable area (everything outside RAM) - 0x0000:0000 - 0x0C00:0000 - */ - NCACHBE0 = 0xC0000000; - NCACHBE1 = 0x00000000; - - /* - Enable chache - */ - reg = SYSCFG; - reg |= 0x00000006; /* 8kB */ - SYSCFG = reg; -} - -void icache_disable (void) -{ - ulong reg; - - reg = SYSCFG; - reg &= ~0x00000006; /* 8kB */ - SYSCFG = reg; -} - -int icache_status (void) -{ - return 0; -} - -void dcache_enable (void) -{ - icache_enable(); -} - -void dcache_disable (void) -{ - icache_disable(); -} - -int dcache_status (void) -{ - return dcache_status(); -} diff --git a/cpu/s3c44b0/config.mk b/cpu/s3c44b0/config.mk deleted file mode 100644 index 7454d728a5..0000000000 --- a/cpu/s3c44b0/config.mk +++ /dev/null @@ -1,33 +0,0 @@ -# -# (C) Copyright 2002 -# Sysgo Real-Time Solutions, GmbH -# Marius Groeger -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float - -PLATFORM_CPPFLAGS += -march=armv4 -mtune=arm7tdmi -msoft-float -# ========================================================================= -# -# Supply options according to compiler version -# -# ======================================================================== -PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/s3c44b0/cpu.c b/cpu/s3c44b0/cpu.c deleted file mode 100644 index bca38f81d3..0000000000 --- a/cpu/s3c44b0/cpu.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * (C) Copyright 2004 - * DAVE Srl - * http://www.dave-tech.it - * http://www.wawnet.biz - * mailto:info@wawnet.biz - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * S3C44B0 CPU specific code - */ - -#include -#include -#include - -int arch_cpu_init (void) -{ - icache_enable(); - - return 0; -} - -int cleanup_before_linux (void) -{ - /* - cache memory should be enabled before calling - Linux to make the kernel uncompression faster - */ - icache_enable(); - - disable_interrupts (); - - return 0; -} - -void reset_cpu (ulong addr) -{ - /* - reset the cpu using watchdog - */ - - /* Disable the watchdog.*/ - WTCON&=~(1<<5); - - /* set the timeout value to a short time... */ - WTCNT = 0x1; - - /* Enable the watchdog. */ - WTCON|=1; - WTCON|=(1<<5); - - while(1) { - /*NOP*/ - } -} diff --git a/cpu/s3c44b0/start.S b/cpu/s3c44b0/start.S deleted file mode 100644 index f5a3d3ac38..0000000000 --- a/cpu/s3c44b0/start.S +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Startup Code for S3C44B0 CPU-core - * - * (C) Copyright 2004 - * DAVE Srl - * - * http://www.dave-tech.it - * http://www.wawnet.biz - * mailto:info@wawnet.biz - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - - -#include -#include - - -/* - * Jump vector table - */ - - -.globl _start -_start: b reset - add pc, pc, #0x0c000000 - add pc, pc, #0x0c000000 - add pc, pc, #0x0c000000 - add pc, pc, #0x0c000000 - add pc, pc, #0x0c000000 - add pc, pc, #0x0c000000 - add pc, pc, #0x0c000000 - - .balignl 16,0xdeadbeef - - -/* - ************************************************************************* - * - * Startup Code (reset vector) - * - * do important init only if we don't start from memory! - * relocate u-boot to ram - * setup stack - * jump to second stage - * - ************************************************************************* - */ - -_TEXT_BASE: - .word TEXT_BASE - -.globl _armboot_start -_armboot_start: - .word _start - -/* - * These are defined in the board-specific linker script. - */ -.globl _bss_start -_bss_start: - .word __bss_start - -.globl _bss_end -_bss_end: - .word _end - -#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 - - -/* - * the actual reset code - */ - -reset: - /* - * set the cpu to SVC32 mode - */ - mrs r0,cpsr - bic r0,r0,#0x1f - orr r0,r0,#0x13 - msr cpsr,r0 - - /* - * we do sys-critical inits only at reboot, - * not when booting from ram! - */ - -#ifndef CONFIG_SKIP_LOWLEVEL_INIT - bl cpu_init_crit - /* - * before relocating, we have to setup RAM timing - * because memory timing is board-dependend, you will - * find a lowlevel_init.S in your board directory. - */ - bl lowlevel_init -#endif - -#ifndef CONFIG_SKIP_RELOCATE_UBOOT -relocate: /* relocate U-Boot to RAM */ - adr r0, _start /* r0 <- current position of code */ - ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ - cmp r0, r1 /* don't reloc during debug */ - beq stack_setup - - ldr r2, _armboot_start - ldr r3, _bss_start - sub r2, r3, r2 /* r2 <- size of armboot */ - add r2, r0, r2 /* r2 <- source end address */ - -copy_loop: - ldmia r0!, {r3-r10} /* copy from source address [r0] */ - stmia r1!, {r3-r10} /* copy to target address [r1] */ - cmp r0, r2 /* until source end addreee [r2] */ - ble copy_loop - -/* - now copy to sram the interrupt vector -*/ - adr r0, real_vectors - add r2, r0, #1024 - ldr r1, =0x0c000000 - add r1, r1, #0x08 -vector_copy_loop: - ldmia r0!, {r3-r10} - stmia r1!, {r3-r10} - cmp r0, r2 - ble vector_copy_loop -#endif /* CONFIG_SKIP_RELOCATE_UBOOT */ - - /* Set up the stack */ -stack_setup: - ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ - sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */ - sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ -#ifdef CONFIG_USE_IRQ - sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) -#endif - sub sp, r0, #12 /* leave 3 words for abort-stack */ - - ldr pc, _start_armboot - -_start_armboot: .word start_armboot - - -/* - ************************************************************************* - * - * CPU_init_critical registers - * - * setup important registers - * setup memory timing - * - ************************************************************************* - */ - -#define INTCON (0x01c00000+0x200000) -#define INTMSK (0x01c00000+0x20000c) -#define LOCKTIME (0x01c00000+0x18000c) -#define PLLCON (0x01c00000+0x180000) -#define CLKCON (0x01c00000+0x180004) -#define WTCON (0x01c00000+0x130000) -cpu_init_crit: - /* disable watch dog */ - ldr r0, =WTCON - ldr r1, =0x0 - str r1, [r0] - - /* - * mask all IRQs by clearing all bits in the INTMRs - */ - ldr r1,=INTMSK - ldr r0, =0x03fffeff - str r0, [r1] - - ldr r1, =INTCON - ldr r0, =0x05 - str r0, [r1] - - /* Set Clock Control Register */ - ldr r1, =LOCKTIME - ldrb r0, =800 - strb r0, [r1] - - ldr r1, =PLLCON - -#if CONFIG_S3C44B0_CLOCK_SPEED==66 - ldr r0, =0x34031 /* 66MHz (Quartz=11MHz) */ -#elif CONFIG_S3C44B0_CLOCK_SPEED==75 - ldr r0, =0x610c1 /*B2: Xtal=20mhz Fclk=75MHz */ -#else -# error CONFIG_S3C44B0_CLOCK_SPEED undefined -#endif - - str r0, [r1] - - ldr r1,=CLKCON - ldr r0, =0x7ff8 - str r0, [r1] - - mov pc, lr - - -/*************************************************/ -/* interrupt vectors */ -/*************************************************/ -real_vectors: - b reset - b undefined_instruction - b software_interrupt - b prefetch_abort - b data_abort - b not_used - b irq - b fiq - -/*************************************************/ - -undefined_instruction: - mov r6, #3 - b reset - -software_interrupt: - mov r6, #4 - b reset - -prefetch_abort: - mov r6, #5 - b reset - -data_abort: - mov r6, #6 - b reset - -not_used: - /* we *should* never reach this */ - mov r6, #7 - b reset - -irq: - mov r6, #8 - b reset - -fiq: - mov r6, #9 - b reset diff --git a/cpu/s3c44b0/timer.c b/cpu/s3c44b0/timer.c deleted file mode 100644 index 6f1d8f677a..0000000000 --- a/cpu/s3c44b0/timer.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * (C) Copyright 2004 - * DAVE Srl - * http://www.dave-tech.it - * http://www.wawnet.biz - * mailto:info@wawnet.biz - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include - -/* we always count down the max. */ -#define TIMER_LOAD_VAL 0xffff - -/* macro to read the 16 bit timer */ -#define READ_TIMER (TCNTO1 & 0xffff) - -#ifdef CONFIG_USE_IRQ -#error CONFIG_USE_IRQ NOT supported -#endif - -static ulong timestamp; -static ulong lastdec; - -int timer_init (void) -{ - TCFG0 = 0x000000E9; - TCFG1 = 0x00000004; - TCON = 0x00000900; - TCNTB1 = TIMER_LOAD_VAL; - TCMPB1 = 0; - TCON = 0x00000B00; - TCON = 0x00000900; - - - lastdec = TCNTB1 = TIMER_LOAD_VAL; - timestamp = 0; - return 0; -} - -/* - * timer without interrupts - */ - -void reset_timer (void) -{ - reset_timer_masked (); -} - -ulong get_timer (ulong base) -{ - return get_timer_masked () - base; -} - -void set_timer (ulong t) -{ - timestamp = t; -} - -void __udelay (unsigned long usec) -{ - ulong tmo; - - tmo = usec / 1000; - tmo *= CONFIG_SYS_HZ; - tmo /= 8; - - tmo += get_timer (0); - - while (get_timer_masked () < tmo) - /*NOP*/; -} - -void reset_timer_masked (void) -{ - /* reset time */ - lastdec = READ_TIMER; - timestamp = 0; -} - -ulong get_timer_masked (void) -{ - ulong now = READ_TIMER; - - if (lastdec >= now) { - /* normal mode */ - timestamp += lastdec - now; - } else { - /* we have an overflow ... */ - timestamp += lastdec + TIMER_LOAD_VAL - now; - } - lastdec = now; - - return timestamp; -} - -void udelay_masked (unsigned long usec) -{ - ulong tmo; - ulong endtime; - signed long diff; - - if (usec >= 1000) { - tmo = usec / 1000; - tmo *= CONFIG_SYS_HZ; - tmo /= 8; - } else { - tmo = usec * CONFIG_SYS_HZ; - tmo /= (1000*8); - } - - endtime = get_timer(0) + tmo; - - do { - ulong now = get_timer_masked (); - diff = endtime - now; - } while (diff >= 0); -} diff --git a/cpu/s3c44b0/u-boot.lds b/cpu/s3c44b0/u-boot.lds deleted file mode 100644 index 41ca3b4e8d..0000000000 --- a/cpu/s3c44b0/u-boot.lds +++ /dev/null @@ -1,56 +0,0 @@ -/* - * (C) Copyright 2000-2004 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -ENTRY(_start) -SECTIONS -{ - . = 0x00000000; - - . = ALIGN(4); - .text : - { - cpu/s3c44b0/start.o (.text) - *(.text) - } - - . = ALIGN(4); - .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } - - . = ALIGN(4); - .data : { *(.data) } - - . = ALIGN(4); - .got : { *(.got) } - - . = .; - __u_boot_cmd_start = .; - .u_boot_cmd : { *(.u_boot_cmd) } - __u_boot_cmd_end = .; - - . = ALIGN(4); - __bss_start = .; - .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } - _end = .; -} diff --git a/cpu/sa1100/Makefile b/cpu/sa1100/Makefile deleted file mode 100644 index 28b668267c..0000000000 --- a/cpu/sa1100/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(CPU).a - -START = start.o - -COBJS += cpu.o -COBJS += timer.o - -SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) -START := $(addprefix $(obj),$(START)) - -all: $(obj).depend $(START) $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/sa1100/config.mk b/cpu/sa1100/config.mk deleted file mode 100644 index 6f21f410be..0000000000 --- a/cpu/sa1100/config.mk +++ /dev/null @@ -1,33 +0,0 @@ -# -# (C) Copyright 2002 -# Sysgo Real-Time Solutions, GmbH -# Marius Groeger -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float - -PLATFORM_CPPFLAGS += -march=armv4 -mtune=strongarm1100 -# ========================================================================= -# -# Supply options according to compiler version -# -# ======================================================================== -PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/sa1100/cpu.c b/cpu/sa1100/cpu.c deleted file mode 100644 index 58e90dc9f6..0000000000 --- a/cpu/sa1100/cpu.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * CPU specific code - */ - -#include -#include -#include - -#ifdef CONFIG_USE_IRQ -DECLARE_GLOBAL_DATA_PTR; -#endif - -static void cache_flush(void); - -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)); -} diff --git a/cpu/sa1100/start.S b/cpu/sa1100/start.S deleted file mode 100644 index 278c5008fb..0000000000 --- a/cpu/sa1100/start.S +++ /dev/null @@ -1,419 +0,0 @@ -/* - * armboot - Startup Code for SA1100 CPU - * - * Copyright (C) 1998 Dan Malek - * Copyright (C) 1999 Magnus Damm - * Copyright (C) 2000 Wolfgang Denk - * Copyright (c) 2001 Alex Züpke - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - - -#include -#include - - -/* - ************************************************************************* - * - * Jump vector table as in table 3.1 in [1] - * - ************************************************************************* - */ - - -.globl _start -_start: b 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 - -_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 - * - ************************************************************************* - */ - -_TEXT_BASE: - .word TEXT_BASE - -.globl _armboot_start -_armboot_start: - .word _start - -/* - * These are defined in the board-specific linker script. - */ -.globl _bss_start -_bss_start: - .word __bss_start - -.globl _bss_end -_bss_end: - .word _end - -#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 - - -/* - * the actual reset code - */ - -reset: - /* - * set the cpu to SVC32 mode - */ - mrs r0,cpsr - bic r0,r0,#0x1f - orr r0,r0,#0x13 - msr cpsr,r0 - - /* - * we do sys-critical inits only at reboot, - * not when booting from ram! - */ -#ifndef CONFIG_SKIP_LOWLEVEL_INIT - bl cpu_init_crit -#endif - -#ifndef CONFIG_SKIP_RELOCATE_UBOOT -relocate: /* relocate U-Boot to RAM */ - adr r0, _start /* r0 <- current position of code */ - ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ - cmp r0, r1 /* don't reloc during debug */ - beq stack_setup - - ldr r2, _armboot_start - ldr r3, _bss_start - sub r2, r3, r2 /* r2 <- size of armboot */ - add r2, r0, r2 /* r2 <- source end address */ - -copy_loop: - ldmia r0!, {r3-r10} /* copy from source address [r0] */ - stmia r1!, {r3-r10} /* copy to target address [r1] */ - cmp r0, r2 /* until source end addreee [r2] */ - ble copy_loop -#endif /* CONFIG_SKIP_RELOCATE_UBOOT */ - - /* Set up the stack */ -stack_setup: - ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ - sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */ - sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ -#ifdef CONFIG_USE_IRQ - sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) -#endif - sub sp, r0, #12 /* leave 3 words for abort-stack */ - -clear_bss: - ldr r0, _bss_start /* find start of bss segment */ - ldr r1, _bss_end /* stop here */ - mov r2, #0x00000000 /* clear */ - -clbss_l:str r2, [r0] /* clear loop... */ - add r0, r0, #4 - cmp r0, r1 - ble clbss_l - - ldr pc, _start_armboot - -_start_armboot: .word start_armboot - - -/* - ************************************************************************* - * - * CPU_init_critical registers - * - * setup important registers - * setup memory timing - * - ************************************************************************* - */ - - -/* Interupt-Controller base address */ -IC_BASE: .word 0x90050000 -#define ICMR 0x04 - - -/* Reset-Controller */ -RST_BASE: .word 0x90030000 -#define RSRR 0x00 -#define RCSR 0x04 - - -/* PWR */ -PWR_BASE: .word 0x90020000 -#define PSPR 0x08 -#define PPCR 0x14 -cpuspeed: .word CONFIG_SYS_CPUSPEED - - -cpu_init_crit: - /* - * mask all IRQs - */ - ldr r0, IC_BASE - mov r1, #0x00 - str r1, [r0, #ICMR] - - /* set clock speed */ - ldr r0, PWR_BASE - ldr r1, cpuspeed - str r1, [r0, #PPCR] - - /* - * before relocating, we have to setup RAM timing - * because memory timing is board-dependend, you will - * find a lowlevel_init.S in your board directory. - */ - mov ip, lr - bl lowlevel_init - mov lr, ip - - /* - * disable MMU stuff and enable I-cache - */ - mrc p15,0,r0,c1,c0 - bic r0, r0, #0x00002000 @ clear bit 13 (X) - bic r0, r0, #0x0000000f @ clear bits 3-0 (WCAM) - orr r0, r0, #0x00001000 @ set bit 12 (I) Icache - orr r0, r0, #0x00000002 @ set bit 2 (A) Align - mcr p15,0,r0,c1,c0 - - /* - * flush v4 I/D caches - */ - mov r0, #0 - mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ - mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ - - mov pc, 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 -#define I_BIT 0x80 - -/* - * use bad_save_user_regs for abort/prefetch/undef/swi ... - * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling - */ - - .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, _armboot_start - sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) - sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack - 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 - - .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, _armboot_start @ setup our mode stack - sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) - sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort 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 - /* someone ought to write a more effiction fiq_save_user_regs */ - irq_save_user_regs - bl do_fiq - 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 - - .align 5 -.globl reset_cpu -reset_cpu: - ldr r0, RST_BASE - mov r1, #0x0 @ set bit 3-0 ... - str r1, [r0, #RCSR] @ ... to clear in RCSR - mov r1, #0x1 - str r1, [r0, #RSRR] @ and perform reset - b reset_cpu @ silly, but repeat endlessly diff --git a/cpu/sa1100/timer.c b/cpu/sa1100/timer.c deleted file mode 100644 index 020750125a..0000000000 --- a/cpu/sa1100/timer.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include - -int timer_init (void) -{ - return 0; -} - -void reset_timer (void) -{ - reset_timer_masked (); -} - -ulong get_timer (ulong base) -{ - return get_timer_masked (); -} - -void set_timer (ulong t) -{ - /* nop */ -} - -void __udelay (unsigned long usec) -{ - udelay_masked (usec); -} - - -void reset_timer_masked (void) -{ - OSCR = 0; -} - -ulong get_timer_masked (void) -{ - return OSCR; -} - -void udelay_masked (unsigned long usec) -{ - ulong tmo; - ulong endtime; - signed long diff; - - if (usec >= 1000) { - tmo = usec / 1000; - tmo *= CONFIG_SYS_HZ; - tmo /= 1000; - } else { - tmo = usec * CONFIG_SYS_HZ; - tmo /= (1000*1000); - } - - endtime = get_timer_masked () + tmo; - - do { - ulong now = get_timer_masked (); - diff = endtime - now; - } while (diff >= 0); -} - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return get_timer(0); -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk (void) -{ - ulong tbclk; - - tbclk = CONFIG_SYS_HZ; - return tbclk; -} diff --git a/cpu/sa1100/u-boot.lds b/cpu/sa1100/u-boot.lds deleted file mode 100644 index 0c02e76e7a..0000000000 --- a/cpu/sa1100/u-boot.lds +++ /dev/null @@ -1,59 +0,0 @@ -/* - * (C) Copyright 2003-2004 - * MontaVista Software, Inc. - * - * (C) Copyright 2000-2004 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -ENTRY(_start) -SECTIONS -{ - . = 0x00000000; - - . = ALIGN(4); - .text : - { - cpu/sa1100/start.o (.text) - *(.text) - } - - . = ALIGN(4); - .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } - - . = ALIGN(4); - .data : { *(.data) } - - . = ALIGN(4); - .got : { *(.got) } - - . = .; - __u_boot_cmd_start = .; - .u_boot_cmd : { *(.u_boot_cmd) } - __u_boot_cmd_end = .; - - . = ALIGN(4); - __bss_start = .; - .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } - _end = .; -} diff --git a/doc/README-integrator b/doc/README-integrator index 4daf3413aa..5a0e934924 100644 --- a/doc/README-integrator +++ b/doc/README-integrator @@ -52,7 +52,7 @@ cpu/arm<>/start.S so that it may be used by other boards. However, to avoid duplicating code through all processor files, a generic core for ARM Integrator CMs has been added - cpu/arm_intcm + arch/arm/cpu/arm_intcm Otherwise. for example, the standard CM reset via the CM control register would need placing in each CM processor file...... diff --git a/doc/README.ARM-SoC b/doc/README.ARM-SoC index 15f065dfbc..d6bd624886 100644 --- a/doc/README.ARM-SoC +++ b/doc/README.ARM-SoC @@ -1,7 +1,7 @@ [By Steven Scholz , 16 Aug 2004] Since the cpu/ directory gets clobbered with peripheral driver code I -started cleaning up cpu/arm920t. +started cleaning up arch/arm/cpu/arm920t. I introduced the concept of Soc (system on a chip) into the ./cpu directory. That means that code that is cpu (i.e. core) specific @@ -17,8 +17,8 @@ peripherals around the core) is moved into Thus a library/archive "$(CPUDIR)/$(SOC)/lib$(SOC).a" will be build and linked. Examples will be - cpu/arm920t/imx/ - cpu/arm920t/s3c24x0 + arch/arm/cpu/arm920t/imx/ + arch/arm/cpu/arm920t/s3c24x0 One can select an SoC by passing the name of it to ./mkconfig just like diff --git a/doc/README.modnet50 b/doc/README.modnet50 index f7bb254e16..2ac3c8fbe3 100644 --- a/doc/README.modnet50 +++ b/doc/README.modnet50 @@ -45,7 +45,7 @@ flash. Files: -cpu/arm720t/serial_netarm.c .. serial I/O for the cpu +arch/arm/cpu/arm720t/serial_netarm.c .. serial I/O for the cpu board/modnet50/lowlevel_init.S .. memory setup for ModNET50 board/modnet50/flash.c .. flash routines diff --git a/nand_spl/board/freescale/mx31pdk/Makefile b/nand_spl/board/freescale/mx31pdk/Makefile index 0e13d5de26..c1dcf05f3b 100644 --- a/nand_spl/board/freescale/mx31pdk/Makefile +++ b/nand_spl/board/freescale/mx31pdk/Makefile @@ -12,7 +12,7 @@ SOBJS = start.o lowlevel_init.o COBJS = nand_boot_fsl_nfc.o SRCS := $(SRCTREE)/nand_spl/nand_boot_fsl_nfc.c -SRCS += $(SRCTREE)/cpu/arm1136/start.S +SRCS += $(SRCTREE)/arch/arm/cpu/arm1136/start.S SRCS += $(SRCTREE)/board/freescale/mx31pdk/lowlevel_init.S OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) __OBJS := $(SOBJS) $(COBJS) @@ -40,7 +40,7 @@ $(nandobj)u-boot.lds: $(LDSCRIPT) ######################################################################### -$(obj)%.o: $(SRCTREE)/cpu/arm1136/%.S +$(obj)%.o: $(SRCTREE)/arch/arm/cpu/arm1136/%.S $(CC) $(AFLAGS) -c -o $@ $< $(obj)%.o: $(SRCTREE)/board/freescale/mx31pdk/%.S diff --git a/nand_spl/board/karo/tx25/Makefile b/nand_spl/board/karo/tx25/Makefile index ae71f6695f..62aa58351c 100644 --- a/nand_spl/board/karo/tx25/Makefile +++ b/nand_spl/board/karo/tx25/Makefile @@ -33,7 +33,7 @@ SOBJS = start.o lowlevel_init.o COBJS = nand_boot_fsl_nfc.o SRCS := $(SRCTREE)/nand_spl/nand_boot_fsl_nfc.c -SRCS += $(SRCTREE)/cpu/arm926ejs/start.S +SRCS += $(SRCTREE)/arch/arm/cpu/arm926ejs/start.S SRCS += $(SRCTREE)/board/karo/tx25/lowlevel_init.S OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) __OBJS := $(SOBJS) $(COBJS) @@ -61,7 +61,7 @@ $(nandobj)u-boot.lds: $(LDSCRIPT) ######################################################################### -$(obj)%.o: $(SRCTREE)/cpu/arm926ejs/%.S +$(obj)%.o: $(SRCTREE)/arch/arm/cpu/arm926ejs/%.S $(CC) $(AFLAGS) -c -o $@ $< $(obj)%.o: $(SRCTREE)/board/karo/tx25/%.S diff --git a/nand_spl/board/samsung/smdk6400/Makefile b/nand_spl/board/samsung/smdk6400/Makefile index 0fdda25ac5..9cb4853318 100644 --- a/nand_spl/board/samsung/smdk6400/Makefile +++ b/nand_spl/board/samsung/smdk6400/Makefile @@ -67,12 +67,12 @@ $(nandobj)u-boot.lds: $(LDSCRIPT) # from cpu directory $(obj)start.S: @rm -f $@ - @ln -s $(TOPDIR)/cpu/arm1176/start.S $@ + @ln -s $(TOPDIR)/arch/arm/cpu/arm1176/start.S $@ # from SoC directory $(obj)cpu_init.S: @rm -f $@ - @ln -s $(TOPDIR)/cpu/arm1176/s3c64xx/cpu_init.S $@ + @ln -s $(TOPDIR)/arch/arm/cpu/arm1176/s3c64xx/cpu_init.S $@ # from board directory $(obj)lowlevel_init.S: