Merge branch 'master' of git://git.denx.de/u-boot-arm

This commit is contained in:
Tom Rini 2014-02-20 12:18:59 -05:00
commit 6853e6aa77
259 changed files with 2117 additions and 70793 deletions

View File

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

View File

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

1
README
View File

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

View File

@ -409,20 +409,15 @@ u32 imx_get_uartclk(void)
u32 imx_get_fecclk(void)
{
return decode_pll(PLL_ENET, MXC_HCLK);
return mxc_get_clock(MXC_IPG_CLK);
}
int enable_sata_clock(void)
static int enable_enet_pll(uint32_t en)
{
u32 reg = 0;
s32 timeout = 100000;
struct mxc_ccm_reg *const imx_ccm
= (struct mxc_ccm_reg *) CCM_BASE_ADDR;
/* Enable sata clock */
reg = readl(&imx_ccm->CCGR5); /* CCGR5 */
reg |= MXC_CCM_CCGR5_SATA_MASK;
writel(reg, &imx_ccm->CCGR5);
s32 timeout = 100000;
u32 reg = 0;
/* Enable PLLs */
reg = readl(&imx_ccm->analog_pll_enet);
@ -437,10 +432,70 @@ int enable_sata_clock(void)
return -EIO;
reg &= ~BM_ANADIG_PLL_SYS_BYPASS;
writel(reg, &imx_ccm->analog_pll_enet);
reg |= BM_ANADIG_PLL_ENET_ENABLE_SATA;
reg |= en;
writel(reg, &imx_ccm->analog_pll_enet);
return 0;
}
return 0 ;
static void ungate_sata_clock(void)
{
struct mxc_ccm_reg *const imx_ccm =
(struct mxc_ccm_reg *)CCM_BASE_ADDR;
/* Enable SATA clock. */
setbits_le32(&imx_ccm->CCGR5, MXC_CCM_CCGR5_SATA_MASK);
}
static void ungate_pcie_clock(void)
{
struct mxc_ccm_reg *const imx_ccm =
(struct mxc_ccm_reg *)CCM_BASE_ADDR;
/* Enable PCIe clock. */
setbits_le32(&imx_ccm->CCGR4, MXC_CCM_CCGR4_PCIE_MASK);
}
int enable_sata_clock(void)
{
ungate_sata_clock();
return enable_enet_pll(BM_ANADIG_PLL_ENET_ENABLE_SATA);
}
int enable_pcie_clock(void)
{
struct anatop_regs *anatop_regs =
(struct anatop_regs *)ANATOP_BASE_ADDR;
struct mxc_ccm_reg *ccm_regs = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
/*
* Here be dragons!
*
* The register ANATOP_MISC1 is not documented in the Freescale
* MX6RM. The register that is mapped in the ANATOP space and
* marked as ANATOP_MISC1 is actually documented in the PMU section
* of the datasheet as PMU_MISC1.
*
* Switch LVDS clock source to SATA (0xb), disable clock INPUT and
* enable clock OUTPUT. This is important for PCI express link that
* is clocked from the i.MX6.
*/
#define ANADIG_ANA_MISC1_LVDSCLK1_IBEN (1 << 12)
#define ANADIG_ANA_MISC1_LVDSCLK1_OBEN (1 << 10)
#define ANADIG_ANA_MISC1_LVDS1_CLK_SEL_MASK 0x0000001F
clrsetbits_le32(&anatop_regs->ana_misc1,
ANADIG_ANA_MISC1_LVDSCLK1_IBEN |
ANADIG_ANA_MISC1_LVDS1_CLK_SEL_MASK,
ANADIG_ANA_MISC1_LVDSCLK1_OBEN | 0xb);
/* PCIe reference clock sourced from AXI. */
clrbits_le32(&ccm_regs->cbcmr, MXC_CCM_CBCMR_PCIE_AXI_CLK_SEL);
/* Party time! Ungate the clock to the PCIe. */
ungate_sata_clock();
ungate_pcie_clock();
return enable_enet_pll(BM_ANADIG_PLL_ENET_ENABLE_SATA |
BM_ANADIG_PLL_ENET_ENABLE_PCIE);
}
unsigned int mxc_get_clock(enum mxc_clock clk)

View File

@ -8,6 +8,8 @@
*/
#include <common.h>
#include <asm/armv7.h>
#include <asm/pl310.h>
#include <asm/errno.h>
#include <asm/io.h>
#include <asm/arch/imx-regs.h>
@ -41,14 +43,19 @@ u32 get_cpu_rev(void)
if (type != MXC_CPU_MX6SL) {
reg = readl(&anatop->digprog);
struct scu_regs *scu = (struct scu_regs *)SCU_BASE_ADDR;
u32 cfg = readl(&scu->config) & 3;
type = ((reg >> 16) & 0xff);
if (type == MXC_CPU_MX6DL) {
struct scu_regs *scu = (struct scu_regs *)SCU_BASE_ADDR;
u32 cfg = readl(&scu->config) & 3;
if (!cfg)
type = MXC_CPU_MX6SOLO;
}
if (type == MXC_CPU_MX6Q) {
if (cfg == 1)
type = MXC_CPU_MX6D;
}
}
reg &= 0xff; /* mx6 silicon revision */
return (type << 12) | (reg + 0x10);
@ -62,6 +69,9 @@ u32 __weak get_board_rev(void)
if (type == MXC_CPU_MX6SOLO)
cpurev = (MXC_CPU_MX6DL) << 12 | (cpurev & 0xFFF);
if (type == MXC_CPU_MX6D)
cpurev = (MXC_CPU_MX6Q) << 12 | (cpurev & 0xFFF);
return cpurev;
}
#endif
@ -177,10 +187,41 @@ static void imx_set_wdog_powerdown(bool enable)
writew(enable, &wdog2->wmcr);
}
static void set_ahb_rate(u32 val)
{
struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
u32 reg, div;
div = get_periph_clk() / val - 1;
reg = readl(&mxc_ccm->cbcdr);
writel((reg & (~MXC_CCM_CBCDR_AHB_PODF_MASK)) |
(div << MXC_CCM_CBCDR_AHB_PODF_OFFSET), &mxc_ccm->cbcdr);
}
static void clear_mmdc_ch_mask(void)
{
struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
/* Clear MMDC channel mask */
writel(0, &mxc_ccm->ccdr);
}
int arch_cpu_init(void)
{
init_aips();
/* Need to clear MMDC_CHx_MASK to make warm reset work. */
clear_mmdc_ch_mask();
/*
* When low freq boot is enabled, ROM will not set AHB
* freq, so we need to ensure AHB freq is 132MHz in such
* scenario.
*/
if (mxc_get_clock(MXC_ARM_CLK) == 396000000)
set_ahb_rate(132000000);
imx_set_wdog_powerdown(false); /* Disable PDE bit of WMCR register */
#ifdef CONFIG_APBH_DMA
@ -336,3 +377,59 @@ void imx_setup_hdmi(void)
writel(reg, &mxc_ccm->chsccdr);
}
#endif
#ifndef CONFIG_SYS_L2CACHE_OFF
#define IOMUXC_GPR11_L2CACHE_AS_OCRAM 0x00000002
void v7_outer_cache_enable(void)
{
struct pl310_regs *const pl310 = (struct pl310_regs *)L2_PL310_BASE;
unsigned int val;
#if defined CONFIG_MX6SL
struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
val = readl(&iomux->gpr[11]);
if (val & IOMUXC_GPR11_L2CACHE_AS_OCRAM) {
/* L2 cache configured as OCRAM, reset it */
val &= ~IOMUXC_GPR11_L2CACHE_AS_OCRAM;
writel(val, &iomux->gpr[11]);
}
#endif
writel(0x132, &pl310->pl310_tag_latency_ctrl);
writel(0x132, &pl310->pl310_data_latency_ctrl);
val = readl(&pl310->pl310_prefetch_ctrl);
/* Turn on the L2 I/D prefetch */
val |= 0x30000000;
/*
* The L2 cache controller(PL310) version on the i.MX6D/Q is r3p1-50rel0
* The L2 cache controller(PL310) version on the i.MX6DL/SOLO/SL is r3p2
* But according to ARM PL310 errata: 752271
* ID: 752271: Double linefill feature can cause data corruption
* Fault Status: Present in: r3p0, r3p1, r3p1-50rel0. Fixed in r3p2
* Workaround: The only workaround to this erratum is to disable the
* double linefill feature. This is the default behavior.
*/
#ifndef CONFIG_MX6Q
val |= 0x40800000;
#endif
writel(val, &pl310->pl310_prefetch_ctrl);
val = readl(&pl310->pl310_power_ctrl);
val |= L2X0_DYNAMIC_CLK_GATING_EN;
val |= L2X0_STNDBY_MODE_EN;
writel(val, &pl310->pl310_power_ctrl);
setbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
}
void v7_outer_cache_disable(void)
{
struct pl310_regs *const pl310 = (struct pl310_regs *)L2_PL310_BASE;
clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
}
#endif /* !CONFIG_SYS_L2CACHE_OFF */

View File

@ -38,12 +38,19 @@ _irq: .word _irq
_fiq: .word _fiq
_pad: .word 0x12345678 /* now 16*4=64 */
#else
.globl _undefined_instruction
_undefined_instruction: .word undefined_instruction
.globl _software_interrupt
_software_interrupt: .word software_interrupt
.globl _prefetch_abort
_prefetch_abort: .word prefetch_abort
.globl _data_abort
_data_abort: .word data_abort
.globl _not_used
_not_used: .word not_used
.globl _irq
_irq: .word irq
.globl _fiq
_fiq: .word fiq
_pad: .word 0x12345678 /* now 16*4=64 */
#endif /* CONFIG_SPL_BUILD */

View File

@ -12,3 +12,5 @@ obj-y := timer.o
obj-y += cpu.o
obj-y += ddrc.o
obj-y += slcr.o
obj-y += clk.o
obj-$(CONFIG_SPL_BUILD) += spl.o

View File

@ -0,0 +1,664 @@
/*
* Copyright (C) 2013 Soren Brinkmann <soren.brinkmann@xilinx.com>
* Copyright (C) 2013 Xilinx, Inc. All rights reserved.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <errno.h>
#include <clk.h>
#include <asm/io.h>
#include <asm/arch/hardware.h>
#include <asm/arch/clk.h>
/* Board oscillator frequency */
#ifndef CONFIG_ZYNQ_PS_CLK_FREQ
# define CONFIG_ZYNQ_PS_CLK_FREQ 33333333UL
#endif
/* Register bitfield defines */
#define PLLCTRL_FBDIV_MASK 0x7f000
#define PLLCTRL_FBDIV_SHIFT 12
#define PLLCTRL_BPFORCE_MASK (1 << 4)
#define PLLCTRL_PWRDWN_MASK 2
#define PLLCTRL_PWRDWN_SHIFT 1
#define PLLCTRL_RESET_MASK 1
#define PLLCTRL_RESET_SHIFT 0
#define ZYNQ_CLK_MAXDIV 0x3f
#define CLK_CTRL_DIV1_SHIFT 20
#define CLK_CTRL_DIV1_MASK (ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV1_SHIFT)
#define CLK_CTRL_DIV0_SHIFT 8
#define CLK_CTRL_DIV0_MASK (ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV0_SHIFT)
#define CLK_CTRL_SRCSEL_SHIFT 4
#define CLK_CTRL_SRCSEL_MASK (0x3 << CLK_CTRL_SRCSEL_SHIFT)
#define CLK_CTRL_DIV2X_SHIFT 26
#define CLK_CTRL_DIV2X_MASK (ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV2X_SHIFT)
#define CLK_CTRL_DIV3X_SHIFT 20
#define CLK_CTRL_DIV3X_MASK (ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV3X_SHIFT)
#define ZYNQ_CLKMUX_SEL_0 0
#define ZYNQ_CLKMUX_SEL_1 1
#define ZYNQ_CLKMUX_SEL_2 2
#define ZYNQ_CLKMUX_SEL_3 3
DECLARE_GLOBAL_DATA_PTR;
struct clk;
/**
* struct clk_ops:
* @set_rate: Function pointer to set_rate() implementation
* @get_rate: Function pointer to get_rate() implementation
*/
struct clk_ops {
int (*set_rate)(struct clk *clk, unsigned long rate);
unsigned long (*get_rate)(struct clk *clk);
};
/**
* struct clk:
* @name: Clock name
* @frequency: Currenct frequency
* @parent: Parent clock
* @flags: Clock flags
* @reg: Clock control register
* @ops: Clock operations
*/
struct clk {
char *name;
unsigned long frequency;
enum zynq_clk parent;
unsigned int flags;
u32 *reg;
struct clk_ops ops;
};
#define ZYNQ_CLK_FLAGS_HAS_2_DIVS 1
static struct clk clks[clk_max];
/**
* __zynq_clk_cpu_get_parent() - Decode clock multiplexer
* @srcsel: Mux select value
* Returns the clock identifier associated with the selected mux input.
*/
static int __zynq_clk_cpu_get_parent(unsigned int srcsel)
{
unsigned int ret;
switch (srcsel) {
case ZYNQ_CLKMUX_SEL_0:
case ZYNQ_CLKMUX_SEL_1:
ret = armpll_clk;
break;
case ZYNQ_CLKMUX_SEL_2:
ret = ddrpll_clk;
break;
case ZYNQ_CLKMUX_SEL_3:
ret = iopll_clk;
break;
default:
ret = armpll_clk;
break;
}
return ret;
}
/**
* ddr2x_get_rate() - Get clock rate of DDR2x clock
* @clk: Clock handle
* Returns the current clock rate of @clk.
*/
static unsigned long ddr2x_get_rate(struct clk *clk)
{
u32 clk_ctrl = readl(clk->reg);
u32 div = (clk_ctrl & CLK_CTRL_DIV2X_MASK) >> CLK_CTRL_DIV2X_SHIFT;
return DIV_ROUND_CLOSEST(zynq_clk_get_rate(clk->parent), div);
}
/**
* ddr3x_get_rate() - Get clock rate of DDR3x clock
* @clk: Clock handle
* Returns the current clock rate of @clk.
*/
static unsigned long ddr3x_get_rate(struct clk *clk)
{
u32 clk_ctrl = readl(clk->reg);
u32 div = (clk_ctrl & CLK_CTRL_DIV3X_MASK) >> CLK_CTRL_DIV3X_SHIFT;
return DIV_ROUND_CLOSEST(zynq_clk_get_rate(clk->parent), div);
}
static void init_ddr_clocks(void)
{
u32 div0, div1;
unsigned long prate = zynq_clk_get_rate(ddrpll_clk);
u32 clk_ctrl = readl(&slcr_base->ddr_clk_ctrl);
/* DDR2x */
clks[ddr2x_clk].reg = &slcr_base->ddr_clk_ctrl;
clks[ddr2x_clk].parent = ddrpll_clk;
clks[ddr2x_clk].name = "ddr_2x";
clks[ddr2x_clk].frequency = ddr2x_get_rate(&clks[ddr2x_clk]);
clks[ddr2x_clk].ops.get_rate = ddr2x_get_rate;
/* DDR3x */
clks[ddr3x_clk].reg = &slcr_base->ddr_clk_ctrl;
clks[ddr3x_clk].parent = ddrpll_clk;
clks[ddr3x_clk].name = "ddr_3x";
clks[ddr3x_clk].frequency = ddr3x_get_rate(&clks[ddr3x_clk]);
clks[ddr3x_clk].ops.get_rate = ddr3x_get_rate;
/* DCI */
clk_ctrl = readl(&slcr_base->dci_clk_ctrl);
div0 = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
div1 = (clk_ctrl & CLK_CTRL_DIV1_MASK) >> CLK_CTRL_DIV1_SHIFT;
clks[dci_clk].reg = &slcr_base->dci_clk_ctrl;
clks[dci_clk].parent = ddrpll_clk;
clks[dci_clk].frequency = DIV_ROUND_CLOSEST(
DIV_ROUND_CLOSEST(prate, div0), div1);
clks[dci_clk].name = "dci";
gd->bd->bi_ddr_freq = clks[ddr3x_clk].frequency / 1000000;
}
static void init_cpu_clocks(void)
{
int clk_621;
u32 reg, div, srcsel;
enum zynq_clk parent;
reg = readl(&slcr_base->arm_clk_ctrl);
clk_621 = readl(&slcr_base->clk_621_true) & 1;
div = (reg & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
srcsel = (reg & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
parent = __zynq_clk_cpu_get_parent(srcsel);
/* cpu clocks */
clks[cpu_6or4x_clk].reg = &slcr_base->arm_clk_ctrl;
clks[cpu_6or4x_clk].parent = parent;
clks[cpu_6or4x_clk].frequency = DIV_ROUND_CLOSEST(
zynq_clk_get_rate(parent), div);
clks[cpu_6or4x_clk].name = "cpu_6or4x";
clks[cpu_3or2x_clk].reg = &slcr_base->arm_clk_ctrl;
clks[cpu_3or2x_clk].parent = cpu_6or4x_clk;
clks[cpu_3or2x_clk].frequency = zynq_clk_get_rate(cpu_6or4x_clk) / 2;
clks[cpu_3or2x_clk].name = "cpu_3or2x";
clks[cpu_2x_clk].reg = &slcr_base->arm_clk_ctrl;
clks[cpu_2x_clk].parent = cpu_6or4x_clk;
clks[cpu_2x_clk].frequency = zynq_clk_get_rate(cpu_6or4x_clk) /
(2 + clk_621);
clks[cpu_2x_clk].name = "cpu_2x";
clks[cpu_1x_clk].reg = &slcr_base->arm_clk_ctrl;
clks[cpu_1x_clk].parent = cpu_6or4x_clk;
clks[cpu_1x_clk].frequency = zynq_clk_get_rate(cpu_6or4x_clk) /
(4 + 2 * clk_621);
clks[cpu_1x_clk].name = "cpu_1x";
}
/**
* periph_calc_two_divs() - Calculate clock dividers
* @cur_rate: Current clock rate
* @tgt_rate: Target clock rate
* @prate: Parent clock rate
* @div0: First divider (output)
* @div1: Second divider (output)
* Returns the actual clock rate possible.
*
* Calculates clock dividers for clocks with two 6-bit dividers.
*/
static unsigned long periph_calc_two_divs(unsigned long cur_rate,
unsigned long tgt_rate, unsigned long prate, u32 *div0,
u32 *div1)
{
long err, best_err = (long)(~0UL >> 1);
unsigned long rate, best_rate = 0;
u32 d0, d1;
for (d0 = 1; d0 <= ZYNQ_CLK_MAXDIV; d0++) {
for (d1 = 1; d1 <= ZYNQ_CLK_MAXDIV >> 1; d1++) {
rate = DIV_ROUND_CLOSEST(DIV_ROUND_CLOSEST(prate, d0),
d1);
err = abs(rate - tgt_rate);
if (err < best_err) {
*div0 = d0;
*div1 = d1;
best_err = err;
best_rate = rate;
}
}
}
return best_rate;
}
/**
* zynq_clk_periph_set_rate() - Set clock rate
* @clk: Handle of the peripheral clock
* @rate: New clock rate
* Sets the clock frequency of @clk to @rate. Returns zero on success.
*/
static int zynq_clk_periph_set_rate(struct clk *clk,
unsigned long rate)
{
u32 ctrl, div0 = 0, div1 = 0;
unsigned long prate, new_rate, cur_rate = clk->frequency;
ctrl = readl(clk->reg);
prate = zynq_clk_get_rate(clk->parent);
ctrl &= ~CLK_CTRL_DIV0_MASK;
if (clk->flags & ZYNQ_CLK_FLAGS_HAS_2_DIVS) {
ctrl &= ~CLK_CTRL_DIV1_MASK;
new_rate = periph_calc_two_divs(cur_rate, rate, prate, &div0,
&div1);
ctrl |= div1 << CLK_CTRL_DIV1_SHIFT;
} else {
div0 = DIV_ROUND_CLOSEST(prate, rate);
div0 &= ZYNQ_CLK_MAXDIV;
new_rate = DIV_ROUND_CLOSEST(rate, div0);
}
/* write new divs to hardware */
ctrl |= div0 << CLK_CTRL_DIV0_SHIFT;
writel(ctrl, clk->reg);
/* update frequency in clk framework */
clk->frequency = new_rate;
return 0;
}
/**
* zynq_clk_periph_get_rate() - Get clock rate
* @clk: Handle of the peripheral clock
* Returns the current clock rate of @clk.
*/
static unsigned long zynq_clk_periph_get_rate(struct clk *clk)
{
u32 clk_ctrl = readl(clk->reg);
u32 div0 = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
u32 div1 = 1;
if (clk->flags & ZYNQ_CLK_FLAGS_HAS_2_DIVS)
div1 = (clk_ctrl & CLK_CTRL_DIV1_MASK) >> CLK_CTRL_DIV1_SHIFT;
/* a register value of zero == division by 1 */
if (!div0)
div0 = 1;
if (!div1)
div1 = 1;
return
DIV_ROUND_CLOSEST(
DIV_ROUND_CLOSEST(zynq_clk_get_rate(clk->parent), div0),
div1);
}
/**
* __zynq_clk_periph_get_parent() - Decode clock multiplexer
* @srcsel: Mux select value
* Returns the clock identifier associated with the selected mux input.
*/
static enum zynq_clk __zynq_clk_periph_get_parent(u32 srcsel)
{
switch (srcsel) {
case ZYNQ_CLKMUX_SEL_0:
case ZYNQ_CLKMUX_SEL_1:
return iopll_clk;
case ZYNQ_CLKMUX_SEL_2:
return armpll_clk;
case ZYNQ_CLKMUX_SEL_3:
return ddrpll_clk;
default:
return 0;
}
}
/**
* zynq_clk_periph_get_parent() - Decode clock multiplexer
* @clk: Clock handle
* Returns the clock identifier associated with the selected mux input.
*/
static enum zynq_clk zynq_clk_periph_get_parent(struct clk *clk)
{
u32 clk_ctrl = readl(clk->reg);
u32 srcsel = (clk_ctrl & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
return __zynq_clk_periph_get_parent(srcsel);
}
/**
* zynq_clk_register_periph_clk() - Set up a peripheral clock with the framework
* @clk: Pointer to struct clk for the clock
* @ctrl: Clock control register
* @name: PLL name
* @two_divs: Indicates whether the clock features one or two dividers
*/
static int zynq_clk_register_periph_clk(struct clk *clk, u32 *ctrl, char *name,
bool two_divs)
{
clk->name = name;
clk->reg = ctrl;
if (two_divs)
clk->flags = ZYNQ_CLK_FLAGS_HAS_2_DIVS;
clk->parent = zynq_clk_periph_get_parent(clk);
clk->frequency = zynq_clk_periph_get_rate(clk);
clk->ops.get_rate = zynq_clk_periph_get_rate;
clk->ops.set_rate = zynq_clk_periph_set_rate;
return 0;
}
static void init_periph_clocks(void)
{
zynq_clk_register_periph_clk(&clks[gem0_clk], &slcr_base->gem0_clk_ctrl,
"gem0", 1);
zynq_clk_register_periph_clk(&clks[gem1_clk], &slcr_base->gem1_clk_ctrl,
"gem1", 1);
zynq_clk_register_periph_clk(&clks[smc_clk], &slcr_base->smc_clk_ctrl,
"smc", 0);
zynq_clk_register_periph_clk(&clks[lqspi_clk],
&slcr_base->lqspi_clk_ctrl, "lqspi", 0);
zynq_clk_register_periph_clk(&clks[sdio0_clk],
&slcr_base->sdio_clk_ctrl, "sdio0", 0);
zynq_clk_register_periph_clk(&clks[sdio1_clk],
&slcr_base->sdio_clk_ctrl, "sdio1", 0);
zynq_clk_register_periph_clk(&clks[spi0_clk], &slcr_base->spi_clk_ctrl,
"spi0", 0);
zynq_clk_register_periph_clk(&clks[spi1_clk], &slcr_base->spi_clk_ctrl,
"spi1", 0);
zynq_clk_register_periph_clk(&clks[uart0_clk],
&slcr_base->uart_clk_ctrl, "uart0", 0);
zynq_clk_register_periph_clk(&clks[uart1_clk],
&slcr_base->uart_clk_ctrl, "uart1", 0);
zynq_clk_register_periph_clk(&clks[dbg_trc_clk],
&slcr_base->dbg_clk_ctrl, "dbg_trc", 0);
zynq_clk_register_periph_clk(&clks[dbg_apb_clk],
&slcr_base->dbg_clk_ctrl, "dbg_apb", 0);
zynq_clk_register_periph_clk(&clks[pcap_clk],
&slcr_base->pcap_clk_ctrl, "pcap", 0);
zynq_clk_register_periph_clk(&clks[fclk0_clk],
&slcr_base->fpga0_clk_ctrl, "fclk0", 1);
zynq_clk_register_periph_clk(&clks[fclk1_clk],
&slcr_base->fpga1_clk_ctrl, "fclk1", 1);
zynq_clk_register_periph_clk(&clks[fclk2_clk],
&slcr_base->fpga2_clk_ctrl, "fclk2", 1);
zynq_clk_register_periph_clk(&clks[fclk3_clk],
&slcr_base->fpga3_clk_ctrl, "fclk3", 1);
}
/**
* zynq_clk_register_aper_clk() - Set up a APER clock with the framework
* @clk: Pointer to struct clk for the clock
* @ctrl: Clock control register
* @name: PLL name
*/
static void zynq_clk_register_aper_clk(struct clk *clk, u32 *ctrl, char *name)
{
clk->name = name;
clk->reg = ctrl;
clk->parent = cpu_1x_clk;
clk->frequency = zynq_clk_get_rate(clk->parent);
}
static void init_aper_clocks(void)
{
zynq_clk_register_aper_clk(&clks[usb0_aper_clk],
&slcr_base->aper_clk_ctrl, "usb0_aper");
zynq_clk_register_aper_clk(&clks[usb1_aper_clk],
&slcr_base->aper_clk_ctrl, "usb1_aper");
zynq_clk_register_aper_clk(&clks[gem0_aper_clk],
&slcr_base->aper_clk_ctrl, "gem0_aper");
zynq_clk_register_aper_clk(&clks[gem1_aper_clk],
&slcr_base->aper_clk_ctrl, "gem1_aper");
zynq_clk_register_aper_clk(&clks[sdio0_aper_clk],
&slcr_base->aper_clk_ctrl, "sdio0_aper");
zynq_clk_register_aper_clk(&clks[sdio1_aper_clk],
&slcr_base->aper_clk_ctrl, "sdio1_aper");
zynq_clk_register_aper_clk(&clks[spi0_aper_clk],
&slcr_base->aper_clk_ctrl, "spi0_aper");
zynq_clk_register_aper_clk(&clks[spi1_aper_clk],
&slcr_base->aper_clk_ctrl, "spi1_aper");
zynq_clk_register_aper_clk(&clks[can0_aper_clk],
&slcr_base->aper_clk_ctrl, "can0_aper");
zynq_clk_register_aper_clk(&clks[can1_aper_clk],
&slcr_base->aper_clk_ctrl, "can1_aper");
zynq_clk_register_aper_clk(&clks[i2c0_aper_clk],
&slcr_base->aper_clk_ctrl, "i2c0_aper");
zynq_clk_register_aper_clk(&clks[i2c1_aper_clk],
&slcr_base->aper_clk_ctrl, "i2c1_aper");
zynq_clk_register_aper_clk(&clks[uart0_aper_clk],
&slcr_base->aper_clk_ctrl, "uart0_aper");
zynq_clk_register_aper_clk(&clks[uart1_aper_clk],
&slcr_base->aper_clk_ctrl, "uart1_aper");
zynq_clk_register_aper_clk(&clks[gpio_aper_clk],
&slcr_base->aper_clk_ctrl, "gpio_aper");
zynq_clk_register_aper_clk(&clks[lqspi_aper_clk],
&slcr_base->aper_clk_ctrl, "lqspi_aper");
zynq_clk_register_aper_clk(&clks[smc_aper_clk],
&slcr_base->aper_clk_ctrl, "smc_aper");
}
/**
* __zynq_clk_pll_get_rate() - Get PLL rate
* @addr: Address of the PLL's control register
* Returns the current PLL output rate.
*/
static unsigned long __zynq_clk_pll_get_rate(u32 *addr)
{
u32 reg, mul, bypass;
reg = readl(addr);
bypass = reg & PLLCTRL_BPFORCE_MASK;
if (bypass)
mul = 1;
else
mul = (reg & PLLCTRL_FBDIV_MASK) >> PLLCTRL_FBDIV_SHIFT;
return CONFIG_ZYNQ_PS_CLK_FREQ * mul;
}
/**
* zynq_clk_pll_get_rate() - Get PLL rate
* @pll: Handle of the PLL
* Returns the current clock rate of @pll.
*/
static unsigned long zynq_clk_pll_get_rate(struct clk *pll)
{
return __zynq_clk_pll_get_rate(pll->reg);
}
/**
* zynq_clk_register_pll() - Set up a PLL with the framework
* @clk: Pointer to struct clk for the PLL
* @ctrl: PLL control register
* @name: PLL name
* @prate: PLL input clock rate
*/
static void zynq_clk_register_pll(struct clk *clk, u32 *ctrl, char *name,
unsigned long prate)
{
clk->name = name;
clk->reg = ctrl;
clk->frequency = zynq_clk_pll_get_rate(clk);
clk->ops.get_rate = zynq_clk_pll_get_rate;
}
/**
* clkid_2_register() - Get clock control register
* @id: Clock identifier of one of the PLLs
* Returns the address of the requested PLL's control register.
*/
static u32 *clkid_2_register(enum zynq_clk id)
{
switch (id) {
case armpll_clk:
return &slcr_base->arm_pll_ctrl;
case ddrpll_clk:
return &slcr_base->ddr_pll_ctrl;
case iopll_clk:
return &slcr_base->io_pll_ctrl;
default:
return &slcr_base->io_pll_ctrl;
}
}
/* API */
/**
* zynq_clk_early_init() - Early init for the clock framework
*
* This function is called from before relocation and sets up the CPU clock
* frequency in the global data struct.
*/
void zynq_clk_early_init(void)
{
u32 reg = readl(&slcr_base->arm_clk_ctrl);
u32 div = (reg & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
u32 srcsel = (reg & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
enum zynq_clk parent = __zynq_clk_cpu_get_parent(srcsel);
u32 *pllreg = clkid_2_register(parent);
unsigned long prate = __zynq_clk_pll_get_rate(pllreg);
if (!div)
div = 1;
gd->cpu_clk = DIV_ROUND_CLOSEST(prate, div);
}
/**
* get_uart_clk() - Get UART input frequency
* @dev_index: UART ID
* Returns UART input clock frequency in Hz.
*
* Compared to zynq_clk_get_rate() this function is designed to work before
* relocation and can be called when the serial UART is set up.
*/
unsigned long get_uart_clk(int dev_index)
{
u32 reg = readl(&slcr_base->uart_clk_ctrl);
u32 div = (reg & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
u32 srcsel = (reg & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
enum zynq_clk parent = __zynq_clk_periph_get_parent(srcsel);
u32 *pllreg = clkid_2_register(parent);
unsigned long prate = __zynq_clk_pll_get_rate(pllreg);
if (!div)
div = 1;
return DIV_ROUND_CLOSEST(prate, div);
}
/**
* set_cpu_clk_info() - Initialize clock framework
* Always returns zero.
*
* This function is called from common code after relocation and sets up the
* clock framework. The framework must not be used before this function had been
* called.
*/
int set_cpu_clk_info(void)
{
zynq_clk_register_pll(&clks[armpll_clk], &slcr_base->arm_pll_ctrl,
"armpll", CONFIG_ZYNQ_PS_CLK_FREQ);
zynq_clk_register_pll(&clks[ddrpll_clk], &slcr_base->ddr_pll_ctrl,
"ddrpll", CONFIG_ZYNQ_PS_CLK_FREQ);
zynq_clk_register_pll(&clks[iopll_clk], &slcr_base->io_pll_ctrl,
"iopll", CONFIG_ZYNQ_PS_CLK_FREQ);
init_ddr_clocks();
init_cpu_clocks();
init_periph_clocks();
init_aper_clocks();
gd->bd->bi_arm_freq = gd->cpu_clk / 1000000;
gd->bd->bi_dsp_freq = 0;
return 0;
}
/**
* zynq_clk_get_rate() - Get clock rate
* @clk: Clock identifier
* Returns the current clock rate of @clk on success or zero for an invalid
* clock id.
*/
unsigned long zynq_clk_get_rate(enum zynq_clk clk)
{
if (clk < 0 || clk >= clk_max)
return 0;
return clks[clk].frequency;
}
/**
* zynq_clk_set_rate() - Set clock rate
* @clk: Clock identifier
* @rate: Requested clock rate
* Passes on the return value from the clock's set_rate() function or negative
* errno.
*/
int zynq_clk_set_rate(enum zynq_clk clk, unsigned long rate)
{
if (clk < 0 || clk >= clk_max)
return -ENODEV;
if (clks[clk].ops.set_rate)
return clks[clk].ops.set_rate(&clks[clk], rate);
return -ENXIO;
}
/**
* zynq_clk_get_name() - Get clock name
* @clk: Clock identifier
* Returns the name of @clk.
*/
const char *zynq_clk_get_name(enum zynq_clk clk)
{
return clks[clk].name;
}
/**
* soc_clk_dump() - Print clock frequencies
* Returns zero on success
*
* Implementation for the clk dump command.
*/
int soc_clk_dump(void)
{
int i;
printf("clk\t\tfrequency\n");
for (i = 0; i < clk_max; i++) {
const char *name = zynq_clk_get_name(i);
if (name)
printf("%10s%20lu\n", name, zynq_clk_get_rate(i));
}
return 0;
}

View File

@ -6,6 +6,7 @@
*/
#include <common.h>
#include <asm/io.h>
#include <asm/arch/clk.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/hardware.h>
@ -16,7 +17,7 @@ void lowlevel_init(void)
int arch_cpu_init(void)
{
zynq_slcr_unlock();
#ifndef CONFIG_SPL_BUILD
/* Device config APB, unlock the PCAP */
writel(0x757BDF0D, &devcfg_base->unlock);
writel(0xFFFFFFFF, &devcfg_base->rom_shadow);
@ -34,7 +35,8 @@ int arch_cpu_init(void)
/* Urgent write, ports S2/S3 */
writel(0xC, &slcr_base->ddr_urgent);
#endif
#endif
zynq_clk_early_init();
zynq_slcr_lock();
return 0;
@ -46,3 +48,11 @@ void reset_cpu(ulong addr)
while (1)
;
}
#ifndef CONFIG_SYS_DCACHE_OFF
void enable_caches(void)
{
/* Enable D-cache. I-cache is already enabled in start.S */
dcache_enable();
}
#endif

View File

@ -8,6 +8,7 @@
#include <asm/io.h>
#include <malloc.h>
#include <asm/arch/hardware.h>
#include <asm/arch/clk.h>
#define SLCR_LOCK_MAGIC 0x767B
#define SLCR_UNLOCK_MAGIC 0xDF0D
@ -50,8 +51,10 @@ void zynq_slcr_cpu_reset(void)
}
/* Setup clk for network */
void zynq_slcr_gem_clk_setup(u32 gem_id, u32 rclk, u32 clk)
void zynq_slcr_gem_clk_setup(u32 gem_id, unsigned long clk_rate)
{
int ret;
zynq_slcr_unlock();
if (gem_id > 1) {
@ -59,16 +62,16 @@ void zynq_slcr_gem_clk_setup(u32 gem_id, u32 rclk, u32 clk)
goto out;
}
ret = zynq_clk_set_rate(gem0_clk + gem_id, clk_rate);
if (ret)
goto out;
if (gem_id) {
/* Set divisors for appropriate frequency in GEM_CLK_CTRL */
writel(clk, &slcr_base->gem1_clk_ctrl);
/* Configure GEM_RCLK_CTRL */
writel(rclk, &slcr_base->gem1_rclk_ctrl);
writel(1, &slcr_base->gem1_rclk_ctrl);
} else {
/* Set divisors for appropriate frequency in GEM_CLK_CTRL */
writel(clk, &slcr_base->gem0_clk_ctrl);
/* Configure GEM_RCLK_CTRL */
writel(rclk, &slcr_base->gem0_rclk_ctrl);
writel(1, &slcr_base->gem0_rclk_ctrl);
}
udelay(100000);
out:

View File

@ -0,0 +1,69 @@
/*
* (C) Copyright 2014 Xilinx, Inc. Michal Simek
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <spl.h>
#include <asm/io.h>
#include <asm/arch/hardware.h>
#include <asm/arch/spl.h>
#include <asm/arch/sys_proto.h>
DECLARE_GLOBAL_DATA_PTR;
void board_init_f(ulong dummy)
{
ps7_init();
/* Clear the BSS. */
memset(__bss_start, 0, __bss_end - __bss_start);
/* Set global data pointer. */
gd = &gdata;
preloader_console_init();
arch_cpu_init();
board_init_r(NULL, 0);
}
u32 spl_boot_device(void)
{
u32 mode;
switch ((zynq_slcr_get_boot_mode()) & ZYNQ_BM_MASK) {
#ifdef CONFIG_SPL_SPI_SUPPORT
case ZYNQ_BM_QSPI:
puts("qspi boot\n");
mode = BOOT_DEVICE_SPI;
break;
#endif
#ifdef CONFIG_SPL_MMC_SUPPORT
case ZYNQ_BM_SD:
puts("mmc boot\n");
mode = BOOT_DEVICE_MMC1;
break;
#endif
default:
puts("Unsupported boot mode selected\n");
hang();
}
return mode;
}
#ifdef CONFIG_SPL_MMC_SUPPORT
u32 spl_boot_mode(void)
{
return MMCSD_MODE_FAT;
}
#endif
#ifdef CONFIG_SPL_OS_BOOT
int spl_start_uboot(void)
{
/* boot linux */
return 0;
}
#endif

View File

@ -29,6 +29,7 @@
#include <div64.h>
#include <asm/io.h>
#include <asm/arch/hardware.h>
#include <asm/arch/clk.h>
DECLARE_GLOBAL_DATA_PTR;
@ -48,7 +49,6 @@ static struct scu_timer *timer_base =
#define TIMER_LOAD_VAL 0xFFFFFFFF
#define TIMER_PRESCALE 255
#define TIMER_TICK_HZ (CONFIG_CPU_FREQ_HZ / 2 / TIMER_PRESCALE)
int timer_init(void)
{
@ -56,6 +56,8 @@ int timer_init(void)
(TIMER_PRESCALE << SCUTIMER_CONTROL_PRESCALER_SHIFT) |
SCUTIMER_CONTROL_ENABLE_MASK;
gd->arch.timer_rate_hz = (gd->cpu_clk / 2) / (TIMER_PRESCALE + 1);
/* Load the timer counter register */
writel(0xFFFFFFFF, &timer_base->load);
@ -69,7 +71,7 @@ int timer_init(void)
/* Reset time */
gd->arch.lastinc = readl(&timer_base->counter) /
(TIMER_TICK_HZ / CONFIG_SYS_HZ);
(gd->arch.timer_rate_hz / CONFIG_SYS_HZ);
gd->arch.tbl = 0;
return 0;
@ -83,14 +85,15 @@ ulong get_timer_masked(void)
{
ulong now;
now = readl(&timer_base->counter) / (TIMER_TICK_HZ / CONFIG_SYS_HZ);
now = readl(&timer_base->counter) /
(gd->arch.timer_rate_hz / CONFIG_SYS_HZ);
if (gd->arch.lastinc >= now) {
/* Normal mode */
gd->arch.tbl += gd->arch.lastinc - now;
} else {
/* We have an overflow ... */
gd->arch.tbl += gd->arch.lastinc + TIMER_LOAD_VAL - now;
gd->arch.tbl += gd->arch.lastinc + TIMER_LOAD_VAL - now + 1;
}
gd->arch.lastinc = now;
@ -107,7 +110,8 @@ void __udelay(unsigned long usec)
if (usec == 0)
return;
countticks = lldiv(TIMER_TICK_HZ * usec, 1000000);
countticks = lldiv(((unsigned long long)gd->arch.timer_rate_hz * usec),
1000000);
/* decrementing timer */
timeend = readl(&timer_base->counter) - countticks;

View File

@ -0,0 +1,61 @@
/*
* Copyright (c) 2014 Xilinx, Inc. Michal Simek
* Copyright (c) 2004-2008 Texas Instruments
*
* (C) Copyright 2002
* Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
*
* SPDX-License-Identifier: GPL-2.0+
*/
MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE,\
LENGTH = CONFIG_SPL_MAX_SIZE }
MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \
LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = ALIGN(4);
.text :
{
__image_copy_start = .;
CPUDIR/start.o (.text*)
*(.text*)
} > .sram
. = ALIGN(4);
.rodata : {
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
} > .sram
. = ALIGN(4);
.data : {
*(.data*)
} > .sram
. = ALIGN(4);
. = .;
__image_copy_end = .;
_end = .;
/* Move BSS section to RAM because of FAT */
.bss (NOLOAD) : {
__bss_start = .;
*(.bss*)
. = ALIGN(4);
__bss_end = .;
} > .sdram
/DISCARD/ : { *(.dynsym) }
/DISCARD/ : { *(.dynstr*) }
/DISCARD/ : { *(.dynamic*) }
/DISCARD/ : { *(.plt*) }
/DISCARD/ : { *(.interp*) }
/DISCARD/ : { *(.gnu*) }
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -106,6 +106,8 @@ const char *get_imx_type(u32 imxtype)
switch (imxtype) {
case MXC_CPU_MX6Q:
return "6Q"; /* Quad-core version of the mx6 */
case MXC_CPU_MX6D:
return "6D"; /* Dual-core version of the mx6 */
case MXC_CPU_MX6DL:
return "6DL"; /* Dual Lite version of the mx6 */
case MXC_CPU_MX6SOLO:

View File

@ -0,0 +1,13 @@
/*
* (C) Copyright 2014 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#define MXC_CPU_MX51 0x51
#define MXC_CPU_MX53 0x53
#define MXC_CPU_MX6SL 0x60
#define MXC_CPU_MX6DL 0x61
#define MXC_CPU_MX6SOLO 0x62
#define MXC_CPU_MX6Q 0x63
#define MXC_CPU_MX6D 0x64

View File

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

View File

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

View File

@ -8,12 +8,7 @@
#ifndef _SYS_PROTO_H_
#define _SYS_PROTO_H_
#define MXC_CPU_MX51 0x51
#define MXC_CPU_MX53 0x53
#define MXC_CPU_MX6SL 0x60
#define MXC_CPU_MX6DL 0x61
#define MXC_CPU_MX6SOLO 0x62
#define MXC_CPU_MX6Q 0x63
#include "../arch-imx/cpu.h"
#define is_soc_rev(rev) ((get_cpu_rev() & 0xFF) - rev)
u32 get_cpu_rev(void);

View File

@ -55,6 +55,7 @@ unsigned int mxc_get_clock(enum mxc_clock clk);
void enable_ocotp_clk(unsigned char enable);
void enable_usboh3_clk(unsigned char enable);
int enable_sata_clock(void);
int enable_pcie_clock(void);
int enable_i2c_clk(unsigned char enable, unsigned i2c_num);
void enable_ipu_clock(void);
int enable_fec_anatop_clock(enum enet_freq freq);

View File

@ -53,6 +53,7 @@
#define GLOBAL_TIMER_BASE_ADDR 0x00A00200
#define PRIVATE_TIMERS_WD_BASE_ADDR 0x00A00600
#define IC_DISTRIBUTOR_BASE_ADDR 0x00A01000
#define L2_PL310_BASE 0x00A02000
#define GPV0_BASE_ADDR 0x00B00000
#define GPV1_BASE_ADDR 0x00C00000
#define PCIE_ARB_BASE_ADDR 0x01000000

View File

@ -15,6 +15,33 @@
#define IOMUXC_GPR1_OTG_ID_ENET_RX_ERR (0<<13)
#define IOMUXC_GPR1_OTG_ID_GPIO1 (1<<13)
#define IOMUXC_GPR1_OTG_ID_MASK (1<<13)
#define IOMUXC_GPR1_REF_SSP_EN (1 << 16)
#define IOMUXC_GPR1_TEST_POWERDOWN (1 << 18)
/*
* IOMUXC_GPR8 bit fields
*/
#define IOMUXC_GPR8_PCS_TX_DEEMPH_GEN1_MASK (0x3f << 0)
#define IOMUXC_GPR8_PCS_TX_DEEMPH_GEN1_OFFSET 0
#define IOMUXC_GPR8_PCS_TX_DEEMPH_GEN2_3P5DB_MASK (0x3f << 6)
#define IOMUXC_GPR8_PCS_TX_DEEMPH_GEN2_3P5DB_OFFSET 6
#define IOMUXC_GPR8_PCS_TX_DEEMPH_GEN2_6DB_MASK (0x3f << 12)
#define IOMUXC_GPR8_PCS_TX_DEEMPH_GEN2_6DB_OFFSET 12
#define IOMUXC_GPR8_PCS_TX_SWING_FULL_MASK (0x7f << 18)
#define IOMUXC_GPR8_PCS_TX_SWING_FULL_OFFSET 18
#define IOMUXC_GPR8_PCS_TX_SWING_LOW_MASK (0x7f << 25)
#define IOMUXC_GPR8_PCS_TX_SWING_LOW_OFFSET 25
/*
* IOMUXC_GPR12 bit fields
*/
#define IOMUXC_GPR12_LOS_LEVEL_9 (0x9 << 4)
#define IOMUXC_GPR12_LOS_LEVEL_MASK (0x1f << 4)
#define IOMUXC_GPR12_APPS_LTSSM_ENABLE (1 << 10)
#define IOMUXC_GPR12_DEVICE_TYPE_EP (0x0 << 12)
#define IOMUXC_GPR12_DEVICE_TYPE_RC (0x2 << 12)
#define IOMUXC_GPR12_DEVICE_TYPE_MASK (0xf << 12)
/*
* IOMUXC_GPR13 bit fields
*/

View File

@ -647,7 +647,7 @@ MX6_PAD_DECL(ENET_MDIO__ESAI_RX_CLK, 0x05BC, 0x01EC, 2, 0x083C, 0, 0)
MX6_PAD_DECL(ENET_MDIO__ENET_1588_EVENT1_OUT, 0x05BC, 0x01EC, 4, 0x0000, 0, 0)
MX6_PAD_DECL(ENET_MDIO__GPIO1_IO22, 0x05BC, 0x01EC, 5, 0x0000, 0, 0)
MX6_PAD_DECL(ENET_MDIO__SPDIF_LOCK, 0x05BC, 0x01EC, 6, 0x0000, 0, 0)
MX6_PAD_DECL(ENET_REF_CLK__ENET_TX_CLK, 0x05C0, 0x01F0, 1, 0x0000, 0, 0)
MX6_PAD_DECL(ENET_REF_CLK__ENET_TX_CLK, 0x05C0, 0x01F0, 1 | IOMUX_CONFIG_SION, 0x0000, 0, 0)
MX6_PAD_DECL(ENET_REF_CLK__ESAI_RX_FS, 0x05C0, 0x01F0, 2, 0x082C, 0, 0)
MX6_PAD_DECL(ENET_REF_CLK__GPIO1_IO23, 0x05C0, 0x01F0, 5, 0x0000, 0, 0)
MX6_PAD_DECL(ENET_REF_CLK__SPDIF_SR_CLK, 0x05C0, 0x01F0, 6, 0x0000, 0, 0)
@ -695,7 +695,7 @@ MX6_PAD_DECL(GPIO_1__GPIO1_IO01, 0x05E0, 0x0210, 5, 0x0000, 0, 0)
MX6_PAD_DECL(GPIO_1__SD1_CD_B, 0x05E0, 0x0210, 6, 0x0000, 0, 0)
MX6_PAD_DECL(GPIO_16__ESAI_TX3_RX2, 0x05E4, 0x0214, 0, 0x0850, 1, 0)
MX6_PAD_DECL(GPIO_16__ENET_1588_EVENT2_IN, 0x05E4, 0x0214, 1, 0x0000, 0, 0)
MX6_PAD_DECL(GPIO_16__ENET_REF_CLK, 0x05E4, 0x0214, 2, 0x080C, 0, 0)
MX6_PAD_DECL(GPIO_16__ENET_REF_CLK, 0x05E4, 0x0214, 2 | IOMUX_CONFIG_SION, 0x080C, 0, 0)
MX6_PAD_DECL(GPIO_16__SD1_LCTL, 0x05E4, 0x0214, 3, 0x0000, 0, 0)
MX6_PAD_DECL(GPIO_16__SPDIF_IN, 0x05E4, 0x0214, 4, 0x08F0, 2, 0)
MX6_PAD_DECL(GPIO_16__GPIO7_IO11, 0x05E4, 0x0214, 5, 0x0000, 0, 0)
@ -934,7 +934,7 @@ MX6_PAD_DECL(RGMII_TX_CTL__USBOH3_H2_STROBE, 0x06BC, 0x02D4, 0 | IOMUX_CONFIG_SI
MX6_PAD_DECL(RGMII_TX_CTL__USB_H2_STROBE, 0x06BC, 0x02D4, 0 | IOMUX_CONFIG_SION, 0x0000, 0, PAD_CTL_PUS_47K_UP)
MX6_PAD_DECL(RGMII_TX_CTL__RGMII_TX_CTL, 0x06BC, 0x02D4, 1, 0x0000, 0, 0)
MX6_PAD_DECL(RGMII_TX_CTL__GPIO6_IO26, 0x06BC, 0x02D4, 5, 0x0000, 0, 0)
MX6_PAD_DECL(RGMII_TX_CTL__ENET_REF_CLK, 0x06BC, 0x02D4, 7, 0x080C, 1, 0)
MX6_PAD_DECL(RGMII_TX_CTL__ENET_REF_CLK, 0x06BC, 0x02D4, 7 | IOMUX_CONFIG_SION, 0x080C, 1, 0)
MX6_PAD_DECL(RGMII_TXC__USB_H2_DATA, 0x06C0, 0x02D8, 0 | IOMUX_CONFIG_SION, 0x0000, 0, 0)
MX6_PAD_DECL(RGMII_TXC__RGMII_TXC, 0x06C0, 0x02D8, 1, 0x0000, 0, 0)
MX6_PAD_DECL(RGMII_TXC__SPDIF_EXT_CLK, 0x06C0, 0x02D8, 2, 0x08F4, 1, 0)

View File

@ -53,7 +53,7 @@ MX6_PAD_DECL(RGMII_RD0__GPIO6_IO25, 0x0384, 0x0070, 5, 0x0000, 0, 0)
MX6_PAD_DECL(RGMII_TX_CTL__USB_H2_STROBE, 0x0388, 0x0074, 0, 0x0000, 0, 0)
MX6_PAD_DECL(RGMII_TX_CTL__RGMII_TX_CTL, 0x0388, 0x0074, 1, 0x0000, 0, 0)
MX6_PAD_DECL(RGMII_TX_CTL__GPIO6_IO26, 0x0388, 0x0074, 5, 0x0000, 0, 0)
MX6_PAD_DECL(RGMII_TX_CTL__ENET_REF_CLK, 0x0388, 0x0074, 7, 0x083C, 0, 0)
MX6_PAD_DECL(RGMII_TX_CTL__ENET_REF_CLK, 0x0388, 0x0074, 7 | IOMUX_CONFIG_SION, 0x083C, 0, 0)
MX6_PAD_DECL(RGMII_RD1__HSI_TX_FLAG, 0x038C, 0x0078, 0, 0x0000, 0, 0)
MX6_PAD_DECL(RGMII_RD1__RGMII_RD1, 0x038C, 0x0078, 1, 0x084C, 0, 0)
MX6_PAD_DECL(RGMII_RD1__GPIO6_IO27, 0x038C, 0x0078, 5, 0x0000, 0, 0)
@ -523,7 +523,7 @@ MX6_PAD_DECL(ENET_MDIO__ESAI_RX_CLK, 0x04E4, 0x01D0, 2, 0x086C, 0, 0)
MX6_PAD_DECL(ENET_MDIO__ENET_1588_EVENT1_OUT, 0x04E4, 0x01D0, 4, 0x0000, 0, 0)
MX6_PAD_DECL(ENET_MDIO__GPIO1_IO22, 0x04E4, 0x01D0, 5, 0x0000, 0, 0)
MX6_PAD_DECL(ENET_MDIO__SPDIF_LOCK, 0x04E4, 0x01D0, 6, 0x0000, 0, 0)
MX6_PAD_DECL(ENET_REF_CLK__ENET_TX_CLK, 0x04E8, 0x01D4, 1, 0x0000, 0, 0)
MX6_PAD_DECL(ENET_REF_CLK__ENET_TX_CLK, 0x04E8, 0x01D4, 1 | IOMUX_CONFIG_SION, 0x0000, 0, 0)
MX6_PAD_DECL(ENET_REF_CLK__ESAI_RX_FS, 0x04E8, 0x01D4, 2, 0x085C, 0, 0)
MX6_PAD_DECL(ENET_REF_CLK__GPIO1_IO23, 0x04E8, 0x01D4, 5, 0x0000, 0, 0)
MX6_PAD_DECL(ENET_REF_CLK__SPDIF_SR_CLK, 0x04E8, 0x01D4, 6, 0x0000, 0, 0)
@ -703,7 +703,7 @@ MX6_PAD_DECL(GPIO_8__SPDIF_SR_CLK, 0x0614, 0x0244, 6, 0x0000, 0, 0)
MX6_PAD_DECL(GPIO_8__USB_OTG_PWR_CTL_WAKE, 0x0614, 0x0244, 7, 0x0000, 0, 0)
MX6_PAD_DECL(GPIO_16__ESAI_TX3_RX2, 0x0618, 0x0248, 0, 0x0880, 1, 0)
MX6_PAD_DECL(GPIO_16__ENET_1588_EVENT2_IN, 0x0618, 0x0248, 1, 0x0000, 0, 0)
MX6_PAD_DECL(GPIO_16__ENET_REF_CLK, 0x0618, 0x0248, 2, 0x083C, 1, 0)
MX6_PAD_DECL(GPIO_16__ENET_REF_CLK, 0x0618, 0x0248, 2 | IOMUX_CONFIG_SION, 0x083C, 1, 0)
MX6_PAD_DECL(GPIO_16__SD1_LCTL, 0x0618, 0x0248, 3, 0x0000, 0, 0)
MX6_PAD_DECL(GPIO_16__SPDIF_IN, 0x0618, 0x0248, 4, 0x0914, 3, 0)
MX6_PAD_DECL(GPIO_16__GPIO7_IO11, 0x0618, 0x0248, 5, 0x0000, 0, 0)

View File

@ -9,13 +9,7 @@
#define _SYS_PROTO_H_
#include <asm/imx-common/regs-common.h>
#define MXC_CPU_MX51 0x51
#define MXC_CPU_MX53 0x53
#define MXC_CPU_MX6SL 0x60
#define MXC_CPU_MX6DL 0x61
#define MXC_CPU_MX6SOLO 0x62
#define MXC_CPU_MX6Q 0x63
#include "../arch-imx/cpu.h"
#define is_soc_rev(rev) ((get_cpu_rev() & 0xFF) - rev)
u32 get_cpu_rev(void);

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2013 Xilinx Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _ZYNQ_CLK_H_
#define _ZYNQ_CLK_H_
enum zynq_clk {
armpll_clk, ddrpll_clk, iopll_clk,
cpu_6or4x_clk, cpu_3or2x_clk, cpu_2x_clk, cpu_1x_clk,
ddr2x_clk, ddr3x_clk, dci_clk,
lqspi_clk, smc_clk, pcap_clk, gem0_clk, gem1_clk,
fclk0_clk, fclk1_clk, fclk2_clk, fclk3_clk, can0_clk, can1_clk,
sdio0_clk, sdio1_clk, uart0_clk, uart1_clk, spi0_clk, spi1_clk, dma_clk,
usb0_aper_clk, usb1_aper_clk, gem0_aper_clk, gem1_aper_clk,
sdio0_aper_clk, sdio1_aper_clk, spi0_aper_clk, spi1_aper_clk,
can0_aper_clk, can1_aper_clk, i2c0_aper_clk, i2c1_aper_clk,
uart0_aper_clk, uart1_aper_clk, gpio_aper_clk, lqspi_aper_clk,
smc_aper_clk, swdt_clk, dbg_trc_clk, dbg_apb_clk, clk_max};
void zynq_clk_early_init(void);
int zynq_clk_set_rate(enum zynq_clk clk, unsigned long rate);
unsigned long zynq_clk_get_rate(enum zynq_clk clk);
const char *zynq_clk_get_name(enum zynq_clk clk);
unsigned long get_uart_clk(int dev_id);
#endif

View File

@ -7,6 +7,8 @@
#ifndef _ASM_ARCH_HARDWARE_H
#define _ASM_ARCH_HARDWARE_H
#define ZYNQ_SERIAL_BASEADDR0 0xE0000000
#define ZYNQ_SERIAL_BASEADDR1 0xE0001000
#define ZYNQ_SYS_CTRL_BASEADDR 0xF8000000
#define ZYNQ_DEV_CFG_APB_BASEADDR 0xF8007000
#define ZYNQ_SCU_BASEADDR 0xF8F00000
@ -21,17 +23,51 @@
#define ZYNQ_SPI_BASEADDR1 0xE0007000
#define ZYNQ_DDRC_BASEADDR 0xF8006000
/* Bootmode setting values */
#define ZYNQ_BM_MASK 0xF
#define ZYNQ_BM_NOR 0x2
#define ZYNQ_BM_SD 0x5
#define ZYNQ_BM_JTAG 0x0
/* Reflect slcr offsets */
struct slcr_regs {
u32 scl; /* 0x0 */
u32 slcr_lock; /* 0x4 */
u32 slcr_unlock; /* 0x8 */
u32 reserved0[75];
u32 reserved0_1[61];
u32 arm_pll_ctrl; /* 0x100 */
u32 ddr_pll_ctrl; /* 0x104 */
u32 io_pll_ctrl; /* 0x108 */
u32 reserved0_2[5];
u32 arm_clk_ctrl; /* 0x120 */
u32 ddr_clk_ctrl; /* 0x124 */
u32 dci_clk_ctrl; /* 0x128 */
u32 aper_clk_ctrl; /* 0x12c */
u32 reserved0_3[2];
u32 gem0_rclk_ctrl; /* 0x138 */
u32 gem1_rclk_ctrl; /* 0x13c */
u32 gem0_clk_ctrl; /* 0x140 */
u32 gem1_clk_ctrl; /* 0x144 */
u32 reserved1[46];
u32 smc_clk_ctrl; /* 0x148 */
u32 lqspi_clk_ctrl; /* 0x14c */
u32 sdio_clk_ctrl; /* 0x150 */
u32 uart_clk_ctrl; /* 0x154 */
u32 spi_clk_ctrl; /* 0x158 */
u32 can_clk_ctrl; /* 0x15c */
u32 can_mioclk_ctrl; /* 0x160 */
u32 dbg_clk_ctrl; /* 0x164 */
u32 pcap_clk_ctrl; /* 0x168 */
u32 reserved0_4[1];
u32 fpga0_clk_ctrl; /* 0x170 */
u32 reserved0_5[3];
u32 fpga1_clk_ctrl; /* 0x180 */
u32 reserved0_6[3];
u32 fpga2_clk_ctrl; /* 0x190 */
u32 reserved0_7[3];
u32 fpga3_clk_ctrl; /* 0x1a0 */
u32 reserved0_8[8];
u32 clk_621_true; /* 0x1c4 */
u32 reserved1[14];
u32 pss_rst_ctrl; /* 0x200 */
u32 reserved2[15];
u32 fpga_rst_ctrl; /* 0x240 */

View File

@ -0,0 +1,18 @@
/*
* (C) Copyright 2014 Xilinx, Inc. Michal Simek
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _ASM_ARCH_SPL_H_
#define _ASM_ARCH_SPL_H_
extern void ps7_init(void);
#define BOOT_DEVICE_NONE 0
#define BOOT_DEVICE_RAM 1
#define BOOT_DEVICE_SPI 2
#define BOOT_DEVICE_MMC1 3
#define BOOT_DEVICE_MMC2 4
#define BOOT_DEVICE_MMC2_2 5
#endif

View File

@ -10,7 +10,7 @@
extern void zynq_slcr_lock(void);
extern void zynq_slcr_unlock(void);
extern void zynq_slcr_cpu_reset(void);
extern void zynq_slcr_gem_clk_setup(u32 gem_id, u32 rclk, u32 clk);
extern void zynq_slcr_gem_clk_setup(u32 gem_id, unsigned long clk_rate);
extern void zynq_slcr_devcfg_disable(void);
extern void zynq_slcr_devcfg_enable(void);
extern u32 zynq_slcr_get_boot_mode(void);

View File

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

View File

@ -12,6 +12,9 @@
/* Register bit fields */
#define PL310_AUX_CTRL_ASSOCIATIVITY_MASK (1 << 16)
#define L2X0_DYNAMIC_CLK_GATING_EN (1 << 1)
#define L2X0_STNDBY_MODE_EN (1 << 0)
#define L2X0_CTRL_EN 1
struct pl310_regs {
u32 pl310_cache_id;
@ -47,6 +50,24 @@ struct pl310_regs {
u32 pad9[1];
u32 pl310_clean_inv_line_idx;
u32 pl310_clean_inv_way;
u32 pad10[64];
u32 pl310_lockdown_dbase;
u32 pl310_lockdown_ibase;
u32 pad11[190];
u32 pl310_addr_filter_start;
u32 pl310_addr_filter_end;
u32 pad12[190];
u32 pl310_test_operation;
u32 pad13[3];
u32 pl310_line_data;
u32 pad14[7];
u32 pl310_line_tag;
u32 pad15[3];
u32 pl310_debug_ctrl;
u32 pad16[7];
u32 pl310_prefetch_ctrl;
u32 pad17[7];
u32 pl310_power_ctrl;
};
void pl310_inval_all(void);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -67,10 +67,10 @@ override auto-detection and force activation of the specified panel.
To build U-Boot for one of the Nitrogen6x or SabreLite board:
make nitrogen6x_config
make u-boot.imx
make
Note that 'nitrogen6x' is a placeholder. The complete list of supported
board configurations is shown in tha MAINTAINERS file:
board configurations is shown in the boards.cfg file:
nitrogen6q i.MX6Q/6D 1GB
nitrogen6dl i.MX6DL 1GB
nitrogen6s i.MX6S 512MB

View File

@ -16,7 +16,7 @@ IMAGE_VERSION 2
* Boot Device : one of
* spi, sd (the board has no nand neither onenand)
*/
BOOT_FROM sd
BOOT_FROM spi
#define __ASSEMBLY__
#include <config.h>

View File

@ -16,7 +16,7 @@ IMAGE_VERSION 2
* Boot Device : one of
* spi, sd (the board has no nand neither onenand)
*/
BOOT_FROM sd
BOOT_FROM spi
#define __ASSEMBLY__
#include <config.h>

View File

@ -16,7 +16,7 @@ IMAGE_VERSION 2
* Boot Device : one of
* spi, sd (the board has no nand neither onenand)
*/
BOOT_FROM sd
BOOT_FROM spi
#define __ASSEMBLY__
#include <config.h>

View File

@ -16,7 +16,7 @@ IMAGE_VERSION 2
* Boot Device : one of
* spi, sd (the board has no nand neither onenand)
*/
BOOT_FROM sd
BOOT_FROM spi
#define __ASSEMBLY__
#include <config.h>

View File

@ -16,7 +16,7 @@ IMAGE_VERSION 2
* Boot Device : one of
* spi, sd (the board has no nand neither onenand)
*/
BOOT_FROM sd
BOOT_FROM spi
#define __ASSEMBLY__
#include <config.h>

View File

@ -16,7 +16,7 @@ IMAGE_VERSION 2
* Boot Device : one of
* spi, sd (the board has no nand neither onenand)
*/
BOOT_FROM sd
BOOT_FROM spi
#define __ASSEMBLY__
#include <config.h>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -29,119 +29,101 @@ BOOT_FROM sd
* Address absolute address of the register
* value value to be stored in the register
*/
DATA 4 0x020e0798 0x000C0000
DATA 4 0x020e0758 0x00000000
DATA 4 0x020e0588 0x00000030
DATA 4 0x020e0594 0x00000030
DATA 4 0x020e056c 0x00000030
DATA 4 0x020e0578 0x00000030
DATA 4 0x020e074c 0x00000030
DATA 4 0x020e057c 0x00000030
DATA 4 0x020e058c 0x00000000
DATA 4 0x020e059c 0x00000030
DATA 4 0x020e05a0 0x00000030
DATA 4 0x020e078c 0x00000030
DATA 4 0x020e0750 0x00020000
DATA 4 0x020e05a8 0x00000028
DATA 4 0x020e05b0 0x00000028
DATA 4 0x020e0524 0x00000028
DATA 4 0x020e051c 0x00000028
DATA 4 0x020e0518 0x00000028
DATA 4 0x020e050c 0x00000028
DATA 4 0x020e05b8 0x00000028
DATA 4 0x020e05c0 0x00000028
DATA 4 0x020e05ac 0x00000028
DATA 4 0x020e05b4 0x00000028
DATA 4 0x020e0528 0x00000028
DATA 4 0x020e0520 0x00000028
DATA 4 0x020e0514 0x00000028
DATA 4 0x020e0510 0x00000028
DATA 4 0x020e05bc 0x00000028
DATA 4 0x020e05c4 0x00000028
DATA 4 0x020e056c 0x00000030
DATA 4 0x020e0578 0x00000030
DATA 4 0x020e0588 0x00000030
DATA 4 0x020e0594 0x00000030
DATA 4 0x020e057c 0x00000030
DATA 4 0x020e0590 0x00000030
DATA 4 0x020e0598 0x00000030
DATA 4 0x020e058c 0x00000000
DATA 4 0x020e059c 0x00003030
DATA 4 0x020e05a0 0x00003030
DATA 4 0x020e0774 0x00020000
DATA 4 0x020e0784 0x00000028
DATA 4 0x020e0788 0x00000028
DATA 4 0x020e0794 0x00000028
DATA 4 0x020e079c 0x00000028
DATA 4 0x020e07a0 0x00000028
DATA 4 0x020e07a4 0x00000028
DATA 4 0x020e07a8 0x00000028
DATA 4 0x020e0748 0x00000028
DATA 4 0x020e074c 0x00000030
DATA 4 0x020e0750 0x00020000
DATA 4 0x020e0758 0x00000000
DATA 4 0x020e0774 0x00020000
DATA 4 0x020e078c 0x00000030
DATA 4 0x020e0798 0x000C0000
DATA 4 0x020e05ac 0x00000028
DATA 4 0x020e05b4 0x00000028
DATA 4 0x020e0528 0x00000028
DATA 4 0x020e0520 0x00000028
DATA 4 0x020e0514 0x00000028
DATA 4 0x020e0510 0x00000028
DATA 4 0x020e05bc 0x00000028
DATA 4 0x020e05c4 0x00000028
DATA 4 0x021b0800 0xa1390003
DATA 4 0x021b080c 0x001F001F
DATA 4 0x021b0810 0x001F001F
DATA 4 0x021b480c 0x001F001F
DATA 4 0x021b4810 0x001F001F
DATA 4 0x021b083c 0x43260335
DATA 4 0x021b0840 0x031A030B
DATA 4 0x021b483c 0x4323033B
DATA 4 0x021b4840 0x0323026F
DATA 4 0x021b0848 0x483D4545
DATA 4 0x021b4848 0x44433E48
DATA 4 0x021b0850 0x41444840
DATA 4 0x021b4850 0x4835483E
DATA 4 0x021b081c 0x33333333
DATA 4 0x021b0820 0x33333333
DATA 4 0x021b0824 0x33333333
DATA 4 0x021b0828 0x33333333
DATA 4 0x021b481c 0x33333333
DATA 4 0x021b4820 0x33333333
DATA 4 0x021b4824 0x33333333
DATA 4 0x021b4828 0x33333333
DATA 4 0x021b0018 0x00001740
DATA 4 0x021b001c 0x00008000
DATA 4 0x021b000c 0x8A8F7975
DATA 4 0x021b0010 0xFF538E64
DATA 4 0x021b0014 0x01FF00DB
DATA 4 0x021b002c 0x000026D2
DATA 4 0x021b0030 0x008F0E21
DATA 4 0x021b0008 0x09444040
DATA 4 0x021b0004 0x00020036
DATA 4 0x021b0040 0x00000047
DATA 4 0x021b0000 0x841A0000
DATA 4 0x021b001c 0x04088032
DATA 4 0x021b001c 0x00008033
DATA 4 0x021b001c 0x00428031
DATA 4 0x021b001c 0x09408030
DATA 4 0x021b001c 0x04008040
DATA 4 0x021b0800 0xA1380003
DATA 4 0x021b0020 0x00005800
DATA 4 0x021b0818 0x00000007
DATA 4 0x021b4818 0x00000007
/* Calibration values based on ARD and 528MHz */
DATA 4 0x021b083c 0x434B0358
DATA 4 0x021b0840 0x033D033C
DATA 4 0x021b483c 0x03520362
DATA 4 0x021b4840 0x03480318
DATA 4 0x021b0848 0x41383A3C
DATA 4 0x021b4848 0x3F3C374A
DATA 4 0x021b0850 0x42434444
DATA 4 0x021b4850 0x4932473A
DATA 4 0x021b080c 0x001F001F
DATA 4 0x021b0810 0x001F001F
DATA 4 0x021b480c 0x001F001F
DATA 4 0x021b4810 0x001F001F
DATA 4 0x021b08b8 0x00000800
DATA 4 0x021b48b8 0x00000800
DATA 4 0x021b0404 0x00011006
DATA 4 0x021b0004 0x00020036
DATA 4 0x021b0008 0x09444040
DATA 4 0x021b000c 0x8A8F7955
DATA 4 0x021b0010 0xFF328F64
DATA 4 0x021b0014 0x01FF00DB
DATA 4 0x021b0018 0x00001740
DATA 4 0x021b001c 0x00008000
DATA 4 0x021b002c 0x000026d2
DATA 4 0x021b0030 0x008F1023
DATA 4 0x021b0040 0x00000047
DATA 4 0x021b0000 0x841A0000
DATA 4 0x021b001c 0x04088032
DATA 4 0x021b001c 0x00008033
DATA 4 0x021b001c 0x00048031
DATA 4 0x021b001c 0x09408030
DATA 4 0x021b001c 0x04008040
DATA 4 0x021b0020 0x00005800
DATA 4 0x021b0818 0x00011117
DATA 4 0x021b4818 0x00011117
DATA 4 0x021b0004 0x00025576
DATA 4 0x021b0404 0x00011006
DATA 4 0x021b001c 0x00000000
/* set the default clock gate to save power */
DATA 4 0x020c4068 0x00C03F3F
DATA 4 0x020c406c 0x0030FC00
DATA 4 0x020c406c 0x0030FC03
DATA 4 0x020c4070 0x0FFFC000
DATA 4 0x020c4074 0x3FF00000
DATA 4 0x020c4078 0x00FFF300
DATA 4 0x020c407c 0x0F0000C3
DATA 4 0x020c4080 0x000003FF
DATA 4 0x020c4078 0xFFFFF300
DATA 4 0x020c407c 0x0F0000F3
DATA 4 0x020c4080 0x00000FFF
/* enable AXI cache for VDOA/VPU/IPU */
DATA 4 0x020e0010 0xF00000CF
/* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */
DATA 4 0x020e0018 0x007F007F
DATA 4 0x020e001c 0x007F007F

View File

@ -1,82 +0,0 @@
/*
* Lowlevel setup for SMDK5250 board based on S5PC520
*
* Copyright (C) 2012 Samsung Electronics
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <config.h>
#include <version.h>
#include <asm/arch/cpu.h>
_TEXT_BASE:
.word CONFIG_SYS_TEXT_BASE
.globl lowlevel_init
lowlevel_init:
/* use iRAM stack in bl2 */
ldr sp, =CONFIG_IRAM_STACK
stmdb r13!, {ip,lr}
/* check reset status */
ldr r0, =(EXYNOS5_POWER_BASE + INFORM1_OFFSET)
ldr r1, [r0]
/* AFTR wakeup reset */
ldr r2, =S5P_CHECK_DIDLE
cmp r1, r2
beq exit_wakeup
/* LPA wakeup reset */
ldr r2, =S5P_CHECK_LPA
cmp r1, r2
beq exit_wakeup
/* Sleep wakeup reset */
ldr r2, =S5P_CHECK_SLEEP
cmp r1, r2
beq wakeup_reset
/*
* If U-boot is already running in RAM, no need to relocate U-Boot.
* Memory controller must be configured before relocating U-Boot
* in ram.
*/
ldr r0, =0x0ffffff /* r0 <- Mask Bits*/
bic r1, pc, r0 /* pc <- current addr of code */
/* r1 <- unmasked bits of pc */
ldr r2, _TEXT_BASE /* r2 <- original base addr in ram */
bic r2, r2, r0 /* r2 <- unmasked bits of r2*/
cmp r1, r2 /* compare r1, r2 */
beq 1f /* r0 == r1 then skip sdram init */
/* init system clock */
bl system_clock_init
/* Memory initialize */
bl mem_ctrl_init
1:
bl arch_cpu_init
bl tzpc_init
ldmia r13!, {ip,pc}
wakeup_reset:
bl system_clock_init
bl mem_ctrl_init
bl arch_cpu_init
bl tzpc_init
exit_wakeup:
/* Load return address and jump to kernel */
ldr r0, =(EXYNOS5_POWER_BASE + INFORM0_OFFSET)
/* r1 = physical address of exynos5_cpu_resume function*/
ldr r1, [r0]
/* Jump to kernel */
mov pc, r1
nop
nop

View File

@ -156,11 +156,7 @@ int board_eth_init(bd_t *bis)
setup_iomux_enet();
ret = cpu_eth_init(bis);
if (ret)
printf("FEC MXC: %s:failed\n", __func__);
return ret;
return cpu_eth_init(bis);
}
#endif

View File

@ -6,3 +6,4 @@
#
obj-y := board.o
obj-$(CONFIG_SPL_BUILD) += ps7_init.o

View File

@ -12,12 +12,6 @@
DECLARE_GLOBAL_DATA_PTR;
/* Bootmode setting values */
#define ZYNQ_BM_MASK 0x0F
#define ZYNQ_BM_NOR 0x02
#define ZYNQ_BM_SD 0x05
#define ZYNQ_BM_JTAG 0x0
#ifdef CONFIG_FPGA
Xilinx_desc fpga;
@ -59,8 +53,6 @@ int board_init(void)
}
#endif
icache_enable();
#ifdef CONFIG_FPGA
fpga_init();
fpga_add(fpga_xilinx, &fpga);
@ -89,7 +81,6 @@ int board_late_init(void)
return 0;
}
#ifdef CONFIG_CMD_NET
int board_eth_init(bd_t *bis)
{
u32 ret = 0;
@ -123,7 +114,6 @@ int board_eth_init(bd_t *bis)
#endif
return ret;
}
#endif
#ifdef CONFIG_CMD_MMC
int board_mmc_init(bd_t *bd)

View File

@ -0,0 +1,12 @@
/*
* (C) Copyright 2014 Xilinx, Inc. Michal Simek
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/arch/spl.h>
__weak void ps7_init(void)
{
puts("Please copy ps7_init.c/h from hw project\n");
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -128,8 +128,12 @@ static void fec_mii_setspeed(struct ethernet_regs *eth)
* Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
* and do not drop the Preamble.
*/
writel((((imx_get_fecclk() / 1000000) + 2) / 5) << 1,
&eth->mii_speed);
register u32 speed = DIV_ROUND_UP(imx_get_fecclk(), 5000000);
#ifdef FEC_QUIRK_ENET_MAC
speed--;
#endif
speed <<= 1;
writel(speed, &eth->mii_speed);
debug("%s: mii_speed %08x\n", __func__, readl(&eth->mii_speed));
}

View File

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

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

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