Merge branch 'master' of git://git.denx.de/u-boot-arm
commit
6853e6aa77
2
MAKEALL
2
MAKEALL
|
@ -398,8 +398,6 @@ LIST_at91="$(targets_by_soc at91)"
|
|||
|
||||
LIST_pxa="$(targets_by_cpu pxa)"
|
||||
|
||||
LIST_ixp="$(targets_by_cpu ixp)"
|
||||
|
||||
#########################################################################
|
||||
## SPEAr Systems
|
||||
#########################################################################
|
||||
|
|
1
Makefile
1
Makefile
|
@ -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
1
README
|
@ -141,7 +141,6 @@ Directory Hierarchy:
|
|||
/s3c24x0 Files specific to Samsung S3C24X0 CPUs
|
||||
/arm926ejs Files specific to ARM 926 CPUs
|
||||
/arm1136 Files specific to ARM 1136 CPUs
|
||||
/ixp Files specific to Intel XScale IXP CPUs
|
||||
/pxa Files specific to Intel XScale PXA CPUs
|
||||
/sa1100 Files specific to Intel StrongARM SA1100 CPUs
|
||||
/lib Architecture specific library files
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
@ -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*) }
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
#
|
||||
# (C) Copyright 2000-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
extra-y = start.o
|
||||
|
||||
obj-y += cpu.o
|
||||
obj-$(CONFIG_USE_IRQ) += interrupts.o
|
||||
obj-y += timer.o
|
|
@ -1,16 +0,0 @@
|
|||
#
|
||||
# (C) Copyright 2002
|
||||
# Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
# Marius Groeger <mgroeger@sysgo.de>
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
BIG_ENDIAN = y
|
||||
|
||||
PLATFORM_RELFLAGS += -mbig-endian
|
||||
|
||||
PLATFORM_CPPFLAGS += -mbig-endian -march=armv5te -mtune=strongarm1100
|
||||
|
||||
PLATFORM_LDFLAGS += -EB
|
||||
USE_PRIVATE_LIBGCC = yes
|
|
@ -1,100 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
* Marius Groeger <mgroeger@sysgo.de>
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
* Alex Zuepke <azu@sysgo.de>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/*
|
||||
* CPU specific code
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <netdev.h>
|
||||
#include <asm/arch/ixp425.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
static void cache_flush(void);
|
||||
|
||||
#if defined(CONFIG_DISPLAY_CPUINFO)
|
||||
int print_cpuinfo (void)
|
||||
{
|
||||
unsigned long id;
|
||||
int speed = 0;
|
||||
|
||||
asm ("mrc p15, 0, %0, c0, c0, 0":"=r" (id));
|
||||
|
||||
puts("CPU: Intel IXP425 at ");
|
||||
switch ((id & 0x000003f0) >> 4) {
|
||||
case 0x1c:
|
||||
speed = 533;
|
||||
break;
|
||||
|
||||
case 0x1d:
|
||||
speed = 400;
|
||||
break;
|
||||
|
||||
case 0x1f:
|
||||
speed = 266;
|
||||
break;
|
||||
}
|
||||
|
||||
if (speed)
|
||||
printf("%d MHz\n", speed);
|
||||
else
|
||||
puts("unknown revision\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_DISPLAY_CPUINFO */
|
||||
|
||||
int cleanup_before_linux (void)
|
||||
{
|
||||
/*
|
||||
* this function is called just before we call linux
|
||||
* it prepares the processor for linux
|
||||
*
|
||||
* just disable everything that can disturb booting linux
|
||||
*/
|
||||
|
||||
disable_interrupts ();
|
||||
|
||||
/* turn off I-cache */
|
||||
icache_disable();
|
||||
dcache_disable();
|
||||
|
||||
/* flush I-cache */
|
||||
cache_flush();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* flush I/D-cache */
|
||||
static void cache_flush (void)
|
||||
{
|
||||
unsigned long i = 0;
|
||||
|
||||
asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (i));
|
||||
}
|
||||
|
||||
/* FIXME */
|
||||
/*
|
||||
void pci_init(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
int cpu_eth_init(bd_t *bis)
|
||||
{
|
||||
#ifdef CONFIG_IXP4XX_NPE
|
||||
npe_initialize(bis);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2006
|
||||
* Stefan Roese, DENX Software Engineering, sr@denx.de.
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
* Marius Groeger <mgroeger@sysgo.de>
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
* Alex Zuepke <azu@sysgo.de>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/ixp425.h>
|
||||
#include <asm/proc-armv/ptrace.h>
|
||||
|
||||
struct _irq_handler {
|
||||
void *m_data;
|
||||
void (*m_func)( void *data);
|
||||
};
|
||||
|
||||
static struct _irq_handler IRQ_HANDLER[N_IRQS];
|
||||
|
||||
static void default_isr(void *data)
|
||||
{
|
||||
printf("default_isr(): called for IRQ %d, Interrupt Status=%x PR=%x\n",
|
||||
(int)data, *IXP425_ICIP, *IXP425_ICIH);
|
||||
}
|
||||
|
||||
static int next_irq(void)
|
||||
{
|
||||
return (((*IXP425_ICIH & 0x000000fc) >> 2) - 1);
|
||||
}
|
||||
|
||||
void do_irq (struct pt_regs *pt_regs)
|
||||
{
|
||||
int irq = next_irq();
|
||||
|
||||
IRQ_HANDLER[irq].m_func(IRQ_HANDLER[irq].m_data);
|
||||
}
|
||||
|
||||
void irq_install_handler (int irq, interrupt_handler_t handle_irq, void *data)
|
||||
{
|
||||
if (irq >= N_IRQS || !handle_irq)
|
||||
return;
|
||||
|
||||
IRQ_HANDLER[irq].m_data = data;
|
||||
IRQ_HANDLER[irq].m_func = handle_irq;
|
||||
}
|
||||
|
||||
int arch_interrupt_init (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* install default interrupt handlers */
|
||||
for (i = 0; i < N_IRQS; i++)
|
||||
irq_install_handler(i, default_isr, (void *)i);
|
||||
|
||||
/* configure interrupts for IRQ mode */
|
||||
*IXP425_ICLR = 0x00000000;
|
||||
|
||||
return (0);
|
||||
}
|
|
@ -1,430 +0,0 @@
|
|||
/* vi: set ts=8 sw=8 noet: */
|
||||
/*
|
||||
* u-boot - Startup Code for XScale IXP
|
||||
*
|
||||
* Copyright (C) 2003 Kyle Harris <kharris@nexus-tech.net>
|
||||
*
|
||||
* Based on startup code example contained in the
|
||||
* Intel IXP4xx Programmer's Guide and past u-boot Start.S
|
||||
* samples.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <asm-offsets.h>
|
||||
#include <config.h>
|
||||
#include <version.h>
|
||||
#include <asm/arch/ixp425.h>
|
||||
|
||||
#define MMU_Control_M 0x001 /* Enable MMU */
|
||||
#define MMU_Control_A 0x002 /* Enable address alignment faults */
|
||||
#define MMU_Control_C 0x004 /* Enable cache */
|
||||
#define MMU_Control_W 0x008 /* Enable write-buffer */
|
||||
#define MMU_Control_P 0x010 /* Compatability: 32 bit code */
|
||||
#define MMU_Control_D 0x020 /* Compatability: 32 bit data */
|
||||
#define MMU_Control_L 0x040 /* Compatability: */
|
||||
#define MMU_Control_B 0x080 /* Enable Big-Endian */
|
||||
#define MMU_Control_S 0x100 /* Enable system protection */
|
||||
#define MMU_Control_R 0x200 /* Enable ROM protection */
|
||||
#define MMU_Control_I 0x1000 /* Enable Instruction cache */
|
||||
#define MMU_Control_X 0x2000 /* Set interrupt vectors at 0xFFFF0000 */
|
||||
#define MMU_Control_Init (MMU_Control_P|MMU_Control_D|MMU_Control_L)
|
||||
|
||||
|
||||
/*
|
||||
* Macro definitions
|
||||
*/
|
||||
/* Delay a bit */
|
||||
.macro DELAY_FOR cycles, reg0
|
||||
ldr \reg0, =\cycles
|
||||
subs \reg0, \reg0, #1
|
||||
subne pc, pc, #0xc
|
||||
.endm
|
||||
|
||||
/* wait for coprocessor write complete */
|
||||
.macro CPWAIT reg
|
||||
mrc p15,0,\reg,c2,c0,0
|
||||
mov \reg,\reg
|
||||
sub pc,pc,#4
|
||||
.endm
|
||||
|
||||
.globl _start
|
||||
_start:
|
||||
ldr pc, _reset
|
||||
ldr pc, _undefined_instruction
|
||||
ldr pc, _software_interrupt
|
||||
ldr pc, _prefetch_abort
|
||||
ldr pc, _data_abort
|
||||
ldr pc, _not_used
|
||||
ldr pc, _irq
|
||||
ldr pc, _fiq
|
||||
|
||||
_reset: .word reset
|
||||
_undefined_instruction: .word undefined_instruction
|
||||
_software_interrupt: .word software_interrupt
|
||||
_prefetch_abort: .word prefetch_abort
|
||||
_data_abort: .word data_abort
|
||||
_not_used: .word not_used
|
||||
_irq: .word irq
|
||||
_fiq: .word fiq
|
||||
|
||||
.balignl 16,0xdeadbeef
|
||||
|
||||
|
||||
/*
|
||||
* Startup Code (reset vector)
|
||||
*
|
||||
* do important init only if we don't start from memory!
|
||||
* - relocate armboot to ram
|
||||
* - setup stack
|
||||
* - jump to second stage
|
||||
*/
|
||||
|
||||
.globl _TEXT_BASE
|
||||
_TEXT_BASE:
|
||||
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_TEXT_BASE)
|
||||
.word CONFIG_SPL_TEXT_BASE
|
||||
#else
|
||||
.word CONFIG_SYS_TEXT_BASE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* These are defined in the board-specific linker script.
|
||||
* Subtracting _start from them lets the linker put their
|
||||
* relative position in the executable instead of leaving
|
||||
* them null.
|
||||
*/
|
||||
.globl _bss_start_ofs
|
||||
_bss_start_ofs:
|
||||
.word __bss_start - _start
|
||||
|
||||
.globl _bss_end_ofs
|
||||
_bss_end_ofs:
|
||||
.word __bss_end - _start
|
||||
|
||||
.globl _end_ofs
|
||||
_end_ofs:
|
||||
.word _end - _start
|
||||
|
||||
#ifdef CONFIG_USE_IRQ
|
||||
/* IRQ stack memory (calculated at run-time) */
|
||||
.globl IRQ_STACK_START
|
||||
IRQ_STACK_START:
|
||||
.word 0x0badc0de
|
||||
|
||||
/* IRQ stack memory (calculated at run-time) */
|
||||
.globl FIQ_STACK_START
|
||||
FIQ_STACK_START:
|
||||
.word 0x0badc0de
|
||||
#endif
|
||||
|
||||
/* IRQ stack memory (calculated at run-time) + 8 bytes */
|
||||
.globl IRQ_STACK_START_IN
|
||||
IRQ_STACK_START_IN:
|
||||
.word 0x0badc0de
|
||||
|
||||
/*
|
||||
* the actual reset code
|
||||
*/
|
||||
|
||||
reset:
|
||||
/* disable mmu, set big-endian */
|
||||
mov r0, #0xf8
|
||||
mcr p15, 0, r0, c1, c0, 0
|
||||
CPWAIT r0
|
||||
|
||||
/* invalidate I & D caches & BTB */
|
||||
mcr p15, 0, r0, c7, c7, 0
|
||||
CPWAIT r0
|
||||
|
||||
/* invalidate I & Data TLB */
|
||||
mcr p15, 0, r0, c8, c7, 0
|
||||
CPWAIT r0
|
||||
|
||||
/* drain write and fill buffers */
|
||||
mcr p15, 0, r0, c7, c10, 4
|
||||
CPWAIT r0
|
||||
|
||||
/* disable write buffer coalescing */
|
||||
mrc p15, 0, r0, c1, c0, 1
|
||||
orr r0, r0, #1
|
||||
mcr p15, 0, r0, c1, c0, 1
|
||||
CPWAIT r0
|
||||
|
||||
/* set EXP CS0 to the optimum timing */
|
||||
ldr r1, =CONFIG_SYS_EXP_CS0
|
||||
ldr r2, =IXP425_EXP_CS0
|
||||
str r1, [r2]
|
||||
|
||||
/* make sure flash is visible at 0 */
|
||||
mov r1, #CONFIG_SYS_SDR_CONFIG
|
||||
ldr r2, =IXP425_SDR_CONFIG
|
||||
str r1, [r2]
|
||||
|
||||
/* disable refresh cycles */
|
||||
mov r1, #0
|
||||
ldr r3, =IXP425_SDR_REFRESH
|
||||
str r1, [r3]
|
||||
|
||||
/* send nop command */
|
||||
mov r1, #3
|
||||
ldr r4, =IXP425_SDR_IR
|
||||
str r1, [r4]
|
||||
DELAY_FOR 0x4000, r0
|
||||
|
||||
/* set SDRAM internal refresh val */
|
||||
ldr r1, =CONFIG_SYS_SDRAM_REFRESH_CNT
|
||||
str r1, [r3]
|
||||
DELAY_FOR 0x4000, r0
|
||||
|
||||
/* send precharge-all command to close all open banks */
|
||||
mov r1, #2
|
||||
str r1, [r4]
|
||||
DELAY_FOR 0x4000, r0
|
||||
|
||||
/* provide 8 auto-refresh cycles */
|
||||
mov r1, #4
|
||||
mov r5, #8
|
||||
111: str r1, [r4]
|
||||
DELAY_FOR 0x100, r0
|
||||
subs r5, r5, #1
|
||||
bne 111b
|
||||
|
||||
/* set mode register in sdram */
|
||||
mov r1, #CONFIG_SYS_SDR_MODE_CONFIG
|
||||
str r1, [r4]
|
||||
DELAY_FOR 0x4000, r0
|
||||
|
||||
/* send normal operation command */
|
||||
mov r1, #6
|
||||
str r1, [r4]
|
||||
DELAY_FOR 0x4000, r0
|
||||
|
||||
/* invalidate I & D caches & BTB */
|
||||
mcr p15, 0, r0, c7, c7, 0
|
||||
CPWAIT r0
|
||||
|
||||
/* invalidate I & Data TLB */
|
||||
mcr p15, 0, r0, c8, c7, 0
|
||||
CPWAIT r0
|
||||
|
||||
/* drain write and fill buffers */
|
||||
mcr p15, 0, r0, c7, c10, 4
|
||||
CPWAIT r0
|
||||
|
||||
/* remove flash mirror at 0x00000000 */
|
||||
ldr r2, =IXP425_EXP_CFG0
|
||||
ldr r1, [r2]
|
||||
bic r1, r1, #0x80000000
|
||||
str r1, [r2]
|
||||
|
||||
/* invalidate I & Data TLB */
|
||||
mcr p15, 0, r0, c8, c7, 0
|
||||
CPWAIT r0
|
||||
|
||||
/* enable I cache */
|
||||
mrc p15, 0, r0, c1, c0, 0
|
||||
orr r0, r0, #MMU_Control_I
|
||||
mcr p15, 0, r0, c1, c0, 0
|
||||
CPWAIT r0
|
||||
|
||||
mrs r0,cpsr /* set the cpu to SVC32 mode */
|
||||
bic r0,r0,#0x1f /* (superviser mode, M=10011) */
|
||||
orr r0,r0,#0x13
|
||||
msr cpsr,r0
|
||||
|
||||
bl _main
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
|
||||
.globl c_runtime_cpu_setup
|
||||
c_runtime_cpu_setup:
|
||||
|
||||
bx lr
|
||||
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* Interrupt handling */
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
|
||||
/* IRQ stack frame */
|
||||
|
||||
#define S_FRAME_SIZE 72
|
||||
|
||||
#define S_OLD_R0 68
|
||||
#define S_PSR 64
|
||||
#define S_PC 60
|
||||
#define S_LR 56
|
||||
#define S_SP 52
|
||||
|
||||
#define S_IP 48
|
||||
#define S_FP 44
|
||||
#define S_R10 40
|
||||
#define S_R9 36
|
||||
#define S_R8 32
|
||||
#define S_R7 28
|
||||
#define S_R6 24
|
||||
#define S_R5 20
|
||||
#define S_R4 16
|
||||
#define S_R3 12
|
||||
#define S_R2 8
|
||||
#define S_R1 4
|
||||
#define S_R0 0
|
||||
|
||||
#define MODE_SVC 0x13
|
||||
|
||||
/* use bad_save_user_regs for abort/prefetch/undef/swi ... */
|
||||
|
||||
.macro bad_save_user_regs
|
||||
sub sp, sp, #S_FRAME_SIZE
|
||||
stmia sp, {r0 - r12} /* Calling r0-r12 */
|
||||
add r8, sp, #S_PC
|
||||
|
||||
ldr r2, IRQ_STACK_START_IN
|
||||
ldmia r2, {r2 - r4} /* get pc, cpsr, old_r0 */
|
||||
add r0, sp, #S_FRAME_SIZE /* restore sp_SVC */
|
||||
|
||||
add r5, sp, #S_SP
|
||||
mov r1, lr
|
||||
stmia r5, {r0 - r4} /* save sp_SVC, lr_SVC, pc, cpsr, old_r */
|
||||
mov r0, sp
|
||||
.endm
|
||||
|
||||
|
||||
/* use irq_save_user_regs / irq_restore_user_regs for */
|
||||
/* IRQ/FIQ handling */
|
||||
|
||||
.macro irq_save_user_regs
|
||||
sub sp, sp, #S_FRAME_SIZE
|
||||
stmia sp, {r0 - r12} /* Calling r0-r12 */
|
||||
add r8, sp, #S_PC
|
||||
stmdb r8, {sp, lr}^ /* Calling SP, LR */
|
||||
str lr, [r8, #0] /* Save calling PC */
|
||||
mrs r6, spsr
|
||||
str r6, [r8, #4] /* Save CPSR */
|
||||
str r0, [r8, #8] /* Save OLD_R0 */
|
||||
mov r0, sp
|
||||
.endm
|
||||
|
||||
.macro irq_restore_user_regs
|
||||
ldmia sp, {r0 - lr}^ @ Calling r0 - lr
|
||||
mov r0, r0
|
||||
ldr lr, [sp, #S_PC] @ Get PC
|
||||
add sp, sp, #S_FRAME_SIZE
|
||||
subs pc, lr, #4 @ return & move spsr_svc into cpsr
|
||||
.endm
|
||||
|
||||
.macro get_bad_stack
|
||||
ldr r13, IRQ_STACK_START_IN @ setup our mode stack
|
||||
|
||||
str lr, [r13] @ save caller lr / spsr
|
||||
mrs lr, spsr
|
||||
str lr, [r13, #4]
|
||||
|
||||
mov r13, #MODE_SVC @ prepare SVC-Mode
|
||||
msr spsr_c, r13
|
||||
mov lr, pc
|
||||
movs pc, lr
|
||||
.endm
|
||||
|
||||
.macro get_irq_stack @ setup IRQ stack
|
||||
ldr sp, IRQ_STACK_START
|
||||
.endm
|
||||
|
||||
.macro get_fiq_stack @ setup FIQ stack
|
||||
ldr sp, FIQ_STACK_START
|
||||
.endm
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* exception handlers */
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
|
||||
.align 5
|
||||
undefined_instruction:
|
||||
get_bad_stack
|
||||
bad_save_user_regs
|
||||
bl do_undefined_instruction
|
||||
|
||||
.align 5
|
||||
software_interrupt:
|
||||
get_bad_stack
|
||||
bad_save_user_regs
|
||||
bl do_software_interrupt
|
||||
|
||||
.align 5
|
||||
prefetch_abort:
|
||||
get_bad_stack
|
||||
bad_save_user_regs
|
||||
bl do_prefetch_abort
|
||||
|
||||
.align 5
|
||||
data_abort:
|
||||
get_bad_stack
|
||||
bad_save_user_regs
|
||||
bl do_data_abort
|
||||
|
||||
.align 5
|
||||
not_used:
|
||||
get_bad_stack
|
||||
bad_save_user_regs
|
||||
bl do_not_used
|
||||
|
||||
#ifdef CONFIG_USE_IRQ
|
||||
|
||||
.align 5
|
||||
irq:
|
||||
get_irq_stack
|
||||
irq_save_user_regs
|
||||
bl do_irq
|
||||
irq_restore_user_regs
|
||||
|
||||
.align 5
|
||||
fiq:
|
||||
get_fiq_stack
|
||||
irq_save_user_regs /* someone ought to write a more */
|
||||
bl do_fiq /* effiction fiq_save_user_regs */
|
||||
irq_restore_user_regs
|
||||
|
||||
#else
|
||||
|
||||
.align 5
|
||||
irq:
|
||||
get_bad_stack
|
||||
bad_save_user_regs
|
||||
bl do_irq
|
||||
|
||||
.align 5
|
||||
fiq:
|
||||
get_bad_stack
|
||||
bad_save_user_regs
|
||||
bl do_fiq
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* Reset function: Use Watchdog to reset */
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
|
||||
.align 5
|
||||
.globl reset_cpu
|
||||
|
||||
reset_cpu:
|
||||
ldr r1, =0x482e
|
||||
ldr r2, =IXP425_OSWK
|
||||
str r1, [r2]
|
||||
ldr r1, =0x0fff
|
||||
ldr r2, =IXP425_OSWT
|
||||
str r1, [r2]
|
||||
ldr r1, =0x5
|
||||
ldr r2, =IXP425_OSWE
|
||||
str r1, [r2]
|
||||
b reset_endless
|
||||
|
||||
reset_endless:
|
||||
b reset_endless
|
|
@ -1,101 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2010
|
||||
* Michael Schwingen, michael@schwingen.org
|
||||
*
|
||||
* (C) Copyright 2006
|
||||
* Stefan Roese, DENX Software Engineering, sr@denx.de.
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
* Marius Groeger <mgroeger@sysgo.de>
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
* Alex Zuepke <azu@sysgo.de>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/ixp425.h>
|
||||
#include <asm/io.h>
|
||||
#include <div64.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/*
|
||||
* The IXP42x time-stamp timer runs at 2*OSC_IN (66.666MHz when using a
|
||||
* 33.333MHz crystal).
|
||||
*/
|
||||
static inline unsigned long long tick_to_time(unsigned long long tick)
|
||||
{
|
||||
tick *= CONFIG_SYS_HZ;
|
||||
do_div(tick, CONFIG_IXP425_TIMER_CLK);
|
||||
return tick;
|
||||
}
|
||||
|
||||
static inline unsigned long long time_to_tick(unsigned long long time)
|
||||
{
|
||||
time *= CONFIG_IXP425_TIMER_CLK;
|
||||
do_div(time, CONFIG_SYS_HZ);
|
||||
return time;
|
||||
}
|
||||
|
||||
static inline unsigned long long us_to_tick(unsigned long long us)
|
||||
{
|
||||
us = us * CONFIG_IXP425_TIMER_CLK + 999999;
|
||||
do_div(us, 1000000);
|
||||
return us;
|
||||
}
|
||||
|
||||
unsigned long long get_ticks(void)
|
||||
{
|
||||
ulong now = readl(IXP425_OSTS_B);
|
||||
|
||||
if (readl(IXP425_OSST) & IXP425_OSST_TIMER_TS_PEND) {
|
||||
/* rollover of timestamp timer register */
|
||||
gd->arch.timestamp += (0xFFFFFFFF - gd->arch.lastinc) + now + 1;
|
||||
writel(IXP425_OSST_TIMER_TS_PEND, IXP425_OSST);
|
||||
} else {
|
||||
/* move stamp forward with absolut diff ticks */
|
||||
gd->arch.timestamp += (now - gd->arch.lastinc);
|
||||
}
|
||||
gd->arch.lastinc = now;
|
||||
return gd->arch.timestamp;
|
||||
}
|
||||
|
||||
|
||||
void reset_timer_masked(void)
|
||||
{
|
||||
/* capture current timestamp counter */
|
||||
gd->arch.lastinc = readl(IXP425_OSTS_B);
|
||||
/* start "advancing" time stamp from 0 */
|
||||
gd->arch.timestamp = 0;
|
||||
}
|
||||
|
||||
ulong get_timer_masked(void)
|
||||
{
|
||||
return tick_to_time(get_ticks());
|
||||
}
|
||||
|
||||
ulong get_timer(ulong base)
|
||||
{
|
||||
return get_timer_masked() - base;
|
||||
}
|
||||
|
||||
/* delay x useconds AND preserve advance timestamp value */
|
||||
void __udelay(unsigned long usec)
|
||||
{
|
||||
unsigned long long tmp;
|
||||
|
||||
tmp = get_ticks() + us_to_tick(usec);
|
||||
|
||||
while (get_ticks() < tmp)
|
||||
;
|
||||
}
|
||||
|
||||
int timer_init(void)
|
||||
{
|
||||
writel(IXP425_OSST_TIMER_TS_PEND, IXP425_OSST);
|
||||
return 0;
|
||||
}
|
|
@ -1,91 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2000-2006
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
OUTPUT_FORMAT("elf32-bigarm", "elf32-bigarm", "elf32-bigarm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x00000000;
|
||||
|
||||
. = ALIGN(4);
|
||||
.text :
|
||||
{
|
||||
*(.__image_copy_start)
|
||||
arch/arm/cpu/ixp/start.o(.text*)
|
||||
*(.text*)
|
||||
}
|
||||
|
||||
. = ALIGN(4);
|
||||
.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
|
||||
|
||||
. = ALIGN(4);
|
||||
.data : {
|
||||
*(.data*)
|
||||
}
|
||||
|
||||
. = ALIGN(4);
|
||||
|
||||
. = .;
|
||||
|
||||
. = ALIGN(4);
|
||||
.u_boot_list : {
|
||||
KEEP(*(SORT(.u_boot_list*)));
|
||||
}
|
||||
|
||||
. = ALIGN(4);
|
||||
|
||||
.image_copy_end :
|
||||
{
|
||||
*(.__image_copy_end)
|
||||
}
|
||||
|
||||
.rel_dyn_start :
|
||||
{
|
||||
*(.__rel_dyn_start)
|
||||
}
|
||||
|
||||
.rel.dyn : {
|
||||
*(.rel*)
|
||||
}
|
||||
|
||||
.rel_dyn_end :
|
||||
{
|
||||
*(.__rel_dyn_end)
|
||||
}
|
||||
|
||||
_end = .;
|
||||
|
||||
/*
|
||||
* Compiler-generated __bss_start and __bss_end, see arch/arm/lib/bss.c
|
||||
* __bss_base and __bss_limit are for linker only (overlay ordering)
|
||||
*/
|
||||
|
||||
.bss_start __rel_dyn_start (OVERLAY) : {
|
||||
KEEP(*(.__bss_start));
|
||||
__bss_base = .;
|
||||
}
|
||||
|
||||
.bss __bss_base (OVERLAY) : {
|
||||
*(.bss*)
|
||||
. = ALIGN(4);
|
||||
__bss_limit = .;
|
||||
}
|
||||
.bss_end __bss_limit (OVERLAY) : {
|
||||
KEEP(*(.__bss_end));
|
||||
}
|
||||
|
||||
.dynsym _end : { *(.dynsym) }
|
||||
.dynbss : { *(.dynbss) }
|
||||
.dynstr : { *(.dynstr*) }
|
||||
.dynamic : { *(.dynamic*) }
|
||||
.hash : { *(.hash*) }
|
||||
.plt : { *(.plt*) }
|
||||
.interp : { *(.interp*) }
|
||||
.gnu : { *(.gnu*) }
|
||||
.ARM.exidx : { *(.ARM.exidx*) }
|
||||
}
|
|
@ -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:
|
||||
|
|
|
@ -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
|
|
@ -1,548 +0,0 @@
|
|||
/*
|
||||
* include/asm-arm/arch-ixp425/ixp425.h
|
||||
*
|
||||
* Register definitions for IXP425
|
||||
*
|
||||
* Copyright (C) 2002 Intel Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _ASM_ARM_IXP425_H_
|
||||
#define _ASM_ARM_IXP425_H_
|
||||
|
||||
#define BIT(x) (1<<(x))
|
||||
|
||||
/* FIXME: Only this does work for u-boot... find out why... [RS] */
|
||||
#define UBOOT_REG_FIX 1
|
||||
#ifdef UBOOT_REG_FIX
|
||||
# undef io_p2v
|
||||
# undef __REG
|
||||
# ifndef __ASSEMBLY__
|
||||
# define io_p2v(PhAdd) (PhAdd)
|
||||
# define __REG(x) (*((volatile u32 *)io_p2v(x)))
|
||||
# define __REG2(x,y) (*(volatile u32 *)((u32)&__REG(x) + (y)))
|
||||
# else
|
||||
# define __REG(x) (x)
|
||||
# endif
|
||||
#endif /* UBOOT_REG_FIX */
|
||||
|
||||
/*
|
||||
*
|
||||
* IXP425 Memory map:
|
||||
*
|
||||
* Phy Phy Size Map Size Virt Description
|
||||
* =========================================================================
|
||||
*
|
||||
* 0x00000000 0x10000000 SDRAM 1
|
||||
*
|
||||
* 0x10000000 0x10000000 SDRAM 2
|
||||
*
|
||||
* 0x20000000 0x10000000 SDRAM 3
|
||||
*
|
||||
* 0x30000000 0x10000000 SDRAM 4
|
||||
*
|
||||
* The above four are aliases to the same memory location (0x00000000)
|
||||
*
|
||||
* 0x48000000 0x4000000 PCI Memory
|
||||
*
|
||||
* 0x50000000 0x10000000 Not Mapped EXP BUS
|
||||
*
|
||||
* 0x6000000 0x00004000 0x4000 0xFFFEB000 QMgr
|
||||
*
|
||||
* 0xC0000000 0x100 0x1000 0xFFFDD000 PCI CFG
|
||||
*
|
||||
* 0xC4000000 0x100 0x1000 0xFFFDE000 EXP CFG
|
||||
*
|
||||
* 0xC8000000 0xC000 0xC000 0xFFFDF000 PERIPHERAL
|
||||
*
|
||||
* 0xCC000000 0x100 0x1000 Not Mapped SDRAM CFG
|
||||
*/
|
||||
|
||||
/*
|
||||
* SDRAM
|
||||
*/
|
||||
#define IXP425_SDRAM_BASE (0x00000000)
|
||||
#define IXP425_SDRAM_BASE_ALT (0x10000000)
|
||||
|
||||
|
||||
/*
|
||||
* PCI Configuration space
|
||||
*/
|
||||
#define IXP425_PCI_CFG_BASE_PHYS (0xC0000000)
|
||||
#define IXP425_PCI_CFG_REGION_SIZE (0x00001000)
|
||||
|
||||
/*
|
||||
* Expansion BUS Configuration registers
|
||||
*/
|
||||
#define IXP425_EXP_CFG_BASE_PHYS (0xC4000000)
|
||||
#define IXP425_EXP_CFG_REGION_SIZE (0x00001000)
|
||||
|
||||
/*
|
||||
* Peripheral space
|
||||
*/
|
||||
#define IXP425_PERIPHERAL_BASE_PHYS (0xC8000000)
|
||||
#define IXP425_PERIPHERAL_REGION_SIZE (0x0000C000)
|
||||
|
||||
/*
|
||||
* SDRAM configuration registers
|
||||
*/
|
||||
#define IXP425_SDRAM_CFG_BASE_PHYS (0xCC000000)
|
||||
|
||||
/*
|
||||
* Q Manager space .. not static mapped
|
||||
*/
|
||||
#define IXP425_QMGR_BASE_PHYS (0x60000000)
|
||||
#define IXP425_QMGR_REGION_SIZE (0x00004000)
|
||||
|
||||
/*
|
||||
* Expansion BUS
|
||||
*
|
||||
* Expansion Bus 'lives' at either base1 or base 2 depending on the value of
|
||||
* Exp Bus config registers:
|
||||
*
|
||||
* Setting bit 31 of IXP425_EXP_CFG0 puts SDRAM at zero,
|
||||
* and The expansion bus to IXP425_EXP_BUS_BASE2
|
||||
*/
|
||||
#define IXP425_EXP_BUS_BASE1_PHYS (0x00000000)
|
||||
#define IXP425_EXP_BUS_BASE2_PHYS (0x50000000)
|
||||
|
||||
#define IXP425_EXP_BUS_BASE_PHYS IXP425_EXP_BUS_BASE2_PHYS
|
||||
|
||||
#define IXP425_EXP_BUS_REGION_SIZE (0x08000000)
|
||||
#define IXP425_EXP_BUS_CSX_REGION_SIZE (0x01000000)
|
||||
|
||||
#define IXP425_EXP_BUS_CS0_BASE_PHYS (IXP425_EXP_BUS_BASE2_PHYS + 0x00000000)
|
||||
#define IXP425_EXP_BUS_CS1_BASE_PHYS (IXP425_EXP_BUS_BASE2_PHYS + 0x01000000)
|
||||
#define IXP425_EXP_BUS_CS2_BASE_PHYS (IXP425_EXP_BUS_BASE2_PHYS + 0x02000000)
|
||||
#define IXP425_EXP_BUS_CS3_BASE_PHYS (IXP425_EXP_BUS_BASE2_PHYS + 0x03000000)
|
||||
#define IXP425_EXP_BUS_CS4_BASE_PHYS (IXP425_EXP_BUS_BASE2_PHYS + 0x04000000)
|
||||
#define IXP425_EXP_BUS_CS5_BASE_PHYS (IXP425_EXP_BUS_BASE2_PHYS + 0x05000000)
|
||||
#define IXP425_EXP_BUS_CS6_BASE_PHYS (IXP425_EXP_BUS_BASE2_PHYS + 0x06000000)
|
||||
#define IXP425_EXP_BUS_CS7_BASE_PHYS (IXP425_EXP_BUS_BASE2_PHYS + 0x07000000)
|
||||
|
||||
#define IXP425_FLASH_WRITABLE (0x2)
|
||||
#define IXP425_FLASH_DEFAULT (0xbcd23c40)
|
||||
#define IXP425_FLASH_WRITE (0xbcd23c42)
|
||||
|
||||
#define IXP425_EXP_CS0_OFFSET 0x00
|
||||
#define IXP425_EXP_CS1_OFFSET 0x04
|
||||
#define IXP425_EXP_CS2_OFFSET 0x08
|
||||
#define IXP425_EXP_CS3_OFFSET 0x0C
|
||||
#define IXP425_EXP_CS4_OFFSET 0x10
|
||||
#define IXP425_EXP_CS5_OFFSET 0x14
|
||||
#define IXP425_EXP_CS6_OFFSET 0x18
|
||||
#define IXP425_EXP_CS7_OFFSET 0x1C
|
||||
#define IXP425_EXP_CFG0_OFFSET 0x20
|
||||
#define IXP425_EXP_CFG1_OFFSET 0x24
|
||||
#define IXP425_EXP_CFG2_OFFSET 0x28
|
||||
#define IXP425_EXP_CFG3_OFFSET 0x2C
|
||||
|
||||
/*
|
||||
* Expansion Bus Controller registers.
|
||||
*/
|
||||
#ifndef __ASSEMBLY__
|
||||
#define IXP425_EXP_REG(x) ((volatile u32 *)(IXP425_EXP_CFG_BASE_PHYS+(x)))
|
||||
#else
|
||||
#define IXP425_EXP_REG(x) (IXP425_EXP_CFG_BASE_PHYS+(x))
|
||||
#endif
|
||||
|
||||
#define IXP425_EXP_CS0 IXP425_EXP_REG(IXP425_EXP_CS0_OFFSET)
|
||||
#define IXP425_EXP_CS1 IXP425_EXP_REG(IXP425_EXP_CS1_OFFSET)
|
||||
#define IXP425_EXP_CS2 IXP425_EXP_REG(IXP425_EXP_CS2_OFFSET)
|
||||
#define IXP425_EXP_CS3 IXP425_EXP_REG(IXP425_EXP_CS3_OFFSET)
|
||||
#define IXP425_EXP_CS4 IXP425_EXP_REG(IXP425_EXP_CS4_OFFSET)
|
||||
#define IXP425_EXP_CS5 IXP425_EXP_REG(IXP425_EXP_CS5_OFFSET)
|
||||
#define IXP425_EXP_CS6 IXP425_EXP_REG(IXP425_EXP_CS6_OFFSET)
|
||||
#define IXP425_EXP_CS7 IXP425_EXP_REG(IXP425_EXP_CS7_OFFSET)
|
||||
|
||||
#define IXP425_EXP_CFG0 IXP425_EXP_REG(IXP425_EXP_CFG0_OFFSET)
|
||||
#define IXP425_EXP_CFG1 IXP425_EXP_REG(IXP425_EXP_CFG1_OFFSET)
|
||||
#define IXP425_EXP_CFG2 IXP425_EXP_REG(IXP425_EXP_CFG2_OFFSET)
|
||||
#define IXP425_EXP_CFG3 IXP425_EXP_REG(IXP425_EXP_CFG3_OFFSET)
|
||||
|
||||
/*
|
||||
* SDRAM Controller registers.
|
||||
*/
|
||||
#define IXP425_SDR_CONFIG_OFFSET 0x00
|
||||
#define IXP425_SDR_REFRESH_OFFSET 0x04
|
||||
#define IXP425_SDR_IR_OFFSET 0x08
|
||||
|
||||
#define IXP425_SDRAM_REG(x) (IXP425_SDRAM_CFG_BASE_PHYS+(x))
|
||||
|
||||
#define IXP425_SDR_CONFIG IXP425_SDRAM_REG(IXP425_SDR_CONFIG_OFFSET)
|
||||
#define IXP425_SDR_REFRESH IXP425_SDRAM_REG(IXP425_SDR_REFRESH_OFFSET)
|
||||
#define IXP425_SDR_IR IXP425_SDRAM_REG(IXP425_SDR_IR_OFFSET)
|
||||
|
||||
/*
|
||||
* UART registers
|
||||
*/
|
||||
#define IXP425_UART1 0
|
||||
#define IXP425_UART2 0x1000
|
||||
|
||||
#define IXP425_UART_RBR_OFFSET 0x00
|
||||
#define IXP425_UART_THR_OFFSET 0x00
|
||||
#define IXP425_UART_DLL_OFFSET 0x00
|
||||
#define IXP425_UART_IER_OFFSET 0x04
|
||||
#define IXP425_UART_DLH_OFFSET 0x04
|
||||
#define IXP425_UART_IIR_OFFSET 0x08
|
||||
#define IXP425_UART_FCR_OFFSET 0x00
|
||||
#define IXP425_UART_LCR_OFFSET 0x0c
|
||||
#define IXP425_UART_MCR_OFFSET 0x10
|
||||
#define IXP425_UART_LSR_OFFSET 0x14
|
||||
#define IXP425_UART_MSR_OFFSET 0x18
|
||||
#define IXP425_UART_SPR_OFFSET 0x1c
|
||||
#define IXP425_UART_ISR_OFFSET 0x20
|
||||
|
||||
#define IXP425_UART_CFG_BASE_PHYS (0xc8000000)
|
||||
|
||||
#define RBR(x) __REG(IXP425_UART_CFG_BASE_PHYS+(x)+IXP425_UART_RBR_OFFSET)
|
||||
#define THR(x) __REG(IXP425_UART_CFG_BASE_PHYS+(x)+IXP425_UART_THR_OFFSET)
|
||||
#define DLL(x) __REG(IXP425_UART_CFG_BASE_PHYS+(x)+IXP425_UART_DLL_OFFSET)
|
||||
#define IER(x) __REG(IXP425_UART_CFG_BASE_PHYS+(x)+IXP425_UART_IER_OFFSET)
|
||||
#define DLH(x) __REG(IXP425_UART_CFG_BASE_PHYS+(x)+IXP425_UART_DLH_OFFSET)
|
||||
#define IIR(x) __REG(IXP425_UART_CFG_BASE_PHYS+(x)+IXP425_UART_IIR_OFFSET)
|
||||
#define FCR(x) __REG(IXP425_UART_CFG_BASE_PHYS+(x)+IXP425_UART_FCR_OFFSET)
|
||||
#define LCR(x) __REG(IXP425_UART_CFG_BASE_PHYS+(x)+IXP425_UART_LCR_OFFSET)
|
||||
#define MCR(x) __REG(IXP425_UART_CFG_BASE_PHYS+(x)+IXP425_UART_MCR_OFFSET)
|
||||
#define LSR(x) __REG(IXP425_UART_CFG_BASE_PHYS+(x)+IXP425_UART_LSR_OFFSET)
|
||||
#define MSR(x) __REG(IXP425_UART_CFG_BASE_PHYS+(x)+IXP425_UART_MSR_OFFSET)
|
||||
#define SPR(x) __REG(IXP425_UART_CFG_BASE_PHYS+(x)+IXP425_UART_SPR_OFFSET)
|
||||
#define ISR(x) __REG(IXP425_UART_CFG_BASE_PHYS+(x)+IXP425_UART_ISR_OFFSET)
|
||||
|
||||
#define IER_DMAE (1 << 7) /* DMA Requests Enable */
|
||||
#define IER_UUE (1 << 6) /* UART Unit Enable */
|
||||
#define IER_NRZE (1 << 5) /* NRZ coding Enable */
|
||||
#define IER_RTIOE (1 << 4) /* Receiver Time Out Interrupt Enable */
|
||||
#define IER_MIE (1 << 3) /* Modem Interrupt Enable */
|
||||
#define IER_RLSE (1 << 2) /* Receiver Line Status Interrupt Enable */
|
||||
#define IER_TIE (1 << 1) /* Transmit Data request Interrupt Enable */
|
||||
#define IER_RAVIE (1 << 0) /* Receiver Data Available Interrupt Enable */
|
||||
|
||||
#define IIR_FIFOES1 (1 << 7) /* FIFO Mode Enable Status */
|
||||
#define IIR_FIFOES0 (1 << 6) /* FIFO Mode Enable Status */
|
||||
#define IIR_TOD (1 << 3) /* Time Out Detected */
|
||||
#define IIR_IID2 (1 << 2) /* Interrupt Source Encoded */
|
||||
#define IIR_IID1 (1 << 1) /* Interrupt Source Encoded */
|
||||
#define IIR_IP (1 << 0) /* Interrupt Pending (active low) */
|
||||
|
||||
#define FCR_ITL2 (1 << 7) /* Interrupt Trigger Level */
|
||||
#define FCR_ITL1 (1 << 6) /* Interrupt Trigger Level */
|
||||
#define FCR_RESETTF (1 << 2) /* Reset Transmitter FIFO */
|
||||
#define FCR_RESETRF (1 << 1) /* Reset Receiver FIFO */
|
||||
#define FCR_TRFIFOE (1 << 0) /* Transmit and Receive FIFO Enable */
|
||||
#define FCR_ITL_1 (0)
|
||||
#define FCR_ITL_8 (FCR_ITL1)
|
||||
#define FCR_ITL_16 (FCR_ITL2)
|
||||
#define FCR_ITL_32 (FCR_ITL2|FCR_ITL1)
|
||||
|
||||
#define LCR_DLAB (1 << 7) /* Divisor Latch Access Bit */
|
||||
#define LCR_SB (1 << 6) /* Set Break */
|
||||
#define LCR_STKYP (1 << 5) /* Sticky Parity */
|
||||
#define LCR_EPS (1 << 4) /* Even Parity Select */
|
||||
#define LCR_PEN (1 << 3) /* Parity Enable */
|
||||
#define LCR_STB (1 << 2) /* Stop Bit */
|
||||
#define LCR_WLS1 (1 << 1) /* Word Length Select */
|
||||
#define LCR_WLS0 (1 << 0) /* Word Length Select */
|
||||
|
||||
#define LSR_FIFOE (1 << 7) /* FIFO Error Status */
|
||||
#define LSR_TEMT (1 << 6) /* Transmitter Empty */
|
||||
#define LSR_TDRQ (1 << 5) /* Transmit Data Request */
|
||||
#define LSR_BI (1 << 4) /* Break Interrupt */
|
||||
#define LSR_FE (1 << 3) /* Framing Error */
|
||||
#define LSR_PE (1 << 2) /* Parity Error */
|
||||
#define LSR_OE (1 << 1) /* Overrun Error */
|
||||
#define LSR_DR (1 << 0) /* Data Ready */
|
||||
|
||||
#define MCR_LOOP (1 << 4) */
|
||||
#define MCR_OUT2 (1 << 3) /* force MSR_DCD in loopback mode */
|
||||
#define MCR_OUT1 (1 << 2) /* force MSR_RI in loopback mode */
|
||||
#define MCR_RTS (1 << 1) /* Request to Send */
|
||||
#define MCR_DTR (1 << 0) /* Data Terminal Ready */
|
||||
|
||||
#define MSR_DCD (1 << 7) /* Data Carrier Detect */
|
||||
#define MSR_RI (1 << 6) /* Ring Indicator */
|
||||
#define MSR_DSR (1 << 5) /* Data Set Ready */
|
||||
#define MSR_CTS (1 << 4) /* Clear To Send */
|
||||
#define MSR_DDCD (1 << 3) /* Delta Data Carrier Detect */
|
||||
#define MSR_TERI (1 << 2) /* Trailing Edge Ring Indicator */
|
||||
#define MSR_DDSR (1 << 1) /* Delta Data Set Ready */
|
||||
#define MSR_DCTS (1 << 0) /* Delta Clear To Send */
|
||||
|
||||
#define IXP425_CONSOLE_UART_BASE_PHYS IXP425_UART1_BASE_PHYS
|
||||
/*
|
||||
* Peripheral Space Registers
|
||||
*/
|
||||
#define IXP425_UART1_BASE_PHYS (IXP425_PERIPHERAL_BASE_PHYS + 0x0000)
|
||||
#define IXP425_UART2_BASE_PHYS (IXP425_PERIPHERAL_BASE_PHYS + 0x1000)
|
||||
#define IXP425_PMU_BASE_PHYS (IXP425_PERIPHERAL_BASE_PHYS + 0x2000)
|
||||
#define IXP425_INTC_BASE_PHYS (IXP425_PERIPHERAL_BASE_PHYS + 0x3000)
|
||||
#define IXP425_GPIO_BASE_PHYS (IXP425_PERIPHERAL_BASE_PHYS + 0x4000)
|
||||
#define IXP425_TIMER_BASE_PHYS (IXP425_PERIPHERAL_BASE_PHYS + 0x5000)
|
||||
#define IXP425_NPEA_BASE_PHYS (IXP425_PERIPHERAL_BASE_PHYS + 0x6000)
|
||||
#define IXP425_NPEB_BASE_PHYS (IXP425_PERIPHERAL_BASE_PHYS + 0x7000)
|
||||
#define IXP425_NPEC_BASE_PHYS (IXP425_PERIPHERAL_BASE_PHYS + 0x8000)
|
||||
#define IXP425_EthA_BASE_PHYS (IXP425_PERIPHERAL_BASE_PHYS + 0x9000)
|
||||
#define IXP425_EthB_BASE_PHYS (IXP425_PERIPHERAL_BASE_PHYS + 0xA000)
|
||||
#define IXP425_USB_BASE_PHYS (IXP425_PERIPHERAL_BASE_PHYS + 0xB000)
|
||||
|
||||
/*
|
||||
* UART Register Definitions , Offsets only as there are 2 UARTS.
|
||||
* IXP425_UART1_BASE , IXP425_UART2_BASE.
|
||||
*/
|
||||
|
||||
#undef UART_NO_RX_INTERRUPT
|
||||
|
||||
#define IXP425_UART_XTAL 14745600
|
||||
|
||||
/*
|
||||
* Constants to make it easy to access Interrupt Controller registers
|
||||
*/
|
||||
#define IXP425_ICPR_OFFSET 0x00 /* Interrupt Status */
|
||||
#define IXP425_ICMR_OFFSET 0x04 /* Interrupt Enable */
|
||||
#define IXP425_ICLR_OFFSET 0x08 /* Interrupt IRQ/FIQ Select */
|
||||
#define IXP425_ICIP_OFFSET 0x0C /* IRQ Status */
|
||||
#define IXP425_ICFP_OFFSET 0x10 /* FIQ Status */
|
||||
#define IXP425_ICHR_OFFSET 0x14 /* Interrupt Priority */
|
||||
#define IXP425_ICIH_OFFSET 0x18 /* IRQ Highest Pri Int */
|
||||
#define IXP425_ICFH_OFFSET 0x1C /* FIQ Highest Pri Int */
|
||||
|
||||
#define N_IRQS 32
|
||||
#define IXP425_TIMER_2_IRQ 11
|
||||
|
||||
/*
|
||||
* Interrupt Controller Register Definitions.
|
||||
*/
|
||||
#ifndef __ASSEMBLY__
|
||||
#define IXP425_INTC_REG(x) ((volatile u32 *)(IXP425_INTC_BASE_PHYS+(x)))
|
||||
#else
|
||||
#define IXP425_INTC_REG(x) (IXP425_INTC_BASE_PHYS+(x))
|
||||
#endif
|
||||
|
||||
#define IXP425_ICPR IXP425_INTC_REG(IXP425_ICPR_OFFSET)
|
||||
#define IXP425_ICMR IXP425_INTC_REG(IXP425_ICMR_OFFSET)
|
||||
#define IXP425_ICLR IXP425_INTC_REG(IXP425_ICLR_OFFSET)
|
||||
#define IXP425_ICIP IXP425_INTC_REG(IXP425_ICIP_OFFSET)
|
||||
#define IXP425_ICFP IXP425_INTC_REG(IXP425_ICFP_OFFSET)
|
||||
#define IXP425_ICHR IXP425_INTC_REG(IXP425_ICHR_OFFSET)
|
||||
#define IXP425_ICIH IXP425_INTC_REG(IXP425_ICIH_OFFSET)
|
||||
#define IXP425_ICFH IXP425_INTC_REG(IXP425_ICFH_OFFSET)
|
||||
|
||||
/*
|
||||
* Constants to make it easy to access GPIO registers
|
||||
*/
|
||||
#define IXP425_GPIO_GPOUTR_OFFSET 0x00
|
||||
#define IXP425_GPIO_GPOER_OFFSET 0x04
|
||||
#define IXP425_GPIO_GPINR_OFFSET 0x08
|
||||
#define IXP425_GPIO_GPISR_OFFSET 0x0C
|
||||
#define IXP425_GPIO_GPIT1R_OFFSET 0x10
|
||||
#define IXP425_GPIO_GPIT2R_OFFSET 0x14
|
||||
#define IXP425_GPIO_GPCLKR_OFFSET 0x18
|
||||
#define IXP425_GPIO_GPDBSELR_OFFSET 0x1C
|
||||
|
||||
/*
|
||||
* GPIO Register Definitions.
|
||||
* [Only perform 32bit reads/writes]
|
||||
*/
|
||||
#define IXP425_GPIO_REG(x) ((volatile u32 *)(IXP425_GPIO_BASE_PHYS+(x)))
|
||||
|
||||
#define IXP425_GPIO_GPOUTR IXP425_GPIO_REG(IXP425_GPIO_GPOUTR_OFFSET)
|
||||
#define IXP425_GPIO_GPOER IXP425_GPIO_REG(IXP425_GPIO_GPOER_OFFSET)
|
||||
#define IXP425_GPIO_GPINR IXP425_GPIO_REG(IXP425_GPIO_GPINR_OFFSET)
|
||||
#define IXP425_GPIO_GPISR IXP425_GPIO_REG(IXP425_GPIO_GPISR_OFFSET)
|
||||
#define IXP425_GPIO_GPIT1R IXP425_GPIO_REG(IXP425_GPIO_GPIT1R_OFFSET)
|
||||
#define IXP425_GPIO_GPIT2R IXP425_GPIO_REG(IXP425_GPIO_GPIT2R_OFFSET)
|
||||
#define IXP425_GPIO_GPCLKR IXP425_GPIO_REG(IXP425_GPIO_GPCLKR_OFFSET)
|
||||
#define IXP425_GPIO_GPDBSELR IXP425_GPIO_REG(IXP425_GPIO_GPDBSELR_OFFSET)
|
||||
|
||||
#define IXP425_GPIO_GPITR(line) (((line) >= 8) ? \
|
||||
IXP425_GPIO_GPIT2R : IXP425_GPIO_GPIT1R)
|
||||
|
||||
/*
|
||||
* Macros to make it easy to access the GPIO registers
|
||||
*/
|
||||
#define GPIO_OUTPUT_ENABLE(line) *IXP425_GPIO_GPOER &= ~(1 << (line))
|
||||
#define GPIO_OUTPUT_DISABLE(line) *IXP425_GPIO_GPOER |= (1 << (line))
|
||||
#define GPIO_OUTPUT_SET(line) *IXP425_GPIO_GPOUTR |= (1 << (line))
|
||||
#define GPIO_OUTPUT_CLEAR(line) *IXP425_GPIO_GPOUTR &= ~(1 << (line))
|
||||
#define GPIO_INT_ACT_LOW_SET(line) \
|
||||
*IXP425_GPIO_GPITR(line) = \
|
||||
(*IXP425_GPIO_GPITR(line) & \
|
||||
~(0x7 << (((line) & 0x7) * 3))) | \
|
||||
(0x1 << (((line) & 0x7) * 3)) \
|
||||
|
||||
/*
|
||||
* Constants to make it easy to access Timer Control/Status registers
|
||||
*/
|
||||
#define IXP425_OSTS_OFFSET 0x00 /* Continious TimeStamp */
|
||||
#define IXP425_OST1_OFFSET 0x04 /* Timer 1 Timestamp */
|
||||
#define IXP425_OSRT1_OFFSET 0x08 /* Timer 1 Reload */
|
||||
#define IXP425_OST2_OFFSET 0x0C /* Timer 2 Timestamp */
|
||||
#define IXP425_OSRT2_OFFSET 0x10 /* Timer 2 Reload */
|
||||
#define IXP425_OSWT_OFFSET 0x14 /* Watchdog Timer */
|
||||
#define IXP425_OSWE_OFFSET 0x18 /* Watchdog Enable */
|
||||
#define IXP425_OSWK_OFFSET 0x1C /* Watchdog Key */
|
||||
#define IXP425_OSST_OFFSET 0x20 /* Timer Status */
|
||||
|
||||
/*
|
||||
* Operating System Timer Register Definitions.
|
||||
*/
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#define IXP425_TIMER_REG(x) ((volatile u32 *)(IXP425_TIMER_BASE_PHYS+(x)))
|
||||
#else
|
||||
#define IXP425_TIMER_REG(x) (IXP425_TIMER_BASE_PHYS+(x))
|
||||
#endif
|
||||
|
||||
/* _B to avoid collision: also defined in npe/include/... */
|
||||
#define IXP425_OSTS_B IXP425_TIMER_REG(IXP425_OSTS_OFFSET)
|
||||
#define IXP425_OST1 IXP425_TIMER_REG(IXP425_OST1_OFFSET)
|
||||
#define IXP425_OSRT1 IXP425_TIMER_REG(IXP425_OSRT1_OFFSET)
|
||||
#define IXP425_OST2 IXP425_TIMER_REG(IXP425_OST2_OFFSET)
|
||||
#define IXP425_OSRT2 IXP425_TIMER_REG(IXP425_OSRT2_OFFSET)
|
||||
#define IXP425_OSWT IXP425_TIMER_REG(IXP425_OSWT_OFFSET)
|
||||
#define IXP425_OSWE IXP425_TIMER_REG(IXP425_OSWE_OFFSET)
|
||||
#define IXP425_OSWK IXP425_TIMER_REG(IXP425_OSWK_OFFSET)
|
||||
#define IXP425_OSST IXP425_TIMER_REG(IXP425_OSST_OFFSET)
|
||||
|
||||
/*
|
||||
* Timer register values and bit definitions
|
||||
*/
|
||||
#define IXP425_OST_ENABLE BIT(0)
|
||||
#define IXP425_OST_ONE_SHOT BIT(1)
|
||||
/* Low order bits of reload value ignored */
|
||||
#define IXP425_OST_RELOAD_MASK (0x3)
|
||||
#define IXP425_OST_DISABLED (0x0)
|
||||
#define IXP425_OSST_TIMER_1_PEND BIT(0)
|
||||
#define IXP425_OSST_TIMER_2_PEND BIT(1)
|
||||
#define IXP425_OSST_TIMER_TS_PEND BIT(2)
|
||||
#define IXP425_OSST_TIMER_WDOG_PEND BIT(3)
|
||||
#define IXP425_OSST_TIMER_WARM_RESET BIT(4)
|
||||
|
||||
/*
|
||||
* Constants to make it easy to access PCI Control/Status registers
|
||||
*/
|
||||
#define PCI_NP_AD_OFFSET 0x00
|
||||
#define PCI_NP_CBE_OFFSET 0x04
|
||||
#define PCI_NP_WDATA_OFFSET 0x08
|
||||
#define PCI_NP_RDATA_OFFSET 0x0c
|
||||
#define PCI_CRP_AD_CBE_OFFSET 0x10
|
||||
#define PCI_CRP_WDATA_OFFSET 0x14
|
||||
#define PCI_CRP_RDATA_OFFSET 0x18
|
||||
#define PCI_CSR_OFFSET 0x1c
|
||||
#define PCI_ISR_OFFSET 0x20
|
||||
#define PCI_INTEN_OFFSET 0x24
|
||||
#define PCI_DMACTRL_OFFSET 0x28
|
||||
#define PCI_AHBMEMBASE_OFFSET 0x2c
|
||||
#define PCI_AHBIOBASE_OFFSET 0x30
|
||||
#define PCI_PCIMEMBASE_OFFSET 0x34
|
||||
#define PCI_AHBDOORBELL_OFFSET 0x38
|
||||
#define PCI_PCIDOORBELL_OFFSET 0x3C
|
||||
#define PCI_ATPDMA0_AHBADDR_OFFSET 0x40
|
||||
#define PCI_ATPDMA0_PCIADDR_OFFSET 0x44
|
||||
#define PCI_ATPDMA0_LENADDR_OFFSET 0x48
|
||||
#define PCI_ATPDMA1_AHBADDR_OFFSET 0x4C
|
||||
#define PCI_ATPDMA1_PCIADDR_OFFSET 0x50
|
||||
#define PCI_ATPDMA1_LENADDR_OFFSET 0x54
|
||||
|
||||
/*
|
||||
* PCI Control/Status Registers
|
||||
*/
|
||||
#define IXP425_PCI_CSR(x) ((volatile u32 *)(IXP425_PCI_CFG_BASE_PHYS+(x)))
|
||||
|
||||
#define PCI_NP_AD IXP425_PCI_CSR(PCI_NP_AD_OFFSET)
|
||||
#define PCI_NP_CBE IXP425_PCI_CSR(PCI_NP_CBE_OFFSET)
|
||||
#define PCI_NP_WDATA IXP425_PCI_CSR(PCI_NP_WDATA_OFFSET)
|
||||
#define PCI_NP_RDATA IXP425_PCI_CSR(PCI_NP_RDATA_OFFSET)
|
||||
#define PCI_CRP_AD_CBE IXP425_PCI_CSR(PCI_CRP_AD_CBE_OFFSET)
|
||||
#define PCI_CRP_WDATA IXP425_PCI_CSR(PCI_CRP_WDATA_OFFSET)
|
||||
#define PCI_CRP_RDATA IXP425_PCI_CSR(PCI_CRP_RDATA_OFFSET)
|
||||
#define PCI_CSR IXP425_PCI_CSR(PCI_CSR_OFFSET)
|
||||
#define PCI_ISR IXP425_PCI_CSR(PCI_ISR_OFFSET)
|
||||
#define PCI_INTEN IXP425_PCI_CSR(PCI_INTEN_OFFSET)
|
||||
#define PCI_DMACTRL IXP425_PCI_CSR(PCI_DMACTRL_OFFSET)
|
||||
#define PCI_AHBMEMBASE IXP425_PCI_CSR(PCI_AHBMEMBASE_OFFSET)
|
||||
#define PCI_AHBIOBASE IXP425_PCI_CSR(PCI_AHBIOBASE_OFFSET)
|
||||
#define PCI_PCIMEMBASE IXP425_PCI_CSR(PCI_PCIMEMBASE_OFFSET)
|
||||
#define PCI_AHBDOORBELL IXP425_PCI_CSR(PCI_AHBDOORBELL_OFFSET)
|
||||
#define PCI_PCIDOORBELL IXP425_PCI_CSR(PCI_PCIDOORBELL_OFFSET)
|
||||
#define PCI_ATPDMA0_AHBADDR IXP425_PCI_CSR(PCI_ATPDMA0_AHBADDR_OFFSET)
|
||||
#define PCI_ATPDMA0_PCIADDR IXP425_PCI_CSR(PCI_ATPDMA0_PCIADDR_OFFSET)
|
||||
#define PCI_ATPDMA0_LENADDR IXP425_PCI_CSR(PCI_ATPDMA0_LENADDR_OFFSET)
|
||||
#define PCI_ATPDMA1_AHBADDR IXP425_PCI_CSR(PCI_ATPDMA1_AHBADDR_OFFSET)
|
||||
#define PCI_ATPDMA1_PCIADDR IXP425_PCI_CSR(PCI_ATPDMA1_PCIADDR_OFFSET)
|
||||
#define PCI_ATPDMA1_LENADDR IXP425_PCI_CSR(PCI_ATPDMA1_LENADDR_OFFSET)
|
||||
|
||||
/*
|
||||
* PCI register values and bit definitions
|
||||
*/
|
||||
|
||||
/* CSR bit definitions */
|
||||
#define PCI_CSR_HOST BIT(0)
|
||||
#define PCI_CSR_ARBEN BIT(1)
|
||||
#define PCI_CSR_ADS BIT(2)
|
||||
#define PCI_CSR_PDS BIT(3)
|
||||
#define PCI_CSR_ABE BIT(4)
|
||||
#define PCI_CSR_DBT BIT(5)
|
||||
#define PCI_CSR_ASE BIT(8)
|
||||
#define PCI_CSR_IC BIT(15)
|
||||
|
||||
/* ISR (Interrupt status) Register bit definitions */
|
||||
#define PCI_ISR_PSE BIT(0)
|
||||
#define PCI_ISR_PFE BIT(1)
|
||||
#define PCI_ISR_PPE BIT(2)
|
||||
#define PCI_ISR_AHBE BIT(3)
|
||||
#define PCI_ISR_APDC BIT(4)
|
||||
#define PCI_ISR_PADC BIT(5)
|
||||
#define PCI_ISR_ADB BIT(6)
|
||||
#define PCI_ISR_PDB BIT(7)
|
||||
|
||||
/* INTEN (Interrupt Enable) Register bit definitions */
|
||||
#define PCI_INTEN_PSE BIT(0)
|
||||
#define PCI_INTEN_PFE BIT(1)
|
||||
#define PCI_INTEN_PPE BIT(2)
|
||||
#define PCI_INTEN_AHBE BIT(3)
|
||||
#define PCI_INTEN_APDC BIT(4)
|
||||
#define PCI_INTEN_PADC BIT(5)
|
||||
#define PCI_INTEN_ADB BIT(6)
|
||||
#define PCI_INTEN_PDB BIT(7)
|
||||
|
||||
/*
|
||||
* Shift value for byte enable on NP cmd/byte enable register
|
||||
*/
|
||||
#define IXP425_PCI_NP_CBE_BESL 4
|
||||
|
||||
/*
|
||||
* PCI commands supported by NP access unit
|
||||
*/
|
||||
#define NP_CMD_IOREAD 0x2
|
||||
#define NP_CMD_IOWRITE 0x3
|
||||
#define NP_CMD_CONFIGREAD 0xa
|
||||
#define NP_CMD_CONFIGWRITE 0xb
|
||||
#define NP_CMD_MEMREAD 0x6
|
||||
#define NP_CMD_MEMWRITE 0x7
|
||||
|
||||
#if 0
|
||||
#ifndef __ASSEMBLY__
|
||||
extern int ixp425_pci_read(u32 addr, u32 cmd, u32* data);
|
||||
extern int ixp425_pci_write(u32 addr, u32 cmd, u32 data);
|
||||
extern void ixp425_pci_init(void *);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Constants for CRP access into local config space
|
||||
*/
|
||||
#define CRP_AD_CBE_BESL 20
|
||||
#define CRP_AD_CBE_WRITE BIT(16)
|
||||
|
||||
/*
|
||||
* Clock Speed Definitions.
|
||||
*/
|
||||
#define IXP425_PERIPHERAL_BUS_CLOCK (66) /* 66Mhzi APB BUS */
|
||||
|
||||
|
||||
#endif
|
|
@ -1,174 +0,0 @@
|
|||
/*
|
||||
* IXP PCI Init
|
||||
* (C) Copyright 2004 eslab.whut.edu.cn
|
||||
* Yue Hu(huyue_whut@yahoo.com.cn), Ligong Xue(lgxue@hotmail.com)
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef _IXP425PCI_H
|
||||
#define _IXP425PCI_H
|
||||
|
||||
#define OK 0
|
||||
#define ERROR -1
|
||||
|
||||
struct pci_controller;
|
||||
extern void pci_ixp_init(struct pci_controller *hose);
|
||||
|
||||
/* Mask definitions*/
|
||||
#define IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK 0x0000000f
|
||||
|
||||
#define PCI_NP_CBE_BESL (4)
|
||||
#define PCI_NP_AD_FUNCSL (8)
|
||||
|
||||
/*Register addressing definitions for PCI controller configuration
|
||||
and status registers*/
|
||||
|
||||
#define PCI_CSR_BASE (0xC0000000)
|
||||
/*
|
||||
#define PCI_NP_AD_OFFSET (0x00)
|
||||
#define PCI_NP_CBE_OFFSET (0x04)
|
||||
#define PCI_NP_WDATA_OFFSET (0x08)
|
||||
#define PCI_NP_RDATA_OFFSET (0x0C)
|
||||
#define PCI_CRP_OFFSET (0x10)
|
||||
#define PCI_CRP_WDATA_OFFSET (0x14)
|
||||
#define PCI_CRP_RDATA_OFFSET (0x18)
|
||||
#define PCI_CSR_OFFSET (0x1C)
|
||||
#define PCI_ISR_OFFSET (0x20)
|
||||
#define PCI_INTEN_OFFSET (0x24)
|
||||
#define PCI_DMACTRL_OFFSET (0x28)
|
||||
#define PCI_AHBMEMBASE_OFFSET (0x2C)
|
||||
#define PCI_AHBIOBASE_OFFSET (0x30)
|
||||
#define PCI_PCIMEMBASE_OFFSET (0x34)
|
||||
#define PCI_AHBDOORBELL_OFFSET (0x38)
|
||||
#define PCI_PCIDOORBELL_OFFSET (0x3C)
|
||||
#define PCI_ATPDMA0_AHBADDR (0x40)
|
||||
#define PCI_ATPDMA0_PCIADDR (0x44)
|
||||
#define PCI_ATPDMA0_LENADDR (0x48)
|
||||
#define PCI_ATPDMA1_AHBADDR (0x4C)
|
||||
#define PCI_ATPDMA1_PCIADDR (0x50)
|
||||
#define PCI_ATPDMA1_LENADDR (0x54)
|
||||
#define PCI_PTADMA0_AHBADDR (0x58)
|
||||
#define PCI_PTADMA0_PCIADDR (0x5C)
|
||||
#define PCI_PTADMA0_LENADDR (0x60)
|
||||
#define PCI_PTADMA1_AHBADDR (0x64)
|
||||
#define PCI_PTADMA1_PCIADDR (0x68)
|
||||
#define PCI_PTADMA1_LENADDR (0x6C)
|
||||
*/
|
||||
/*Non prefetch registers bit definitions*/
|
||||
/*
|
||||
#define NP_CMD_INTACK (0x0)
|
||||
#define NP_CMD_SPECIAL (0x1)
|
||||
#define NP_CMD_IOREAD (0x2)
|
||||
#define NP_CMD_IOWRITE (0x3)
|
||||
#define NP_CMD_MEMREAD (0x6)
|
||||
#define NP_CMD_MEMWRITE (0x7)
|
||||
#define NP_CMD_CONFIGREAD (0xa)
|
||||
#define NP_CMD_CONFIGWRITE (0xb)
|
||||
*/
|
||||
|
||||
/*Configuration Port register bit definitions*/
|
||||
#define PCI_CRP_WRITE BIT(16)
|
||||
|
||||
/*ISR (Interrupt status) Register bit definitions*/
|
||||
#define PCI_ISR_PSE BIT(0)
|
||||
#define PCI_ISR_PFE BIT(1)
|
||||
#define PCI_ISR_PPE BIT(2)
|
||||
#define PCI_ISR_AHBE BIT(3)
|
||||
#define PCI_ISR_APDC BIT(4)
|
||||
#define PCI_ISR_PADC BIT(5)
|
||||
#define PCI_ISR_ADB BIT(6)
|
||||
#define PCI_ISR_PDB BIT(7)
|
||||
|
||||
/*INTEN (Interrupt Enable) Register bit definitions*/
|
||||
#define PCI_INTEN_PSE BIT(0)
|
||||
#define PCI_INTEN_PFE BIT(1)
|
||||
#define PCI_INTEN_PPE BIT(2)
|
||||
#define PCI_INTEN_AHBE BIT(3)
|
||||
#define PCI_INTEN_APDC BIT(4)
|
||||
#define PCI_INTEN_PADC BIT(5)
|
||||
#define PCI_INTEN_ADB BIT(6)
|
||||
#define PCI_INTEN_PDB BIT(7)
|
||||
|
||||
/*PCI configuration regs.*/
|
||||
|
||||
#define PCI_CFG_VENDOR_ID 0x00
|
||||
#define PCI_CFG_DEVICE_ID 0x02
|
||||
#define PCI_CFG_COMMAND 0x04
|
||||
#define PCI_CFG_STATUS 0x06
|
||||
#define PCI_CFG_REVISION 0x08
|
||||
#define PCI_CFG_PROGRAMMING_IF 0x09
|
||||
#define PCI_CFG_SUBCLASS 0x0a
|
||||
#define PCI_CFG_CLASS 0x0b
|
||||
#define PCI_CFG_CACHE_LINE_SIZE 0x0c
|
||||
#define PCI_CFG_LATENCY_TIMER 0x0d
|
||||
#define PCI_CFG_HEADER_TYPE 0x0e
|
||||
#define PCI_CFG_BIST 0x0f
|
||||
#define PCI_CFG_BASE_ADDRESS_0 0x10
|
||||
#define PCI_CFG_BASE_ADDRESS_1 0x14
|
||||
#define PCI_CFG_BASE_ADDRESS_2 0x18
|
||||
#define PCI_CFG_BASE_ADDRESS_3 0x1c
|
||||
#define PCI_CFG_BASE_ADDRESS_4 0x20
|
||||
#define PCI_CFG_BASE_ADDRESS_5 0x24
|
||||
#define PCI_CFG_CIS 0x28
|
||||
#define PCI_CFG_SUB_VENDOR_ID 0x2c
|
||||
#define PCI_CFG_SUB_SYSTEM_ID 0x2e
|
||||
#define PCI_CFG_EXPANSION_ROM 0x30
|
||||
#define PCI_CFG_RESERVED_0 0x34
|
||||
#define PCI_CFG_RESERVED_1 0x38
|
||||
#define PCI_CFG_DEV_INT_LINE 0x3c
|
||||
#define PCI_CFG_DEV_INT_PIN 0x3d
|
||||
#define PCI_CFG_MIN_GRANT 0x3e
|
||||
#define PCI_CFG_MAX_LATENCY 0x3f
|
||||
#define PCI_CFG_SPECIAL_USE 0x41
|
||||
#define PCI_CFG_MODE 0x43
|
||||
|
||||
#define PCI_CMD_IO_ENABLE 0x0001 /* IO access enable */
|
||||
#define PCI_CMD_MEM_ENABLE 0x0002 /* memory access enable */
|
||||
#define PCI_CMD_MASTER_ENABLE 0x0004 /* bus master enable */
|
||||
#define PCI_CMD_MON_ENABLE 0x0008 /* monitor special cycles enable */
|
||||
#define PCI_CMD_WI_ENABLE 0x0010 /* write and invalidate enable */
|
||||
#define PCI_CMD_SNOOP_ENABLE 0x0020 /* palette snoop enable */
|
||||
#define PCI_CMD_PERR_ENABLE 0x0040 /* parity error enable */
|
||||
#define PCI_CMD_WC_ENABLE 0x0080 /* wait cycle enable */
|
||||
#define PCI_CMD_SERR_ENABLE 0x0100 /* system error enable */
|
||||
#define PCI_CMD_FBTB_ENABLE 0x0200 /* fast back to back enable */
|
||||
|
||||
|
||||
/*CSR Register bit definitions*/
|
||||
#define PCI_CSR_HOST BIT(0)
|
||||
#define PCI_CSR_ARBEN BIT(1)
|
||||
#define PCI_CSR_ADS BIT(2)
|
||||
#define PCI_CSR_PDS BIT(3)
|
||||
#define PCI_CSR_ABE BIT(4)
|
||||
#define PCI_CSR_DBT BIT(5)
|
||||
#define PCI_CSR_ASE BIT(8)
|
||||
#define PCI_CSR_IC BIT(15)
|
||||
|
||||
/*Configuration command bit definitions*/
|
||||
#define PCI_CFG_CMD_IOAE BIT(0)
|
||||
#define PCI_CFG_CMD_MAE BIT(1)
|
||||
#define PCI_CFG_CMD_BME BIT(2)
|
||||
#define PCI_CFG_CMD_MWIE BIT(4)
|
||||
#define PCI_CFG_CMD_SER BIT(8)
|
||||
#define PCI_CFG_CMD_FBBE BIT(9)
|
||||
#define PCI_CFG_CMD_MDPE BIT(24)
|
||||
#define PCI_CFG_CMD_STA BIT(27)
|
||||
#define PCI_CFG_CMD_RTA BIT(28)
|
||||
#define PCI_CFG_CMD_RMA BIT(29)
|
||||
#define PCI_CFG_CMD_SSE BIT(30)
|
||||
#define PCI_CFG_CMD_DPE BIT(31)
|
||||
|
||||
/*DMACTRL DMA Control and status Register*/
|
||||
#define PCI_DMACTRL_APDCEN BIT(0)
|
||||
#define PCI_DMACTRL_APDC0 BIT(4)
|
||||
#define PCI_DMACTRL_APDE0 BIT(5)
|
||||
#define PCI_DMACTRL_APDC1 BIT(6)
|
||||
#define PCI_DMACTRL_APDE1 BIT(7)
|
||||
#define PCI_DMACTRL_PADCEN BIT(8)
|
||||
#define PCI_DMACTRL_PADC0 BIT(12)
|
||||
#define PCI_DMACTRL_PADE0 BIT(13)
|
||||
#define PCI_DMACTRL_PADC1 BIT(14)
|
||||
#define PCI_DMACTRL_PADE1 BIT(15)
|
||||
|
||||
#endif
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
#
|
||||
# (C) Copyright 2000-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-y := actux1.o
|
|
@ -1,148 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2007
|
||||
* Michael Schwingen, michael@schwingen.org
|
||||
*
|
||||
* (C) Copyright 2006
|
||||
* Stefan Roese, DENX Software Engineering, sr@denx.de.
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
* Marius Groeger <mgroeger@sysgo.de>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <malloc.h>
|
||||
#include <asm/arch/ixp425.h>
|
||||
#include <asm/io.h>
|
||||
#include <miiphy.h>
|
||||
#ifdef CONFIG_PCI
|
||||
#include <pci.h>
|
||||
#include <asm/arch/ixp425pci.h>
|
||||
#endif
|
||||
|
||||
#include "actux1_hw.h"
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
/* CS5: Debug port */
|
||||
writel(0x9d520003, IXP425_EXP_CS5);
|
||||
/* CS6: HwRel */
|
||||
writel(0x81860001, IXP425_EXP_CS6);
|
||||
/* CS7: LEDs */
|
||||
writel(0x80900003, IXP425_EXP_CS7);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
/* adress of boot parameters */
|
||||
gd->bd->bi_boot_params = 0x00000100;
|
||||
|
||||
GPIO_OUTPUT_CLEAR(CONFIG_SYS_GPIO_IORST);
|
||||
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_IORST);
|
||||
|
||||
/* Setup GPIOs for PCI INTA */
|
||||
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_PCI1_INTA);
|
||||
GPIO_INT_ACT_LOW_SET(CONFIG_SYS_GPIO_PCI1_INTA);
|
||||
|
||||
/* Setup GPIOs for 33MHz clock output */
|
||||
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_PCI_CLK);
|
||||
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_EXTBUS_CLK);
|
||||
writel(0x011001FF, IXP425_GPIO_GPCLKR);
|
||||
|
||||
udelay(533);
|
||||
GPIO_OUTPUT_SET(CONFIG_SYS_GPIO_IORST);
|
||||
|
||||
ACTUX1_LED1(2);
|
||||
ACTUX1_LED2(2);
|
||||
ACTUX1_LED3(0);
|
||||
ACTUX1_LED4(0);
|
||||
ACTUX1_LED5(0);
|
||||
ACTUX1_LED6(0);
|
||||
ACTUX1_LED7(0);
|
||||
|
||||
ACTUX1_HS(ACTUX1_HS_DCD);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check Board Identity
|
||||
*/
|
||||
int checkboard(void)
|
||||
{
|
||||
char buf[64];
|
||||
int i = getenv_f("serial#", buf, sizeof(buf));
|
||||
|
||||
puts("Board: AcTux-1 rev.");
|
||||
putc(ACTUX1_BOARDREL + 'A' - 1);
|
||||
|
||||
if (i > 0) {
|
||||
puts(", serial# ");
|
||||
puts(buf);
|
||||
}
|
||||
putc('\n');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* get_board_rev() - setup to pass kernel board revision information
|
||||
* 0 = reserved
|
||||
* 1 = Rev. A
|
||||
* 2 = Rev. B
|
||||
*************************************************************************/
|
||||
u32 get_board_rev(void)
|
||||
{
|
||||
return ACTUX1_BOARDREL;
|
||||
}
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
gd->ram_size = get_ram_size(CONFIG_SYS_SDRAM_BASE, 128<<20);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
struct pci_controller hose;
|
||||
|
||||
void pci_init_board(void)
|
||||
{
|
||||
pci_ixp_init(&hose);
|
||||
}
|
||||
#endif
|
||||
|
||||
void reset_phy(void)
|
||||
{
|
||||
u16 id1, id2;
|
||||
|
||||
/* initialize the PHY */
|
||||
miiphy_reset("NPE0", CONFIG_PHY_ADDR);
|
||||
|
||||
miiphy_read("NPE0", CONFIG_PHY_ADDR, MII_PHYSID1, &id1);
|
||||
miiphy_read("NPE0", CONFIG_PHY_ADDR, MII_PHYSID2, &id2);
|
||||
|
||||
id2 &= 0xFFF0; /* mask out revision bits */
|
||||
|
||||
if (id1 == 0x13 && id2 == 0x78e0) {
|
||||
/*
|
||||
* LXT971/LXT972 PHY: set LED outputs:
|
||||
* LED1(green) = Link/ACT,
|
||||
* LED2 (unused) = LINK,
|
||||
* LED3(red) = Coll
|
||||
*/
|
||||
miiphy_write("NPE0", CONFIG_PHY_ADDR, 20, 0xD432);
|
||||
} else if (id1 == 0x143 && id2 == 0xbc30) {
|
||||
/* BCM5241: default values are OK */
|
||||
} else
|
||||
printf("unknown ethernet PHY ID: %x %x\n", id1, id2);
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2007
|
||||
* Michael Schwingen, michael@schwingen.org
|
||||
*
|
||||
* hardware register definitions for the AcTux-1 board.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef _ACTUX1_HW_H
|
||||
#define _ACTUX1_HW_H
|
||||
|
||||
/* 0 = LED off,1 = green, 2 = red, 3 = orange */
|
||||
#define ACTUX1_LED1(a) writeb((a), IXP425_EXP_BUS_CS7_BASE_PHYS + 0)
|
||||
#define ACTUX1_LED2(a) writeb((a), IXP425_EXP_BUS_CS7_BASE_PHYS + 1)
|
||||
#define ACTUX1_LED3(a) writeb((a), IXP425_EXP_BUS_CS7_BASE_PHYS + 2)
|
||||
#define ACTUX1_LED4(a) writeb((a)^3, IXP425_EXP_BUS_CS7_BASE_PHYS + 3)
|
||||
#define ACTUX1_LED5(a) writeb((a)^3, IXP425_EXP_BUS_CS7_BASE_PHYS + 4)
|
||||
#define ACTUX1_LED6(a) writeb((a)^3, IXP425_EXP_BUS_CS7_BASE_PHYS + 5)
|
||||
#define ACTUX1_LED7(a) writeb((a)^3, IXP425_EXP_BUS_CS7_BASE_PHYS + 6)
|
||||
#define ACTUX1_HS(a) writeb((a), IXP425_EXP_BUS_CS7_BASE_PHYS + 7)
|
||||
#define ACTUX1_HS_DCD 0x01
|
||||
#define ACTUX1_HS_DSR 0x02
|
||||
|
||||
#define ACTUX1_DBG_PORT IXP425_EXP_BUS_CS5_BASE_PHYS
|
||||
#define ACTUX1_BOARDREL (readb(IXP425_EXP_BUS_CS6_BASE_PHYS) & 0x0F)
|
||||
|
||||
/* GPIO settings */
|
||||
#define CONFIG_SYS_GPIO_PCI1_INTA 2
|
||||
#define CONFIG_SYS_GPIO_PCI2_INTA 3
|
||||
#define CONFIG_SYS_GPIO_I2C_SDA 4
|
||||
#define CONFIG_SYS_GPIO_I2C_SCL 5
|
||||
#define CONFIG_SYS_GPIO_DBGJUMPER 9
|
||||
#define CONFIG_SYS_GPIO_BUTTON1 10
|
||||
#define CONFIG_SYS_GPIO_DBGSENSE 11
|
||||
#define CONFIG_SYS_GPIO_DTR 12
|
||||
#define CONFIG_SYS_GPIO_IORST 13 /* Out */
|
||||
#define CONFIG_SYS_GPIO_PCI_CLK 14 /* Out */
|
||||
#define CONFIG_SYS_GPIO_EXTBUS_CLK 15 /* Out */
|
||||
|
||||
#endif
|
|
@ -1,99 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2000
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
OUTPUT_FORMAT ("elf32-bigarm", "elf32-bigarm", "elf32-bigarm")
|
||||
OUTPUT_ARCH (arm)
|
||||
ENTRY (_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x00000000;
|
||||
|
||||
. = ALIGN (4);
|
||||
.text : {
|
||||
*(.__image_copy_start)
|
||||
arch/arm/cpu/ixp/start.o(.text*)
|
||||
net/built-in.o(.text*)
|
||||
board/actux1/built-in.o(.text*)
|
||||
arch/arm/cpu/ixp/built-in.o(.text*)
|
||||
drivers/input/built-in.o(.text*)
|
||||
|
||||
. = env_offset;
|
||||
common/env_embedded.o(.ppcenv)
|
||||
*(.text*)
|
||||
}
|
||||
|
||||
. = ALIGN(4);
|
||||
.rodata : {
|
||||
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
|
||||
}
|
||||
. = ALIGN(4);
|
||||
.data : {
|
||||
*(.data*)
|
||||
}
|
||||
. = ALIGN(4);
|
||||
.got : {
|
||||
*(.got)
|
||||
}
|
||||
. =.;
|
||||
|
||||
. = ALIGN(4);
|
||||
.u_boot_list : {
|
||||
KEEP(*(SORT(.u_boot_list*)));
|
||||
}
|
||||
|
||||
. = ALIGN (4);
|
||||
|
||||
.image_copy_end :
|
||||
{
|
||||
*(.__image_copy_end)
|
||||
}
|
||||
|
||||
.rel_dyn_start :
|
||||
{
|
||||
*(.__rel_dyn_start)
|
||||
}
|
||||
|
||||
.rel.dyn : {
|
||||
*(.rel*)
|
||||
}
|
||||
|
||||
.rel_dyn_end :
|
||||
{
|
||||
*(.__rel_dyn_end)
|
||||
}
|
||||
|
||||
_end = .;
|
||||
|
||||
/*
|
||||
* Compiler-generated __bss_start and __bss_end, see arch/arm/lib/bss.c
|
||||
* __bss_base and __bss_limit are for linker only (overlay ordering)
|
||||
*/
|
||||
|
||||
.bss_start __rel_dyn_start (OVERLAY) : {
|
||||
KEEP(*(.__bss_start));
|
||||
__bss_base = .;
|
||||
}
|
||||
|
||||
.bss __bss_base (OVERLAY) : {
|
||||
*(.bss*)
|
||||
. = ALIGN(4);
|
||||
__bss_limit = .;
|
||||
}
|
||||
.bss_end __bss_limit (OVERLAY) : {
|
||||
KEEP(*(.__bss_end));
|
||||
}
|
||||
|
||||
.dynsym _end : { *(.dynsym) }
|
||||
.dynbss : { *(.dynbss) }
|
||||
.dynstr : { *(.dynstr*) }
|
||||
.dynamic : { *(.dynamic*) }
|
||||
.hash : { *(.hash*) }
|
||||
.plt : { *(.plt*) }
|
||||
.interp : { *(.interp*) }
|
||||
.gnu : { *(.gnu*) }
|
||||
.ARM.exidx : { *(.ARM.exidx*) }
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
#
|
||||
# (C) Copyright 2000-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-y := actux2.o
|
|
@ -1,122 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2007
|
||||
* Michael Schwingen, michael@schwingen.org
|
||||
*
|
||||
* (C) Copyright 2006
|
||||
* Stefan Roese, DENX Software Engineering, sr@denx.de.
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
* Marius Groeger <mgroeger@sysgo.de>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <malloc.h>
|
||||
#include <asm/arch/ixp425.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include <miiphy.h>
|
||||
|
||||
#include "actux2_hw.h"
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
/* CS1: IPAC-X */
|
||||
writel(0x94d10013, IXP425_EXP_CS1);
|
||||
/* CS5: Debug port */
|
||||
writel(0x9d520003, IXP425_EXP_CS5);
|
||||
/* CS6: HW release register */
|
||||
writel(0x81860001, IXP425_EXP_CS6);
|
||||
/* CS7: LEDs */
|
||||
writel(0x80900003, IXP425_EXP_CS7);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
/* adress of boot parameters */
|
||||
gd->bd->bi_boot_params = 0x00000100;
|
||||
|
||||
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_IORST);
|
||||
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_ETHRST);
|
||||
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_DSR);
|
||||
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_DCD);
|
||||
|
||||
GPIO_OUTPUT_CLEAR(CONFIG_SYS_GPIO_IORST);
|
||||
GPIO_OUTPUT_CLEAR(CONFIG_SYS_GPIO_ETHRST);
|
||||
|
||||
GPIO_OUTPUT_CLEAR(CONFIG_SYS_GPIO_DSR);
|
||||
GPIO_OUTPUT_SET(CONFIG_SYS_GPIO_DCD);
|
||||
|
||||
/* Setup GPIOs for Interrupt inputs */
|
||||
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_DBGINT);
|
||||
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_ETHINT);
|
||||
|
||||
/* Setup GPIOs for 33MHz clock output */
|
||||
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_PCI_CLK);
|
||||
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_EXTBUS_CLK);
|
||||
writel(0x011001FF, IXP425_GPIO_GPCLKR);
|
||||
|
||||
udelay(533);
|
||||
GPIO_OUTPUT_SET(CONFIG_SYS_GPIO_IORST);
|
||||
GPIO_OUTPUT_SET(CONFIG_SYS_GPIO_ETHRST);
|
||||
|
||||
ACTUX2_LED1(1);
|
||||
ACTUX2_LED2(0);
|
||||
ACTUX2_LED3(0);
|
||||
ACTUX2_LED4(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check Board Identity
|
||||
*/
|
||||
int checkboard(void)
|
||||
{
|
||||
char buf[64];
|
||||
int i = getenv_f("serial#", buf, sizeof(buf));
|
||||
|
||||
puts("Board: AcTux-2 rev.");
|
||||
putc(ACTUX2_BOARDREL + 'A' - 1);
|
||||
|
||||
if (i > 0) {
|
||||
puts(", serial# ");
|
||||
puts(buf);
|
||||
}
|
||||
putc('\n');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
gd->ram_size = get_ram_size(CONFIG_SYS_SDRAM_BASE, 128<<20);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* get_board_rev() - setup to pass kernel board revision information
|
||||
* 0 = reserved
|
||||
* 1 = Rev. A
|
||||
* 2 = Rev. B
|
||||
*************************************************************************/
|
||||
u32 get_board_rev(void)
|
||||
{
|
||||
return ACTUX2_BOARDREL;
|
||||
}
|
||||
|
||||
void reset_phy(void)
|
||||
{
|
||||
/* init IcPlus IP175C ethernet switch to native IP175C mode */
|
||||
miiphy_write("NPE0", 29, 31, 0x175C);
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2007
|
||||
* Michael Schwingen, michael@schwingen.org
|
||||
*
|
||||
* hardware register definitions for the AcTux-2 board.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef _ACTUX2_HW_H
|
||||
#define _ACTUX2_HW_H
|
||||
|
||||
/* 0 = LED off,1 = green, 2 = red, 3 = orange */
|
||||
#define ACTUX2_LED1(a) writeb((a ? 2 : 0), IXP425_EXP_BUS_CS7_BASE_PHYS + 0)
|
||||
#define ACTUX2_LED2(a) writeb((a ? 2 : 0), IXP425_EXP_BUS_CS7_BASE_PHYS + 1)
|
||||
#define ACTUX2_LED3(a) writeb((a ? 0 : 2), IXP425_EXP_BUS_CS7_BASE_PHYS + 2)
|
||||
#define ACTUX2_LED4(a) writeb((a ? 0 : 2), IXP425_EXP_BUS_CS7_BASE_PHYS + 3)
|
||||
|
||||
#define ACTUX2_DBG_PORT IXP425_EXP_BUS_CS5_BASE_PHYS
|
||||
#define ACTUX2_BOARDREL (readb(IXP425_EXP_BUS_CS6_BASE_PHYS) & 0x0F)
|
||||
#define ACTUX2_OPTION (readb(IXP425_EXP_BUS_CS6_BASE_PHYS) & 0xF0)
|
||||
|
||||
/*
|
||||
* GPIO settings
|
||||
*/
|
||||
#define CONFIG_SYS_GPIO_DBGINT 0
|
||||
#define CONFIG_SYS_GPIO_ETHINT 1
|
||||
#define CONFIG_SYS_GPIO_ETHRST 2 /* Out */
|
||||
#define CONFIG_SYS_GPIO_LED5_GN 3 /* Out */
|
||||
#define CONFIG_SYS_GPIO_UNUSED4 4
|
||||
#define CONFIG_SYS_GPIO_UNUSED5 5
|
||||
#define CONFIG_SYS_GPIO_DSR 6 /* Out */
|
||||
#define CONFIG_SYS_GPIO_DCD 7 /* Out */
|
||||
#define CONFIG_SYS_GPIO_IPAC_INT 8
|
||||
#define CONFIG_SYS_GPIO_DBGJUMPER 9
|
||||
#define CONFIG_SYS_GPIO_BUTTON1 10
|
||||
#define CONFIG_SYS_GPIO_DBGSENSE 11
|
||||
#define CONFIG_SYS_GPIO_DTR 12
|
||||
#define CONFIG_SYS_GPIO_IORST 13 /* Out */
|
||||
#define CONFIG_SYS_GPIO_PCI_CLK 14 /* Out */
|
||||
#define CONFIG_SYS_GPIO_EXTBUS_CLK 15 /* Out */
|
||||
|
||||
#endif
|
|
@ -1,99 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2000
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
OUTPUT_FORMAT ("elf32-bigarm", "elf32-bigarm", "elf32-bigarm")
|
||||
OUTPUT_ARCH (arm)
|
||||
ENTRY (_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x00000000;
|
||||
|
||||
. = ALIGN (4);
|
||||
.text : {
|
||||
*(.__image_copy_start)
|
||||
arch/arm/cpu/ixp/start.o(.text*)
|
||||
net/built-in.o(.text*)
|
||||
board/actux2/built-in.o(.text*)
|
||||
arch/arm/cpu/ixp/built-in.o(.text*)
|
||||
drivers/input/built-in.o(.text*)
|
||||
|
||||
. = env_offset;
|
||||
common/env_embedded.o(.ppcenv)
|
||||
*(.text*)
|
||||
}
|
||||
|
||||
. = ALIGN(4);
|
||||
.rodata : {
|
||||
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
|
||||
}
|
||||
. = ALIGN(4);
|
||||
.data : {
|
||||
*(.data*)
|
||||
}
|
||||
. = ALIGN(4);
|
||||
.got : {
|
||||
*(.got)
|
||||
}
|
||||
. =.;
|
||||
|
||||
. = ALIGN(4);
|
||||
.u_boot_list : {
|
||||
KEEP(*(SORT(.u_boot_list*)));
|
||||
}
|
||||
|
||||
. = ALIGN (4);
|
||||
|
||||
.image_copy_end :
|
||||
{
|
||||
*(.__image_copy_end)
|
||||
}
|
||||
|
||||
.rel_dyn_start :
|
||||
{
|
||||
*(.__rel_dyn_start)
|
||||
}
|
||||
|
||||
.rel.dyn : {
|
||||
*(.rel*)
|
||||
}
|
||||
|
||||
.rel_dyn_end :
|
||||
{
|
||||
*(.__rel_dyn_end)
|
||||
}
|
||||
|
||||
_end = .;
|
||||
|
||||
/*
|
||||
* Compiler-generated __bss_start and __bss_end, see arch/arm/lib/bss.c
|
||||
* __bss_base and __bss_limit are for linker only (overlay ordering)
|
||||
*/
|
||||
|
||||
.bss_start __rel_dyn_start (OVERLAY) : {
|
||||
KEEP(*(.__bss_start));
|
||||
__bss_base = .;
|
||||
}
|
||||
|
||||
.bss __bss_base (OVERLAY) : {
|
||||
*(.bss*)
|
||||
. = ALIGN(4);
|
||||
__bss_limit = .;
|
||||
}
|
||||
.bss_end __bss_limit (OVERLAY) : {
|
||||
KEEP(*(.__bss_end));
|
||||
}
|
||||
|
||||
.dynsym _end : { *(.dynsym) }
|
||||
.dynbss : { *(.dynbss) }
|
||||
.dynstr : { *(.dynstr*) }
|
||||
.dynamic : { *(.dynamic*) }
|
||||
.hash : { *(.hash*) }
|
||||
.plt : { *(.plt*) }
|
||||
.interp : { *(.interp*) }
|
||||
.gnu : { *(.gnu*) }
|
||||
.ARM.exidx : { *(.ARM.exidx*) }
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
#
|
||||
# (C) Copyright 2000-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-y := actux3.o
|
|
@ -1,149 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2007
|
||||
* Michael Schwingen, michael@schwingen.org
|
||||
*
|
||||
* (C) Copyright 2006
|
||||
* Stefan Roese, DENX Software Engineering, sr@denx.de.
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
* Marius Groeger <mgroeger@sysgo.de>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <malloc.h>
|
||||
#include <asm/arch/ixp425.h>
|
||||
#include <asm/io.h>
|
||||
#include <miiphy.h>
|
||||
#include "actux3_hw.h"
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
/* CS1: IPAC-X */
|
||||
writel(0x94d10013, IXP425_EXP_CS1);
|
||||
/* CS5: Debug port */
|
||||
writel(0x9d520003, IXP425_EXP_CS5);
|
||||
/* CS6: Release/Option register */
|
||||
writel(0x81860001, IXP425_EXP_CS6);
|
||||
/* CS7: LEDs */
|
||||
writel(0x80900003, IXP425_EXP_CS7);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
/* adress of boot parameters */
|
||||
gd->bd->bi_boot_params = 0x00000100;
|
||||
|
||||
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_IORST);
|
||||
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_ETHRST);
|
||||
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_DSR);
|
||||
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_DCD);
|
||||
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_LED5_GN);
|
||||
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_LED6_RT);
|
||||
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_LED6_GN);
|
||||
|
||||
GPIO_OUTPUT_CLEAR(CONFIG_SYS_GPIO_IORST);
|
||||
GPIO_OUTPUT_CLEAR(CONFIG_SYS_GPIO_ETHRST);
|
||||
|
||||
GPIO_OUTPUT_CLEAR(CONFIG_SYS_GPIO_DSR);
|
||||
GPIO_OUTPUT_SET(CONFIG_SYS_GPIO_DCD);
|
||||
|
||||
GPIO_OUTPUT_CLEAR(CONFIG_SYS_GPIO_LED5_GN);
|
||||
GPIO_OUTPUT_CLEAR(CONFIG_SYS_GPIO_LED6_RT);
|
||||
GPIO_OUTPUT_CLEAR(CONFIG_SYS_GPIO_LED6_GN);
|
||||
|
||||
/*
|
||||
* Setup GPIO's for Interrupt inputs
|
||||
*/
|
||||
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_DBGINT);
|
||||
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_ETHINT);
|
||||
|
||||
/*
|
||||
* Setup GPIO's for 33MHz clock output
|
||||
*/
|
||||
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_PCI_CLK);
|
||||
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_EXTBUS_CLK);
|
||||
writel(0x011001FF, IXP425_GPIO_GPCLKR);
|
||||
|
||||
/* we need a minimum PCI reset pulse width after enabling the clock */
|
||||
udelay(533);
|
||||
GPIO_OUTPUT_SET(CONFIG_SYS_GPIO_IORST);
|
||||
GPIO_OUTPUT_SET(CONFIG_SYS_GPIO_ETHRST);
|
||||
|
||||
ACTUX3_LED1_RT(1);
|
||||
ACTUX3_LED1_GN(0);
|
||||
ACTUX3_LED2_RT(0);
|
||||
ACTUX3_LED2_GN(0);
|
||||
ACTUX3_LED3_RT(0);
|
||||
ACTUX3_LED3_GN(0);
|
||||
ACTUX3_LED4_GN(0);
|
||||
ACTUX3_LED5_RT(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check Board Identity
|
||||
*/
|
||||
int checkboard(void)
|
||||
{
|
||||
char buf[64];
|
||||
int i = getenv_f("serial#", buf, sizeof(buf));
|
||||
|
||||
puts("Board: AcTux-3 rev.");
|
||||
putc(ACTUX3_BOARDREL + 'A' - 1);
|
||||
|
||||
if (i > 0) {
|
||||
puts (", serial# ");
|
||||
puts (buf);
|
||||
}
|
||||
putc('\n');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* get_board_rev() - setup to pass kernel board revision information
|
||||
* 0 = reserved
|
||||
* 1 = Rev. A
|
||||
* 2 = Rev. B
|
||||
*************************************************************************/
|
||||
u32 get_board_rev(void)
|
||||
{
|
||||
return ACTUX3_BOARDREL;
|
||||
}
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
gd->ram_size = get_ram_size(CONFIG_SYS_SDRAM_BASE, 128<<20);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void reset_phy(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* initialize the PHY */
|
||||
miiphy_reset("NPE0", CONFIG_PHY_ADDR);
|
||||
|
||||
/* all LED outputs = Link/Act */
|
||||
miiphy_write("NPE0", CONFIG_PHY_ADDR, 0x16, 0x0AAA);
|
||||
|
||||
/*
|
||||
* The Marvell 88E6060 switch comes up with all ports disabled.
|
||||
* set all ethernet switch ports to forwarding state
|
||||
*/
|
||||
for (i = 1; i <= 5; i++)
|
||||
miiphy_write("NPE0", CONFIG_PHY_ADDR + 8 + i, 0x04, 0x03);
|
||||
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2007
|
||||
* Michael Schwingen, michael@schwingen.org
|
||||
*
|
||||
* hardware register definitions for the AcTux-3 board.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef _ACTUX3_HW_H
|
||||
#define _ACTUX3_HW_H
|
||||
|
||||
/* 0 = LED off,1 = ON */
|
||||
#define ACTUX3_LED1_RT(a) writeb((a), IXP425_EXP_BUS_CS7_BASE_PHYS + 0)
|
||||
#define ACTUX3_LED1_GN(a) writeb((a), IXP425_EXP_BUS_CS7_BASE_PHYS + 1)
|
||||
#define ACTUX3_LED2_RT(a) writeb((a), IXP425_EXP_BUS_CS7_BASE_PHYS + 2)
|
||||
#define ACTUX3_LED2_GN(a) writeb((a), IXP425_EXP_BUS_CS7_BASE_PHYS + 3)
|
||||
#define ACTUX3_LED3_RT(a) writeb((a), IXP425_EXP_BUS_CS7_BASE_PHYS + 4)
|
||||
#define ACTUX3_LED3_GN(a) writeb((a), IXP425_EXP_BUS_CS7_BASE_PHYS + 5)
|
||||
#define ACTUX3_LED4_GN(a) writeb((a)^1, IXP425_EXP_BUS_CS7_BASE_PHYS + 6)
|
||||
#define ACTUX3_LED5_RT(a) writeb((a), IXP425_EXP_BUS_CS7_BASE_PHYS + 7)
|
||||
|
||||
#define ACTUX3_DBG_PORT IXP425_EXP_BUS_CS5_BASE_PHYS
|
||||
#define ACTUX3_BOARDREL (readb(IXP425_EXP_BUS_CS6_BASE_PHYS) & 0x0F)
|
||||
#define ACTUX3_OPTION (readb(IXP425_EXP_BUS_CS6_BASE_PHYS) & 0xF0)
|
||||
|
||||
/* GPIO settings */
|
||||
#define CONFIG_SYS_GPIO_DBGINT 0
|
||||
#define CONFIG_SYS_GPIO_ETHINT 1
|
||||
#define CONFIG_SYS_GPIO_ETHRST 2 /* Out */
|
||||
#define CONFIG_SYS_GPIO_LED5_GN 3 /* Out */
|
||||
#define CONFIG_SYS_GPIO_LED6_RT 4 /* Out */
|
||||
#define CONFIG_SYS_GPIO_LED6_GN 5 /* Out */
|
||||
#define CONFIG_SYS_GPIO_DSR 6 /* Out */
|
||||
#define CONFIG_SYS_GPIO_DCD 7 /* Out */
|
||||
#define CONFIG_SYS_GPIO_DBGJUMPER 9
|
||||
#define CONFIG_SYS_GPIO_BUTTON1 10
|
||||
#define CONFIG_SYS_GPIO_DBGSENSE 11
|
||||
#define CONFIG_SYS_GPIO_DTR 12
|
||||
#define CONFIG_SYS_GPIO_IORST 13 /* Out */
|
||||
#define CONFIG_SYS_GPIO_PCI_CLK 14 /* Out */
|
||||
#define CONFIG_SYS_GPIO_EXTBUS_CLK 15 /* Out */
|
||||
|
||||
#endif
|
|
@ -1,99 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2000
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
OUTPUT_FORMAT ("elf32-bigarm", "elf32-bigarm", "elf32-bigarm")
|
||||
OUTPUT_ARCH (arm)
|
||||
ENTRY (_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x00000000;
|
||||
|
||||
. = ALIGN (4);
|
||||
.text : {
|
||||
*(.__image_copy_start)
|
||||
arch/arm/cpu/ixp/start.o(.text*)
|
||||
net/built-in.o(.text*)
|
||||
board/actux3/built-in.o(.text*)
|
||||
arch/arm/cpu/ixp/built-in.o(.text*)
|
||||
drivers/input/built-in.o(.text*)
|
||||
|
||||
. = env_offset;
|
||||
common/env_embedded.o(.ppcenv)
|
||||
*(.text*)
|
||||
}
|
||||
|
||||
. = ALIGN(4);
|
||||
.rodata : {
|
||||
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
|
||||
}
|
||||
. = ALIGN(4);
|
||||
.data : {
|
||||
*(.data*)
|
||||
}
|
||||
. = ALIGN(4);
|
||||
.got : {
|
||||
*(.got)
|
||||
}
|
||||
. =.;
|
||||
|
||||
. = ALIGN(4);
|
||||
.u_boot_list : {
|
||||
KEEP(*(SORT(.u_boot_list*)));
|
||||
}
|
||||
|
||||
. = ALIGN (4);
|
||||
|
||||
.image_copy_end :
|
||||
{
|
||||
*(.__image_copy_end)
|
||||
}
|
||||
|
||||
.rel_dyn_start :
|
||||
{
|
||||
*(.__rel_dyn_start)
|
||||
}
|
||||
|
||||
.rel.dyn : {
|
||||
*(.rel*)
|
||||
}
|
||||
|
||||
.rel_dyn_end :
|
||||
{
|
||||
*(.__rel_dyn_end)
|
||||
}
|
||||
|
||||
_end = .;
|
||||
|
||||
/*
|
||||
* Compiler-generated __bss_start and __bss_end, see arch/arm/lib/bss.c
|
||||
* __bss_base and __bss_limit are for linker only (overlay ordering)
|
||||
*/
|
||||
|
||||
.bss_start __rel_dyn_start (OVERLAY) : {
|
||||
KEEP(*(.__bss_start));
|
||||
__bss_base = .;
|
||||
}
|
||||
|
||||
.bss __bss_base (OVERLAY) : {
|
||||
*(.bss*)
|
||||
. = ALIGN(4);
|
||||
__bss_limit = .;
|
||||
}
|
||||
.bss_end __bss_limit (OVERLAY) : {
|
||||
KEEP(*(.__bss_end));
|
||||
}
|
||||
|
||||
.dynsym _end : { *(.dynsym) }
|
||||
.dynbss : { *(.dynbss) }
|
||||
.dynstr : { *(.dynstr*) }
|
||||
.dynamic : { *(.dynamic*) }
|
||||
.hash : { *(.hash*) }
|
||||
.plt : { *(.plt*) }
|
||||
.interp : { *(.interp*) }
|
||||
.gnu : { *(.gnu*) }
|
||||
.ARM.exidx : { *(.ARM.exidx*) }
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
#
|
||||
# (C) Copyright 2000-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-y := actux4.o
|
|
@ -1,129 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2007
|
||||
* Michael Schwingen, michael@schwingen.org
|
||||
*
|
||||
* (C) Copyright 2006
|
||||
* Stefan Roese, DENX Software Engineering, sr@denx.de.
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
* Marius Groeger <mgroeger@sysgo.de>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <malloc.h>
|
||||
#include <asm/arch/ixp425.h>
|
||||
#include <asm/io.h>
|
||||
#include <miiphy.h>
|
||||
#ifdef CONFIG_PCI
|
||||
#include <pci.h>
|
||||
#include <asm/arch/ixp425pci.h>
|
||||
#endif
|
||||
|
||||
#include "actux4_hw.h"
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
writel(0xbd113c42, IXP425_EXP_CS1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
/* adress of boot parameters */
|
||||
gd->bd->bi_boot_params = 0x00000100;
|
||||
|
||||
GPIO_OUTPUT_CLEAR(CONFIG_SYS_GPIO_nPWRON);
|
||||
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_nPWRON);
|
||||
|
||||
GPIO_OUTPUT_CLEAR(CONFIG_SYS_GPIO_IORST);
|
||||
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_IORST);
|
||||
|
||||
/* led not populated on board*/
|
||||
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_LED3);
|
||||
GPIO_OUTPUT_SET(CONFIG_SYS_GPIO_LED3);
|
||||
|
||||
/* middle LED */
|
||||
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_LED2);
|
||||
GPIO_OUTPUT_SET(CONFIG_SYS_GPIO_LED2);
|
||||
|
||||
/* right LED */
|
||||
/* weak pulldown = LED weak on */
|
||||
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_LED1);
|
||||
GPIO_OUTPUT_SET(CONFIG_SYS_GPIO_LED1);
|
||||
|
||||
/* Setup GPIO's for Interrupt inputs */
|
||||
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_USBINTA);
|
||||
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_USBINTB);
|
||||
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_USBINTC);
|
||||
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_RTCINT);
|
||||
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_PCI_INTA);
|
||||
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_PCI_INTB);
|
||||
|
||||
GPIO_INT_ACT_LOW_SET(CONFIG_SYS_GPIO_USBINTA);
|
||||
GPIO_INT_ACT_LOW_SET(CONFIG_SYS_GPIO_USBINTB);
|
||||
GPIO_INT_ACT_LOW_SET(CONFIG_SYS_GPIO_USBINTC);
|
||||
GPIO_INT_ACT_LOW_SET(CONFIG_SYS_GPIO_RTCINT);
|
||||
GPIO_INT_ACT_LOW_SET(CONFIG_SYS_GPIO_PCI_INTA);
|
||||
GPIO_INT_ACT_LOW_SET(CONFIG_SYS_GPIO_PCI_INTB);
|
||||
|
||||
/* Setup GPIO's for 33MHz clock output */
|
||||
writel(0x011001FF, IXP425_GPIO_GPCLKR);
|
||||
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_EXTBUS_CLK);
|
||||
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_PCI_CLK);
|
||||
|
||||
udelay(10000);
|
||||
GPIO_OUTPUT_SET(CONFIG_SYS_GPIO_IORST);
|
||||
udelay(10000);
|
||||
GPIO_OUTPUT_CLEAR(CONFIG_SYS_GPIO_IORST);
|
||||
udelay(10000);
|
||||
GPIO_OUTPUT_SET(CONFIG_SYS_GPIO_IORST);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check Board Identity */
|
||||
int checkboard(void)
|
||||
{
|
||||
puts("Board: AcTux-4\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
gd->ram_size = get_ram_size(CONFIG_SYS_SDRAM_BASE, 128<<20);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
struct pci_controller hose;
|
||||
|
||||
void pci_init_board(void)
|
||||
{
|
||||
pci_ixp_init(&hose);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Hardcoded flash setup:
|
||||
* Flash 0 is a non-CFI SST 39VF020 flash, 8 bit flash / 8 bit bus.
|
||||
* Flash 1 is an Intel *16 flash using the CFI driver.
|
||||
*/
|
||||
ulong board_flash_get_legacy(ulong base, int banknum, flash_info_t *info)
|
||||
{
|
||||
if (banknum == 0) { /* non-CFI boot flash */
|
||||
info->portwidth = 1;
|
||||
info->chipwidth = 1;
|
||||
info->interface = FLASH_CFI_X8;
|
||||
return 1;
|
||||
} else
|
||||
return 0;
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2007
|
||||
* Michael Schwingen, michael@schwingen.org
|
||||
*
|
||||
* hardware register definitions for the AcTux-4 board.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef _ACTUX4_HW_H
|
||||
#define _ACTUX4_HW_H
|
||||
|
||||
/*
|
||||
* GPIO settings
|
||||
*/
|
||||
#define CONFIG_SYS_GPIO_USBINTA 0
|
||||
#define CONFIG_SYS_GPIO_USBINTB 1
|
||||
#define CONFIG_SYS_GPIO_USBINTC 2
|
||||
#define CONFIG_SYS_GPIO_nPWRON 3 /* Out */
|
||||
#define CONFIG_SYS_GPIO_I2C_SCL 4
|
||||
#define CONFIG_SYS_GPIO_I2C_SDA 5
|
||||
#define CONFIG_SYS_GPIO_PCI_INTB 6
|
||||
#define CONFIG_SYS_GPIO_BUTTON1 7
|
||||
#define CONFIG_SYS_GPIO_LED1 8 /* Out */
|
||||
#define CONFIG_SYS_GPIO_RTCINT 9
|
||||
#define CONFIG_SYS_GPIO_LED2 10 /* Out */
|
||||
#define CONFIG_SYS_GPIO_PCI_INTA 11
|
||||
#define CONFIG_SYS_GPIO_IORST 12 /* Out */
|
||||
#define CONFIG_SYS_GPIO_LED3 13 /* Out */
|
||||
#define CONFIG_SYS_GPIO_PCI_CLK 14 /* Out */
|
||||
#define CONFIG_SYS_GPIO_EXTBUS_CLK 15 /* Out */
|
||||
|
||||
#endif
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
#
|
||||
# (C) Copyright 2000-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-y := dvlhost.o watchdog.o
|
|
@ -1,112 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2009
|
||||
* Michael Schwingen, michael@schwingen.org
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <config.h>
|
||||
#include <command.h>
|
||||
#include <malloc.h>
|
||||
#include <asm/arch/ixp425.h>
|
||||
#include <asm/io.h>
|
||||
#include <miiphy.h>
|
||||
#ifdef CONFIG_PCI
|
||||
#include <pci.h>
|
||||
#include <asm/arch/ixp425pci.h>
|
||||
#endif
|
||||
|
||||
#include "dvlhost_hw.h"
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
/* CS1: LED Latch */
|
||||
writel(0xBFFF0002, IXP425_EXP_CS1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
/* adress of boot parameters */
|
||||
gd->bd->bi_boot_params = 0x00000100;
|
||||
|
||||
/* Setup GPIOs used as output */
|
||||
GPIO_OUTPUT_CLEAR(CONFIG_SYS_GPIO_WDGTRIGGER);
|
||||
GPIO_OUTPUT_SET(CONFIG_SYS_GPIO_DLAN_PAIRING);
|
||||
GPIO_OUTPUT_CLEAR(CONFIG_SYS_GPIO_PCIRST);
|
||||
|
||||
/*
|
||||
* LED latch enable and watchdog enable are tied to the same GPIO,
|
||||
* so we need to trigger the watchdog if we want to enable the LEDs.
|
||||
*/
|
||||
#ifdef CONFIG_HW_WATCHDOG
|
||||
GPIO_OUTPUT_CLEAR(CONFIG_SYS_GPIO_WDG_LED_EN);
|
||||
#else
|
||||
GPIO_OUTPUT_SET(CONFIG_SYS_GPIO_WDG_LED_EN);
|
||||
#endif
|
||||
|
||||
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_WDGTRIGGER);
|
||||
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_DLAN_PAIRING);
|
||||
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_WDG_LED_EN);
|
||||
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_PCIRST);
|
||||
|
||||
/* Setup GPIOs for Interrupt inputs */
|
||||
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_BTN_WLAN);
|
||||
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_BTN_PAIRING);
|
||||
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_BTN_RESET);
|
||||
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_IRQA);
|
||||
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_IRQB);
|
||||
|
||||
/* Setup GPIO's for 33MHz clock output */
|
||||
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_PCI_CLK);
|
||||
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_EXTBUS_CLK);
|
||||
writel(0x01FF01FF, IXP425_GPIO_GPCLKR);
|
||||
|
||||
/* turn off all LEDs */
|
||||
writew(0x0000, DVLHOST_LED_LATCH);
|
||||
|
||||
udelay(533);
|
||||
GPIO_OUTPUT_SET(CONFIG_SYS_GPIO_PCIRST);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check Board Identity */
|
||||
int checkboard(void)
|
||||
{
|
||||
char *s = getenv("serial#");
|
||||
|
||||
puts("Board: dLAN 200AV (dvlhost)");
|
||||
|
||||
if (s != NULL) {
|
||||
puts(", serial# ");
|
||||
puts(s);
|
||||
}
|
||||
putc('\n');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
gd->ram_size = get_ram_size(CONFIG_SYS_SDRAM_BASE, 128<<20);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
struct pci_controller hose;
|
||||
|
||||
void pci_init_board(void)
|
||||
{
|
||||
pci_ixp_init(&hose);
|
||||
}
|
||||
#endif
|
||||
|
||||
void reset_phy(void)
|
||||
{
|
||||
/* init IcPlus IP175C ethernet switch to native IP175C mode */
|
||||
miiphy_write("NPE1", 29, 31, 0x175C);
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2009
|
||||
* Michael Schwingen, michael@schwingen.org
|
||||
*
|
||||
* hardware register definitions for the
|
||||
* dLAN200 AV Wireless G ("dvlhost") board.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef _DVLHOST_HW_H
|
||||
#define _DVLHOST_HW_H
|
||||
|
||||
/*
|
||||
* GPIO settings
|
||||
*/
|
||||
#define CONFIG_SYS_GPIO_WDGTRIGGER 0 /* Out */
|
||||
#define CONFIG_SYS_GPIO_BTN_WLAN 1
|
||||
#define CONFIG_SYS_GPIO_BTN_PAIRING 6
|
||||
#define CONFIG_SYS_GPIO_DLAN_PAIRING 7 /* Out */
|
||||
#define CONFIG_SYS_GPIO_BTN_RESET 9
|
||||
#define CONFIG_SYS_GPIO_IRQB 10
|
||||
#define CONFIG_SYS_GPIO_IRQA 11
|
||||
#define CONFIG_SYS_GPIO_WDG_LED_EN 12 /* Out */
|
||||
#define CONFIG_SYS_GPIO_PCIRST 13 /* Out */
|
||||
#define CONFIG_SYS_GPIO_PCI_CLK 14 /* Out */
|
||||
#define CONFIG_SYS_GPIO_EXTBUS_CLK 15 /* Out */
|
||||
|
||||
#define DVLHOST_LED_LATCH IXP425_EXP_BUS_CS1_BASE_PHYS
|
||||
|
||||
#endif
|
|
@ -1,99 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2000
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
OUTPUT_FORMAT ("elf32-bigarm", "elf32-bigarm", "elf32-bigarm")
|
||||
OUTPUT_ARCH (arm)
|
||||
ENTRY (_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x00000000;
|
||||
|
||||
. = ALIGN (4);
|
||||
.text : {
|
||||
*(.__image_copy_start)
|
||||
arch/arm/cpu/ixp/start.o(.text*)
|
||||
net/built-in.o(.text*)
|
||||
board/dvlhost/built-in.o(.text*)
|
||||
arch/arm/cpu/ixp/built-in.o(.text*)
|
||||
drivers/serial/built-in.o(.text*)
|
||||
|
||||
. = env_offset;
|
||||
common/env_embedded.o(.ppcenv)
|
||||
*(.text*)
|
||||
}
|
||||
|
||||
. = ALIGN (4);
|
||||
.rodata : {
|
||||
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
|
||||
}
|
||||
. = ALIGN (4);
|
||||
.data : {
|
||||
*(.data*)
|
||||
}
|
||||
. = ALIGN (4);
|
||||
.got : {
|
||||
*(.got)
|
||||
}
|
||||
. =.;
|
||||
|
||||
. = ALIGN(4);
|
||||
.u_boot_list : {
|
||||
KEEP(*(SORT(.u_boot_list*)));
|
||||
}
|
||||
|
||||
. = ALIGN (4);
|
||||
|
||||
.image_copy_end :
|
||||
{
|
||||
*(.__image_copy_end)
|
||||
}
|
||||
|
||||
.rel_dyn_start :
|
||||
{
|
||||
*(.__rel_dyn_start)
|
||||
}
|
||||
|
||||
.rel.dyn : {
|
||||
*(.rel*)
|
||||
}
|
||||
|
||||
.rel_dyn_end :
|
||||
{
|
||||
*(.__rel_dyn_end)
|
||||
}
|
||||
|
||||
_end = .;
|
||||
|
||||
/*
|
||||
* Compiler-generated __bss_start and __bss_end, see arch/arm/lib/bss.c
|
||||
* __bss_base and __bss_limit are for linker only (overlay ordering)
|
||||
*/
|
||||
|
||||
.bss_start __rel_dyn_start (OVERLAY) : {
|
||||
KEEP(*(.__bss_start));
|
||||
__bss_base = .;
|
||||
}
|
||||
|
||||
.bss __bss_base (OVERLAY) : {
|
||||
*(.bss*)
|
||||
. = ALIGN(4);
|
||||
__bss_limit = .;
|
||||
}
|
||||
.bss_end __bss_limit (OVERLAY) : {
|
||||
KEEP(*(.__bss_end));
|
||||
}
|
||||
|
||||
.dynsym _end : { *(.dynsym) }
|
||||
.dynbss : { *(.dynbss) }
|
||||
.dynstr : { *(.dynstr*) }
|
||||
.dynamic : { *(.dynamic*) }
|
||||
.hash : { *(.hash*) }
|
||||
.plt : { *(.plt*) }
|
||||
.interp : { *(.interp*) }
|
||||
.gnu : { *(.gnu*) }
|
||||
.ARM.exidx : { *(.ARM.exidx*) }
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2009
|
||||
* Michael Schwingen, michael@schwingen.org
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <config.h>
|
||||
#include <asm/io.h>
|
||||
#include "dvlhost_hw.h"
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#ifdef CONFIG_HW_WATCHDOG
|
||||
#include <watchdog.h>
|
||||
#include <asm/arch/ixp425.h>
|
||||
|
||||
void hw_watchdog_reset(void)
|
||||
{
|
||||
unsigned int x;
|
||||
x = readl(IXP425_GPIO_GPOUTR);
|
||||
x ^= (1 << (CONFIG_SYS_GPIO_WDGTRIGGER));
|
||||
writel(x, IXP425_GPIO_GPOUTR);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_HW_WATCHDOG */
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
|
|
@ -6,3 +6,4 @@
|
|||
#
|
||||
|
||||
obj-y := board.o
|
||||
obj-$(CONFIG_SPL_BUILD) += ps7_init.o
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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");
|
||||
}
|
|
@ -379,14 +379,6 @@ Active arm armv7:arm720t tegra20 toradex colibri_t20_iris
|
|||
Active arm armv7:arm720t tegra30 avionic-design tec-ng tec-ng - Alban Bedel <alban.bedel@avionic-design.de>
|
||||
Active arm armv7:arm720t tegra30 nvidia beaver beaver - Tom Warren <twarren@nvidia.com>:Stephen Warren <swarren@nvidia.com>
|
||||
Active arm armv7:arm720t tegra30 nvidia cardhu cardhu - Tom Warren <twarren@nvidia.com>
|
||||
Active arm ixp - - - actux2 - Michael Schwingen <michael@schwingen.org>
|
||||
Active arm ixp - - - actux3 - Michael Schwingen <michael@schwingen.org>
|
||||
Active arm ixp - - - actux4 - Michael Schwingen <michael@schwingen.org>
|
||||
Active arm ixp - - - dvlhost - Michael Schwingen <michael@schwingen.org>
|
||||
Active arm ixp - - actux1 actux1_4_16 actux1:FLASH2X2 Michael Schwingen <michael@schwingen.org>
|
||||
Active arm ixp - - actux1 actux1_4_32 actux1:FLASH2X2,RAM_32MB Michael Schwingen <michael@schwingen.org>
|
||||
Active arm ixp - - actux1 actux1_8_16 actux1:FLASH1X8 Michael Schwingen <michael@schwingen.org>
|
||||
Active arm ixp - - actux1 actux1_8_32 actux1:FLASH1X8,RAM_32MB Michael Schwingen <michael@schwingen.org>
|
||||
Active arm pxa - - - balloon3 - Marek Vasut <marek.vasut@gmail.com>
|
||||
Active arm pxa - - - h2200 - Lukasz Dalek <luk0104@gmail.com>
|
||||
Active arm pxa - - - palmld - Marek Vasut <marek.vasut@gmail.com>
|
||||
|
|
|
@ -11,6 +11,11 @@ easily if here is something they might want to dig for...
|
|||
|
||||
Board Arch CPU Commit Removed Last known maintainer/contact
|
||||
=================================================================================================
|
||||
dvl_host arm ixp - 2014-01-28 Michael Schwingen <michael@schwingen.org>
|
||||
actux4 arm ixp - 2014-01-28 Michael Schwingen <michael@schwingen.org>
|
||||
actux3 arm ixp - 2014-01-28 Michael Schwingen <michael@schwingen.org>
|
||||
actux2 arm ixp - 2014-01-28 Michael Schwingen <michael@schwingen.org>
|
||||
actux1 arm ixp - 2014-01-28 Michael Schwingen <michael@schwingen.org>
|
||||
mx1ads arm arm920t - 2014-01-13
|
||||
mini2440 arm arm920t - 2014-01-13 Gabriel Huau <contact@huau-gabriel.fr>
|
||||
omap730p2 arm arm926ejs 79c5c08d 2013-11-11
|
||||
|
|
|
@ -125,10 +125,6 @@ III) Analysis of in-tree drivers
|
|||
Shared driver for indirect PCI bridges, several CONFIG macros - will
|
||||
require significant cleanup.
|
||||
|
||||
pci_ixp.c
|
||||
---------
|
||||
Standard driver, specifies all read/write functions separately.
|
||||
|
||||
pci_sh4.c
|
||||
---------
|
||||
Shared init function for SH4 drivers, uses dword for read/write ops.
|
||||
|
|
|
@ -101,10 +101,6 @@ III) Analysis of in-tree drivers
|
|||
No support for CONFIG_SERIAL_MULTI. Simple conversion possible. This driver
|
||||
might be removed in favor of serial_mxc.c .
|
||||
|
||||
serial_ixp.c
|
||||
------------
|
||||
No support for CONFIG_SERIAL_MULTI. Simple conversion possible.
|
||||
|
||||
serial_ks8695.c
|
||||
---------------
|
||||
No support for CONFIG_SERIAL_MULTI. Simple conversion possible.
|
||||
|
|
|
@ -29,9 +29,6 @@
|
|||
#include <asm/arch/gpio.h>
|
||||
#endif
|
||||
#endif
|
||||
#ifdef CONFIG_IXP425 /* only valid for IXP425 */
|
||||
#include <asm/arch/ixp425.h>
|
||||
#endif
|
||||
#if defined(CONFIG_MPC852T) || defined(CONFIG_MPC866)
|
||||
#include <asm/io.h>
|
||||
#endif
|
||||
|
|
|
@ -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,
|
||||
ð->mii_speed);
|
||||
register u32 speed = DIV_ROUND_UP(imx_get_fecclk(), 5000000);
|
||||
#ifdef FEC_QUIRK_ENET_MAC
|
||||
speed--;
|
||||
#endif
|
||||
speed <<= 1;
|
||||
writel(speed, ð->mii_speed);
|
||||
debug("%s: mii_speed %08x\n", __func__, readl(ð->mii_speed));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,237 +0,0 @@
|
|||
/**
|
||||
* @file IxEthAcc.c
|
||||
*
|
||||
* @author Intel Corporation
|
||||
* @date 20-Feb-2001
|
||||
*
|
||||
* @brief This file contains the implementation of the IXP425 Ethernet Access Component
|
||||
*
|
||||
* Design Notes:
|
||||
*
|
||||
* @par
|
||||
* IXP400 SW Release version 2.0
|
||||
*
|
||||
* -- Copyright Notice --
|
||||
*
|
||||
* @par
|
||||
* Copyright 2001-2005, Intel Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
* @par
|
||||
* -- End of Copyright Notice --
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "IxEthAcc.h"
|
||||
#ifdef CONFIG_IXP425_COMPONENT_ETHDB
|
||||
#include "IxEthDB.h"
|
||||
#endif
|
||||
#include "IxFeatureCtrl.h"
|
||||
|
||||
#include "IxEthAcc_p.h"
|
||||
#include "IxEthAccMac_p.h"
|
||||
#include "IxEthAccMii_p.h"
|
||||
|
||||
/**
|
||||
* @addtogroup IxEthAcc
|
||||
*@{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief System-wide information data strucure.
|
||||
*
|
||||
* @ingroup IxEthAccPri
|
||||
*
|
||||
*/
|
||||
|
||||
IxEthAccInfo ixEthAccDataInfo;
|
||||
extern PUBLIC IxEthAccMacState ixEthAccMacState[];
|
||||
extern PUBLIC IxOsalMutex ixEthAccControlInterfaceMutex;
|
||||
|
||||
/**
|
||||
* @brief System-wide information
|
||||
*
|
||||
* @ingroup IxEthAccPri
|
||||
*
|
||||
*/
|
||||
BOOL ixEthAccServiceInit = false;
|
||||
|
||||
/* global filtering bit mask */
|
||||
PUBLIC UINT32 ixEthAccNewSrcMask;
|
||||
|
||||
/**
|
||||
* @brief Per port information data strucure.
|
||||
*
|
||||
* @ingroup IxEthAccPri
|
||||
*
|
||||
*/
|
||||
|
||||
IxEthAccPortDataInfo ixEthAccPortData[IX_ETH_ACC_NUMBER_OF_PORTS];
|
||||
|
||||
PUBLIC IxEthAccStatus ixEthAccInit()
|
||||
{
|
||||
#ifdef CONFIG_IXP425_COMPONENT_ETHDB
|
||||
/*
|
||||
* Initialize Control plane
|
||||
*/
|
||||
if (ixEthDBInit() != IX_ETH_DB_SUCCESS)
|
||||
{
|
||||
IX_ETH_ACC_WARNING_LOG("ixEthAccInit: EthDB init failed\n", 0, 0, 0, 0, 0, 0);
|
||||
|
||||
return IX_ETH_ACC_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (IX_FEATURE_CTRL_SWCONFIG_ENABLED == ixFeatureCtrlSwConfigurationCheck (IX_FEATURECTRL_ETH_LEARNING))
|
||||
{
|
||||
ixEthAccNewSrcMask = (~0); /* want all the bits */
|
||||
}
|
||||
else
|
||||
{
|
||||
ixEthAccNewSrcMask = (~IX_ETHACC_NE_NEWSRCMASK); /* want all but the NewSrc bit */
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize Data plane
|
||||
*/
|
||||
if ( ixEthAccInitDataPlane() != IX_ETH_ACC_SUCCESS )
|
||||
{
|
||||
IX_ETH_ACC_WARNING_LOG("ixEthAccInit: data plane init failed\n", 0, 0, 0, 0, 0, 0);
|
||||
|
||||
return IX_ETH_ACC_FAIL;
|
||||
}
|
||||
|
||||
|
||||
if ( ixEthAccQMgrQueuesConfig() != IX_ETH_ACC_SUCCESS )
|
||||
{
|
||||
IX_ETH_ACC_WARNING_LOG("ixEthAccInit: queue config failed\n", 0, 0, 0, 0, 0, 0);
|
||||
|
||||
return IX_ETH_ACC_FAIL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize MII
|
||||
*/
|
||||
if ( ixEthAccMiiInit() != IX_ETH_ACC_SUCCESS )
|
||||
{
|
||||
IX_ETH_ACC_WARNING_LOG("ixEthAccInit: Mii init failed\n", 0, 0, 0, 0, 0, 0);
|
||||
|
||||
return IX_ETH_ACC_FAIL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize MAC I/O memory
|
||||
*/
|
||||
if (ixEthAccMacMemInit() != IX_ETH_ACC_SUCCESS)
|
||||
{
|
||||
IX_ETH_ACC_WARNING_LOG("ixEthAccInit: Mac init failed\n", 0, 0, 0, 0, 0, 0);
|
||||
|
||||
return IX_ETH_ACC_FAIL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize control plane interface lock
|
||||
*/
|
||||
if (ixOsalMutexInit(&ixEthAccControlInterfaceMutex) != IX_SUCCESS)
|
||||
{
|
||||
IX_ETH_ACC_WARNING_LOG("ixEthAccInit: Control plane interface lock initialization failed\n", 0, 0, 0, 0, 0, 0);
|
||||
|
||||
return IX_ETH_ACC_FAIL;
|
||||
}
|
||||
|
||||
/* initialiasation is complete */
|
||||
ixEthAccServiceInit = true;
|
||||
|
||||
return IX_ETH_ACC_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
PUBLIC void ixEthAccUnload(void)
|
||||
{
|
||||
IxEthAccPortId portId;
|
||||
|
||||
if ( IX_ETH_ACC_IS_SERVICE_INITIALIZED() )
|
||||
{
|
||||
/* check none of the port is still active */
|
||||
for (portId = 0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++)
|
||||
{
|
||||
if ( IX_ETH_IS_PORT_INITIALIZED(portId) )
|
||||
{
|
||||
if (ixEthAccMacState[portId].portDisableState == ACTIVE)
|
||||
{
|
||||
IX_ETH_ACC_WARNING_LOG("ixEthAccUnload: port %u still active, bail out\n", portId, 0, 0, 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* unmap the memory areas */
|
||||
ixEthAccMiiUnload();
|
||||
ixEthAccMacUnload();
|
||||
|
||||
/* set all ports as uninitialized */
|
||||
for (portId = 0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++)
|
||||
{
|
||||
ixEthAccPortData[portId].portInitialized = false;
|
||||
}
|
||||
|
||||
/* uninitialize the service */
|
||||
ixEthAccServiceInit = false;
|
||||
}
|
||||
}
|
||||
|
||||
PUBLIC IxEthAccStatus ixEthAccPortInit( IxEthAccPortId portId)
|
||||
{
|
||||
|
||||
IxEthAccStatus ret=IX_ETH_ACC_SUCCESS;
|
||||
|
||||
if ( ! IX_ETH_ACC_IS_SERVICE_INITIALIZED() )
|
||||
{
|
||||
return(IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for valid port
|
||||
*/
|
||||
|
||||
if ( ! IX_ETH_ACC_IS_PORT_VALID(portId) )
|
||||
{
|
||||
return (IX_ETH_ACC_INVALID_PORT);
|
||||
}
|
||||
|
||||
if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
|
||||
{
|
||||
IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot initialize Eth port.\n",(INT32) portId,0,0,0,0,0);
|
||||
return IX_ETH_ACC_SUCCESS ;
|
||||
}
|
||||
|
||||
if ( IX_ETH_IS_PORT_INITIALIZED(portId) )
|
||||
{
|
||||
/* Already initialized */
|
||||
return(IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
if(ixEthAccMacInit(portId)!=IX_ETH_ACC_SUCCESS)
|
||||
{
|
||||
return IX_ETH_ACC_FAIL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the port init flag.
|
||||
*/
|
||||
|
||||
ixEthAccPortData[portId].portInitialized = true;
|
||||
|
||||
#ifdef CONFIG_IXP425_COMPONENT_ETHDB
|
||||
/* init learning/filtering database structures for this port */
|
||||
ixEthDBPortInit(portId);
|
||||
#endif
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -1,509 +0,0 @@
|
|||
/**
|
||||
* @file IxEthAccControlInterface.c
|
||||
*
|
||||
* @author Intel Corporation
|
||||
* @date
|
||||
*
|
||||
* @brief IX_ETH_ACC_PUBLIC wrappers for control plane functions
|
||||
*
|
||||
* Design Notes:
|
||||
*
|
||||
* @par
|
||||
* IXP400 SW Release version 2.0
|
||||
*
|
||||
* -- Copyright Notice --
|
||||
*
|
||||
* @par
|
||||
* Copyright 2001-2005, Intel Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
* @par
|
||||
* -- End of Copyright Notice --
|
||||
*/
|
||||
|
||||
#include "IxOsal.h"
|
||||
#include "IxEthAcc.h"
|
||||
#include "IxEthAcc_p.h"
|
||||
|
||||
PUBLIC IxOsalMutex ixEthAccControlInterfaceMutex;
|
||||
|
||||
IX_ETH_ACC_PUBLIC IxEthAccStatus
|
||||
ixEthAccPortEnable(IxEthAccPortId portId)
|
||||
{
|
||||
IxEthAccStatus result;
|
||||
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
printf("EthAcc: (Mac) cannot enable port %d, service not initialized\n", portId);
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
|
||||
result = ixEthAccPortEnablePriv(portId);
|
||||
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
IX_ETH_ACC_PUBLIC IxEthAccStatus
|
||||
ixEthAccPortDisable(IxEthAccPortId portId)
|
||||
{
|
||||
IxEthAccStatus result;
|
||||
|
||||
/* check the context is iinitialized */
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
|
||||
result = ixEthAccPortDisablePriv(portId);
|
||||
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
IX_ETH_ACC_PUBLIC IxEthAccStatus
|
||||
ixEthAccPortEnabledQuery(IxEthAccPortId portId, BOOL *enabled)
|
||||
{
|
||||
IxEthAccStatus result;
|
||||
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
|
||||
result = ixEthAccPortEnabledQueryPriv(portId, enabled);
|
||||
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
IX_ETH_ACC_PUBLIC IxEthAccStatus
|
||||
ixEthAccPortPromiscuousModeClear(IxEthAccPortId portId)
|
||||
{
|
||||
IxEthAccStatus result;
|
||||
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
|
||||
result = ixEthAccPortPromiscuousModeClearPriv(portId);
|
||||
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
IX_ETH_ACC_PUBLIC IxEthAccStatus
|
||||
ixEthAccPortPromiscuousModeSet(IxEthAccPortId portId)
|
||||
{
|
||||
IxEthAccStatus result;
|
||||
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
|
||||
result = ixEthAccPortPromiscuousModeSetPriv(portId);
|
||||
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
IX_ETH_ACC_PUBLIC IxEthAccStatus
|
||||
ixEthAccPortUnicastMacAddressSet(IxEthAccPortId portId, IxEthAccMacAddr *macAddr)
|
||||
{
|
||||
IxEthAccStatus result;
|
||||
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
|
||||
result = ixEthAccPortUnicastMacAddressSetPriv(portId, macAddr);
|
||||
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
IX_ETH_ACC_PUBLIC IxEthAccStatus
|
||||
ixEthAccPortUnicastMacAddressGet(IxEthAccPortId portId, IxEthAccMacAddr *macAddr)
|
||||
{
|
||||
IxEthAccStatus result;
|
||||
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
|
||||
result = ixEthAccPortUnicastMacAddressGetPriv(portId, macAddr);
|
||||
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
IX_ETH_ACC_PUBLIC IxEthAccStatus
|
||||
ixEthAccPortMulticastAddressJoin(IxEthAccPortId portId, IxEthAccMacAddr *macAddr)
|
||||
{
|
||||
IxEthAccStatus result;
|
||||
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
|
||||
result = ixEthAccPortMulticastAddressJoinPriv(portId, macAddr);
|
||||
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
IX_ETH_ACC_PUBLIC IxEthAccStatus
|
||||
ixEthAccPortMulticastAddressJoinAll(IxEthAccPortId portId)
|
||||
{
|
||||
IxEthAccStatus result;
|
||||
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
|
||||
result = ixEthAccPortMulticastAddressJoinAllPriv(portId);
|
||||
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
IX_ETH_ACC_PUBLIC IxEthAccStatus
|
||||
ixEthAccPortMulticastAddressLeave(IxEthAccPortId portId, IxEthAccMacAddr *macAddr)
|
||||
{
|
||||
IxEthAccStatus result;
|
||||
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
|
||||
result = ixEthAccPortMulticastAddressLeavePriv(portId, macAddr);
|
||||
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
IX_ETH_ACC_PUBLIC IxEthAccStatus
|
||||
ixEthAccPortMulticastAddressLeaveAll(IxEthAccPortId portId)
|
||||
{
|
||||
IxEthAccStatus result;
|
||||
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
|
||||
result = ixEthAccPortMulticastAddressLeaveAllPriv(portId);
|
||||
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
IX_ETH_ACC_PUBLIC IxEthAccStatus
|
||||
ixEthAccPortUnicastAddressShow(IxEthAccPortId portId)
|
||||
{
|
||||
IxEthAccStatus result;
|
||||
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
|
||||
result = ixEthAccPortUnicastAddressShowPriv(portId);
|
||||
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
IX_ETH_ACC_PUBLIC void
|
||||
ixEthAccPortMulticastAddressShow(IxEthAccPortId portId)
|
||||
{
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
|
||||
ixEthAccPortMulticastAddressShowPriv(portId);
|
||||
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
|
||||
}
|
||||
|
||||
IX_ETH_ACC_PUBLIC IxEthAccStatus
|
||||
ixEthAccPortDuplexModeSet(IxEthAccPortId portId, IxEthAccDuplexMode mode)
|
||||
{
|
||||
IxEthAccStatus result;
|
||||
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
|
||||
result = ixEthAccPortDuplexModeSetPriv(portId, mode);
|
||||
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
IX_ETH_ACC_PUBLIC IxEthAccStatus
|
||||
ixEthAccPortDuplexModeGet(IxEthAccPortId portId, IxEthAccDuplexMode *mode)
|
||||
{
|
||||
IxEthAccStatus result;
|
||||
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
|
||||
result = ixEthAccPortDuplexModeGetPriv(portId, mode);
|
||||
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
IX_ETH_ACC_PUBLIC IxEthAccStatus
|
||||
ixEthAccPortTxFrameAppendPaddingEnable(IxEthAccPortId portId)
|
||||
{
|
||||
IxEthAccStatus result;
|
||||
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
|
||||
result = ixEthAccPortTxFrameAppendPaddingEnablePriv(portId);
|
||||
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
IX_ETH_ACC_PUBLIC IxEthAccStatus
|
||||
ixEthAccPortTxFrameAppendPaddingDisable(IxEthAccPortId portId)
|
||||
{
|
||||
IxEthAccStatus result;
|
||||
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
|
||||
result = ixEthAccPortTxFrameAppendPaddingDisablePriv(portId);
|
||||
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
IX_ETH_ACC_PUBLIC IxEthAccStatus
|
||||
ixEthAccPortTxFrameAppendFCSEnable(IxEthAccPortId portId)
|
||||
{
|
||||
IxEthAccStatus result;
|
||||
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
|
||||
result = ixEthAccPortTxFrameAppendFCSEnablePriv(portId);
|
||||
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
IX_ETH_ACC_PUBLIC IxEthAccStatus
|
||||
ixEthAccPortTxFrameAppendFCSDisable(IxEthAccPortId portId)
|
||||
{
|
||||
IxEthAccStatus result;
|
||||
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
|
||||
result = ixEthAccPortTxFrameAppendFCSDisablePriv(portId);
|
||||
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
IX_ETH_ACC_PUBLIC IxEthAccStatus
|
||||
ixEthAccPortRxFrameAppendFCSEnable(IxEthAccPortId portId)
|
||||
{
|
||||
IxEthAccStatus result;
|
||||
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
|
||||
result = ixEthAccPortRxFrameAppendFCSEnablePriv(portId);
|
||||
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
IX_ETH_ACC_PUBLIC IxEthAccStatus
|
||||
ixEthAccPortRxFrameAppendFCSDisable(IxEthAccPortId portId)
|
||||
{
|
||||
IxEthAccStatus result;
|
||||
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
|
||||
result = ixEthAccPortRxFrameAppendFCSDisablePriv(portId);
|
||||
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
IX_ETH_ACC_PUBLIC IxEthAccStatus
|
||||
ixEthAccTxSchedulingDisciplineSet(IxEthAccPortId portId, IxEthAccSchedulerDiscipline sched)
|
||||
{
|
||||
IxEthAccStatus result;
|
||||
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
|
||||
result = ixEthAccTxSchedulingDisciplineSetPriv(portId, sched);
|
||||
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
IX_ETH_ACC_PUBLIC IxEthAccStatus
|
||||
ixEthAccRxSchedulingDisciplineSet(IxEthAccSchedulerDiscipline sched)
|
||||
{
|
||||
IxEthAccStatus result;
|
||||
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
|
||||
result = ixEthAccRxSchedulingDisciplineSetPriv(sched);
|
||||
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
IX_ETH_ACC_PUBLIC IxEthAccStatus
|
||||
ixEthAccPortNpeLoopbackEnable(IxEthAccPortId portId)
|
||||
{
|
||||
IxEthAccStatus result;
|
||||
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
|
||||
result = ixEthAccNpeLoopbackEnablePriv(portId);
|
||||
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
IX_ETH_ACC_PUBLIC IxEthAccStatus
|
||||
ixEthAccPortTxEnable(IxEthAccPortId portId)
|
||||
{
|
||||
IxEthAccStatus result;
|
||||
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
|
||||
result = ixEthAccPortTxEnablePriv(portId);
|
||||
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
IX_ETH_ACC_PUBLIC IxEthAccStatus
|
||||
ixEthAccPortRxEnable(IxEthAccPortId portId)
|
||||
{
|
||||
IxEthAccStatus result;
|
||||
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
|
||||
result = ixEthAccPortRxEnablePriv(portId);
|
||||
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
IX_ETH_ACC_PUBLIC IxEthAccStatus
|
||||
ixEthAccPortNpeLoopbackDisable(IxEthAccPortId portId)
|
||||
{
|
||||
IxEthAccStatus result;
|
||||
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
|
||||
result = ixEthAccNpeLoopbackDisablePriv(portId);
|
||||
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
IX_ETH_ACC_PUBLIC IxEthAccStatus
|
||||
ixEthAccPortTxDisable(IxEthAccPortId portId)
|
||||
{
|
||||
IxEthAccStatus result;
|
||||
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
|
||||
result = ixEthAccPortTxDisablePriv(portId);
|
||||
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
IX_ETH_ACC_PUBLIC IxEthAccStatus
|
||||
ixEthAccPortRxDisable(IxEthAccPortId portId)
|
||||
{
|
||||
IxEthAccStatus result;
|
||||
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
|
||||
result = ixEthAccPortRxDisablePriv(portId);
|
||||
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
IX_ETH_ACC_PUBLIC IxEthAccStatus
|
||||
ixEthAccPortMacReset(IxEthAccPortId portId)
|
||||
{
|
||||
IxEthAccStatus result;
|
||||
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
|
||||
result = ixEthAccPortMacResetPriv(portId);
|
||||
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
|
||||
return result;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,386 +0,0 @@
|
|||
/**
|
||||
* @file IxEthAccMii.c
|
||||
*
|
||||
* @author Intel Corporation
|
||||
* @date
|
||||
*
|
||||
* @brief MII control functions
|
||||
*
|
||||
* Design Notes:
|
||||
*
|
||||
* IXP400 SW Release version 2.0
|
||||
*
|
||||
* -- Copyright Notice --
|
||||
*
|
||||
* @par
|
||||
* Copyright 2001-2005, Intel Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
* @par
|
||||
* -- End of Copyright Notice --
|
||||
*/
|
||||
|
||||
#include "IxOsal.h"
|
||||
#include "IxEthAcc.h"
|
||||
#include "IxEthAcc_p.h"
|
||||
#include "IxEthAccMac_p.h"
|
||||
#include "IxEthAccMii_p.h"
|
||||
|
||||
|
||||
PRIVATE UINT32 miiBaseAddressVirt;
|
||||
PRIVATE IxOsalMutex miiAccessLock;
|
||||
|
||||
PUBLIC UINT32 ixEthAccMiiRetryCount = IX_ETH_ACC_MII_TIMEOUT_10TH_SECS;
|
||||
PUBLIC UINT32 ixEthAccMiiAccessTimeout = IX_ETH_ACC_MII_10TH_SEC_IN_MILLIS;
|
||||
|
||||
/* -----------------------------------
|
||||
* private function prototypes
|
||||
*/
|
||||
PRIVATE void
|
||||
ixEthAccMdioCmdWrite(UINT32 mdioCommand);
|
||||
|
||||
PRIVATE void
|
||||
ixEthAccMdioCmdRead(UINT32 *data);
|
||||
|
||||
PRIVATE void
|
||||
ixEthAccMdioStatusRead(UINT32 *data);
|
||||
|
||||
|
||||
PRIVATE void
|
||||
ixEthAccMdioCmdWrite(UINT32 mdioCommand)
|
||||
{
|
||||
REG_WRITE(miiBaseAddressVirt,
|
||||
IX_ETH_ACC_MAC_MDIO_CMD_1,
|
||||
mdioCommand & 0xff);
|
||||
|
||||
REG_WRITE(miiBaseAddressVirt,
|
||||
IX_ETH_ACC_MAC_MDIO_CMD_2,
|
||||
(mdioCommand >> 8) & 0xff);
|
||||
|
||||
REG_WRITE(miiBaseAddressVirt,
|
||||
IX_ETH_ACC_MAC_MDIO_CMD_3,
|
||||
(mdioCommand >> 16) & 0xff);
|
||||
|
||||
REG_WRITE(miiBaseAddressVirt,
|
||||
IX_ETH_ACC_MAC_MDIO_CMD_4,
|
||||
(mdioCommand >> 24) & 0xff);
|
||||
}
|
||||
|
||||
PRIVATE void
|
||||
ixEthAccMdioCmdRead(UINT32 *data)
|
||||
{
|
||||
UINT32 regval;
|
||||
|
||||
REG_READ(miiBaseAddressVirt,
|
||||
IX_ETH_ACC_MAC_MDIO_CMD_1,
|
||||
regval);
|
||||
|
||||
*data = regval & 0xff;
|
||||
|
||||
REG_READ(miiBaseAddressVirt,
|
||||
IX_ETH_ACC_MAC_MDIO_CMD_2,
|
||||
regval);
|
||||
|
||||
*data |= (regval & 0xff) << 8;
|
||||
|
||||
REG_READ(miiBaseAddressVirt,
|
||||
IX_ETH_ACC_MAC_MDIO_CMD_3,
|
||||
regval);
|
||||
|
||||
*data |= (regval & 0xff) << 16;
|
||||
|
||||
REG_READ(miiBaseAddressVirt,
|
||||
IX_ETH_ACC_MAC_MDIO_CMD_4,
|
||||
regval);
|
||||
|
||||
*data |= (regval & 0xff) << 24;
|
||||
|
||||
}
|
||||
|
||||
PRIVATE void
|
||||
ixEthAccMdioStatusRead(UINT32 *data)
|
||||
{
|
||||
UINT32 regval;
|
||||
|
||||
REG_READ(miiBaseAddressVirt,
|
||||
IX_ETH_ACC_MAC_MDIO_STS_1,
|
||||
regval);
|
||||
|
||||
*data = regval & 0xff;
|
||||
|
||||
REG_READ(miiBaseAddressVirt,
|
||||
IX_ETH_ACC_MAC_MDIO_STS_2,
|
||||
regval);
|
||||
|
||||
*data |= (regval & 0xff) << 8;
|
||||
|
||||
REG_READ(miiBaseAddressVirt,
|
||||
IX_ETH_ACC_MAC_MDIO_STS_3,
|
||||
regval);
|
||||
|
||||
*data |= (regval & 0xff) << 16;
|
||||
|
||||
REG_READ(miiBaseAddressVirt,
|
||||
IX_ETH_ACC_MAC_MDIO_STS_4,
|
||||
regval);
|
||||
|
||||
*data |= (regval & 0xff) << 24;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* ixEthAccMiiInit
|
||||
*/
|
||||
IxEthAccStatus
|
||||
ixEthAccMiiInit()
|
||||
{
|
||||
if(ixOsalMutexInit(&miiAccessLock)!= IX_SUCCESS)
|
||||
{
|
||||
return IX_ETH_ACC_FAIL;
|
||||
}
|
||||
|
||||
miiBaseAddressVirt = (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_0_BASE, IX_OSAL_IXP400_ETHA_MAP_SIZE);
|
||||
|
||||
if (miiBaseAddressVirt == 0)
|
||||
{
|
||||
ixOsalLog(IX_OSAL_LOG_LVL_FATAL,
|
||||
IX_OSAL_LOG_DEV_STDOUT,
|
||||
"EthAcc: Could not map MII I/O mapped memory\n",
|
||||
0, 0, 0, 0, 0, 0);
|
||||
|
||||
return IX_ETH_ACC_FAIL;
|
||||
}
|
||||
|
||||
return IX_ETH_ACC_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
ixEthAccMiiUnload(void)
|
||||
{
|
||||
IX_OSAL_MEM_UNMAP(miiBaseAddressVirt);
|
||||
|
||||
miiBaseAddressVirt = 0;
|
||||
}
|
||||
|
||||
PUBLIC IxEthAccStatus
|
||||
ixEthAccMiiAccessTimeoutSet(UINT32 timeout, UINT32 retryCount)
|
||||
{
|
||||
if (retryCount < 1) return IX_ETH_ACC_FAIL;
|
||||
|
||||
ixEthAccMiiRetryCount = retryCount;
|
||||
ixEthAccMiiAccessTimeout = timeout;
|
||||
|
||||
return IX_ETH_ACC_SUCCESS;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* ixEthAccMiiReadRtn - read a 16 bit value from a PHY
|
||||
*/
|
||||
IxEthAccStatus
|
||||
ixEthAccMiiReadRtn (UINT8 phyAddr,
|
||||
UINT8 phyReg,
|
||||
UINT16 *value)
|
||||
{
|
||||
UINT32 mdioCommand;
|
||||
UINT32 regval;
|
||||
UINT32 miiTimeout;
|
||||
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
if ((phyAddr >= IXP425_ETH_ACC_MII_MAX_ADDR)
|
||||
|| (phyReg >= IXP425_ETH_ACC_MII_MAX_REG))
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
if (value == NULL)
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER);
|
||||
mdioCommand = phyReg << IX_ETH_ACC_MII_REG_SHL
|
||||
| phyAddr << IX_ETH_ACC_MII_ADDR_SHL;
|
||||
mdioCommand |= IX_ETH_ACC_MII_GO;
|
||||
|
||||
ixEthAccMdioCmdWrite(mdioCommand);
|
||||
|
||||
miiTimeout = ixEthAccMiiRetryCount;
|
||||
|
||||
while(miiTimeout)
|
||||
{
|
||||
|
||||
ixEthAccMdioCmdRead(®val);
|
||||
|
||||
if((regval & IX_ETH_ACC_MII_GO) == 0x0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
/* Sleep for a while */
|
||||
ixOsalSleep(ixEthAccMiiAccessTimeout);
|
||||
miiTimeout--;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(miiTimeout == 0)
|
||||
{
|
||||
ixOsalMutexUnlock(&miiAccessLock);
|
||||
*value = 0xffff;
|
||||
return IX_ETH_ACC_FAIL;
|
||||
}
|
||||
|
||||
|
||||
ixEthAccMdioStatusRead(®val);
|
||||
if(regval & IX_ETH_ACC_MII_READ_FAIL)
|
||||
{
|
||||
ixOsalMutexUnlock(&miiAccessLock);
|
||||
*value = 0xffff;
|
||||
return IX_ETH_ACC_FAIL;
|
||||
}
|
||||
|
||||
*value = regval & 0xffff;
|
||||
ixOsalMutexUnlock(&miiAccessLock);
|
||||
return IX_ETH_ACC_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* ixEthAccMiiWriteRtn - write a 16 bit value to a PHY
|
||||
*/
|
||||
IxEthAccStatus
|
||||
ixEthAccMiiWriteRtn (UINT8 phyAddr,
|
||||
UINT8 phyReg,
|
||||
UINT16 value)
|
||||
{
|
||||
UINT32 mdioCommand;
|
||||
UINT32 regval;
|
||||
UINT16 readVal;
|
||||
UINT32 miiTimeout;
|
||||
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
if ((phyAddr >= IXP425_ETH_ACC_MII_MAX_ADDR)
|
||||
|| (phyReg >= IXP425_ETH_ACC_MII_MAX_REG))
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
/* ensure that a PHY is present at this address */
|
||||
if(ixEthAccMiiReadRtn(phyAddr,
|
||||
IX_ETH_ACC_MII_CTRL_REG,
|
||||
&readVal) != IX_ETH_ACC_SUCCESS)
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER);
|
||||
mdioCommand = phyReg << IX_ETH_ACC_MII_REG_SHL
|
||||
| phyAddr << IX_ETH_ACC_MII_ADDR_SHL ;
|
||||
mdioCommand |= IX_ETH_ACC_MII_GO | IX_ETH_ACC_MII_WRITE | value;
|
||||
|
||||
ixEthAccMdioCmdWrite(mdioCommand);
|
||||
|
||||
miiTimeout = ixEthAccMiiRetryCount;
|
||||
|
||||
while(miiTimeout)
|
||||
{
|
||||
|
||||
ixEthAccMdioCmdRead(®val);
|
||||
|
||||
/*The "GO" bit is reset to 0 when the write completes*/
|
||||
if((regval & IX_ETH_ACC_MII_GO) == 0x0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
/* Sleep for a while */
|
||||
ixOsalSleep(ixEthAccMiiAccessTimeout);
|
||||
miiTimeout--;
|
||||
}
|
||||
|
||||
ixOsalMutexUnlock(&miiAccessLock);
|
||||
if(miiTimeout == 0)
|
||||
{
|
||||
return IX_ETH_ACC_FAIL;
|
||||
}
|
||||
return IX_ETH_ACC_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************
|
||||
*
|
||||
* Phy query functions
|
||||
*
|
||||
*/
|
||||
IxEthAccStatus
|
||||
ixEthAccMiiStatsShow (UINT32 phyAddr)
|
||||
{
|
||||
UINT16 regval;
|
||||
printf("Regisers on PHY at address 0x%x\n", phyAddr);
|
||||
ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_CTRL_REG, ®val);
|
||||
printf(" Control Register : 0x%4.4x\n", regval);
|
||||
ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_STAT_REG, ®val);
|
||||
printf(" Status Register : 0x%4.4x\n", regval);
|
||||
ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_PHY_ID1_REG, ®val);
|
||||
printf(" PHY ID1 Register : 0x%4.4x\n", regval);
|
||||
ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_PHY_ID2_REG, ®val);
|
||||
printf(" PHY ID2 Register : 0x%4.4x\n", regval);
|
||||
ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_ADS_REG, ®val);
|
||||
printf(" Auto Neg ADS Register : 0x%4.4x\n", regval);
|
||||
ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_PRTN_REG, ®val);
|
||||
printf(" Auto Neg Partner Ability Register : 0x%4.4x\n", regval);
|
||||
ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_EXP_REG, ®val);
|
||||
printf(" Auto Neg Expansion Register : 0x%4.4x\n", regval);
|
||||
ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_NEXT_REG, ®val);
|
||||
printf(" Auto Neg Next Register : 0x%4.4x\n", regval);
|
||||
|
||||
return IX_ETH_ACC_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************
|
||||
*
|
||||
* Interface query functions
|
||||
*
|
||||
*/
|
||||
IxEthAccStatus
|
||||
ixEthAccMdioShow (void)
|
||||
{
|
||||
UINT32 regval;
|
||||
|
||||
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
|
||||
{
|
||||
return (IX_ETH_ACC_FAIL);
|
||||
}
|
||||
|
||||
ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER);
|
||||
ixEthAccMdioCmdRead(®val);
|
||||
ixOsalMutexUnlock(&miiAccessLock);
|
||||
|
||||
printf("MDIO command register\n");
|
||||
printf(" Go bit : 0x%x\n", (regval & BIT(31)) >> 31);
|
||||
printf(" MDIO Write : 0x%x\n", (regval & BIT(26)) >> 26);
|
||||
printf(" PHY address : 0x%x\n", (regval >> 21) & 0x1f);
|
||||
printf(" Reg address : 0x%x\n", (regval >> 16) & 0x1f);
|
||||
|
||||
ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER);
|
||||
ixEthAccMdioStatusRead(®val);
|
||||
ixOsalMutexUnlock(&miiAccessLock);
|
||||
|
||||
printf("MDIO status register\n");
|
||||
printf(" Read OK : 0x%x\n", (regval & BIT(31)) >> 31);
|
||||
printf(" Read Data : 0x%x\n", (regval >> 16) & 0xff);
|
||||
|
||||
return IX_ETH_ACC_SUCCESS;
|
||||
}
|
||||
|
|
@ -1,424 +0,0 @@
|
|||
/**
|
||||
* @file IxEthDBAPI.c
|
||||
*
|
||||
* @brief Implementation of the public API
|
||||
*
|
||||
* @par
|
||||
* IXP400 SW Release version 2.0
|
||||
*
|
||||
* -- Copyright Notice --
|
||||
*
|
||||
* @par
|
||||
* Copyright 2001-2005, Intel Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
* @par
|
||||
* -- End of Copyright Notice --
|
||||
*/
|
||||
|
||||
#include "IxEthDB_p.h"
|
||||
#include "IxFeatureCtrl.h"
|
||||
|
||||
extern HashTable dbHashtable;
|
||||
extern IxEthDBPortMap overflowUpdatePortList;
|
||||
extern BOOL ixEthDBPortUpdateRequired[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1];
|
||||
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBFilteringStaticEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
|
||||
{
|
||||
IX_ETH_DB_CHECK_PORT(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_REFERENCE(macAddr);
|
||||
|
||||
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
|
||||
|
||||
return ixEthDBTriggerAddPortUpdate(macAddr, portID, true);
|
||||
}
|
||||
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBFilteringDynamicEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
|
||||
{
|
||||
IX_ETH_DB_CHECK_PORT(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_REFERENCE(macAddr);
|
||||
|
||||
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
|
||||
|
||||
return ixEthDBTriggerAddPortUpdate(macAddr, portID, false);
|
||||
}
|
||||
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBFilteringEntryDelete(IxEthDBMacAddr *macAddr)
|
||||
{
|
||||
HashNode *searchResult;
|
||||
|
||||
IX_ETH_DB_CHECK_REFERENCE(macAddr);
|
||||
|
||||
searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
|
||||
|
||||
if (searchResult == NULL)
|
||||
{
|
||||
return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
|
||||
}
|
||||
|
||||
ixEthDBReleaseHashNode(searchResult);
|
||||
|
||||
/* build a remove event and place it on the event queue */
|
||||
return ixEthDBTriggerRemovePortUpdate(macAddr, ((MacDescriptor *) searchResult->data)->portID);
|
||||
}
|
||||
|
||||
IX_ETH_DB_PUBLIC
|
||||
void ixEthDBDatabaseMaintenance()
|
||||
{
|
||||
HashIterator iterator;
|
||||
UINT32 portIndex;
|
||||
BOOL agingRequired = false;
|
||||
|
||||
/* ports who will have deleted records and therefore will need updating */
|
||||
IxEthDBPortMap triggerPorts;
|
||||
|
||||
if (IX_FEATURE_CTRL_SWCONFIG_ENABLED !=
|
||||
ixFeatureCtrlSwConfigurationCheck (IX_FEATURECTRL_ETH_LEARNING))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SET_EMPTY_DEPENDENCY_MAP(triggerPorts);
|
||||
|
||||
/* check if there's at least a port that needs aging */
|
||||
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
|
||||
{
|
||||
if (ixEthDBPortInfo[portIndex].agingEnabled && ixEthDBPortInfo[portIndex].enabled)
|
||||
{
|
||||
agingRequired = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (agingRequired)
|
||||
{
|
||||
/* ask each NPE port to write back the database for aging inspection */
|
||||
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
|
||||
{
|
||||
if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE
|
||||
&& ixEthDBPortInfo[portIndex].agingEnabled
|
||||
&& ixEthDBPortInfo[portIndex].enabled)
|
||||
{
|
||||
IxNpeMhMessage message;
|
||||
IX_STATUS result;
|
||||
|
||||
/* send EDB_GetMACAddressDatabase message */
|
||||
FILL_GETMACADDRESSDATABASE(message,
|
||||
0 /* unused */,
|
||||
IX_OSAL_MMU_VIRT_TO_PHYS(ixEthDBPortInfo[portIndex].updateMethod.npeUpdateZone));
|
||||
|
||||
IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portIndex), message, result);
|
||||
|
||||
if (result == IX_SUCCESS)
|
||||
{
|
||||
/* analyze NPE copy */
|
||||
ixEthDBNPESyncScan(portIndex, ixEthDBPortInfo[portIndex].updateMethod.npeUpdateZone, FULL_ELT_BYTE_SIZE);
|
||||
|
||||
IX_ETH_DB_SUPPORT_TRACE("DB: (API) Finished scanning NPE tree on port %d\n", portIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
ixEthDBPortInfo[portIndex].agingEnabled = false;
|
||||
ixEthDBPortInfo[portIndex].updateMethod.updateEnabled = false;
|
||||
ixEthDBPortInfo[portIndex].updateMethod.userControlled = true;
|
||||
|
||||
ixOsalLog(IX_OSAL_LOG_LVL_FATAL,
|
||||
IX_OSAL_LOG_DEV_STDOUT,
|
||||
"EthDB: (Maintenance) warning, disabling aging and updates for port %d (assumed dead)\n",
|
||||
portIndex, 0, 0, 0, 0, 0);
|
||||
|
||||
ixEthDBDatabaseClear(portIndex, IX_ETH_DB_ALL_RECORD_TYPES);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* browse database and age entries */
|
||||
BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
|
||||
|
||||
while (IS_ITERATOR_VALID(&iterator))
|
||||
{
|
||||
MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
|
||||
UINT32 *age = NULL;
|
||||
BOOL staticEntry = true;
|
||||
|
||||
if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
|
||||
{
|
||||
age = &descriptor->recordData.filteringData.age;
|
||||
staticEntry = descriptor->recordData.filteringData.staticEntry;
|
||||
}
|
||||
else if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD)
|
||||
{
|
||||
age = &descriptor->recordData.filteringVlanData.age;
|
||||
staticEntry = descriptor->recordData.filteringVlanData.staticEntry;
|
||||
}
|
||||
else
|
||||
{
|
||||
staticEntry = true;
|
||||
}
|
||||
|
||||
if (ixEthDBPortInfo[descriptor->portID].agingEnabled && (staticEntry == false))
|
||||
{
|
||||
/* manually increment the age if the port has no such capability */
|
||||
if ((ixEthDBPortDefinitions[descriptor->portID].capabilities & IX_ETH_ENTRY_AGING) == 0)
|
||||
{
|
||||
*age += (IX_ETH_DB_MAINTENANCE_TIME / 60);
|
||||
}
|
||||
|
||||
/* age entry if it exceeded the maximum time to live */
|
||||
if (*age >= (IX_ETH_DB_LEARNING_ENTRY_AGE_TIME / 60))
|
||||
{
|
||||
/* add port to the set of update trigger ports */
|
||||
JOIN_PORT_TO_MAP(triggerPorts, descriptor->portID);
|
||||
|
||||
/* delete entry */
|
||||
BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* move to the next record */
|
||||
BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* move to the next record */
|
||||
BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
|
||||
}
|
||||
}
|
||||
|
||||
/* update ports which lost records */
|
||||
ixEthDBUpdatePortLearningTrees(triggerPorts);
|
||||
}
|
||||
}
|
||||
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBDatabaseClear(IxEthDBPortId portID, IxEthDBRecordType recordType)
|
||||
{
|
||||
IxEthDBPortMap triggerPorts;
|
||||
HashIterator iterator;
|
||||
|
||||
if (portID >= IX_ETH_DB_NUMBER_OF_PORTS && portID != IX_ETH_DB_ALL_PORTS)
|
||||
{
|
||||
return IX_ETH_DB_INVALID_PORT;
|
||||
}
|
||||
|
||||
/* check if the user passes some extra bits */
|
||||
if ((recordType | IX_ETH_DB_ALL_RECORD_TYPES) != IX_ETH_DB_ALL_RECORD_TYPES)
|
||||
{
|
||||
return IX_ETH_DB_INVALID_ARG;
|
||||
}
|
||||
|
||||
SET_EMPTY_DEPENDENCY_MAP(triggerPorts);
|
||||
|
||||
/* browse database and age entries */
|
||||
BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
|
||||
|
||||
while (IS_ITERATOR_VALID(&iterator))
|
||||
{
|
||||
MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
|
||||
|
||||
if (((descriptor->portID == portID) || (portID == IX_ETH_DB_ALL_PORTS))
|
||||
&& ((descriptor->type & recordType) != 0))
|
||||
{
|
||||
/* add to trigger if automatic updates are required */
|
||||
if (ixEthDBPortUpdateRequired[descriptor->type])
|
||||
{
|
||||
/* add port to the set of update trigger ports */
|
||||
JOIN_PORT_TO_MAP(triggerPorts, descriptor->portID);
|
||||
}
|
||||
|
||||
/* delete entry */
|
||||
BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* move to the next record */
|
||||
BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
|
||||
}
|
||||
}
|
||||
|
||||
/* update ports which lost records */
|
||||
ixEthDBUpdatePortLearningTrees(triggerPorts);
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBFilteringPortSearch(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
|
||||
{
|
||||
HashNode *searchResult;
|
||||
IxEthDBStatus result = IX_ETH_DB_NO_SUCH_ADDR;
|
||||
|
||||
IX_ETH_DB_CHECK_PORT(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_REFERENCE(macAddr);
|
||||
|
||||
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
|
||||
|
||||
searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
|
||||
|
||||
if (searchResult == NULL)
|
||||
{
|
||||
return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
|
||||
}
|
||||
|
||||
if (((MacDescriptor *) (searchResult->data))->portID == portID)
|
||||
{
|
||||
result = IX_ETH_DB_SUCCESS; /* address and port match */
|
||||
}
|
||||
|
||||
ixEthDBReleaseHashNode(searchResult);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBFilteringDatabaseSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr)
|
||||
{
|
||||
HashNode *searchResult;
|
||||
|
||||
IX_ETH_DB_CHECK_REFERENCE(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_REFERENCE(macAddr);
|
||||
|
||||
searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
|
||||
|
||||
if (searchResult == NULL)
|
||||
{
|
||||
return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
|
||||
}
|
||||
|
||||
/* return the port ID */
|
||||
*portID = ((MacDescriptor *) searchResult->data)->portID;
|
||||
|
||||
ixEthDBReleaseHashNode(searchResult);
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBPortAgingDisable(IxEthDBPortId portID)
|
||||
{
|
||||
IX_ETH_DB_CHECK_PORT(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
|
||||
|
||||
ixEthDBPortInfo[portID].agingEnabled = false;
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBPortAgingEnable(IxEthDBPortId portID)
|
||||
{
|
||||
IX_ETH_DB_CHECK_PORT(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
|
||||
|
||||
ixEthDBPortInfo[portID].agingEnabled = true;
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBFilteringPortUpdatingSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr)
|
||||
{
|
||||
HashNode *searchResult;
|
||||
MacDescriptor *descriptor;
|
||||
|
||||
IX_ETH_DB_CHECK_REFERENCE(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_REFERENCE(macAddr);
|
||||
|
||||
searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
|
||||
|
||||
if (searchResult == NULL)
|
||||
{
|
||||
return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
|
||||
}
|
||||
|
||||
descriptor = (MacDescriptor *) searchResult->data;
|
||||
|
||||
/* return the port ID */
|
||||
*portID = descriptor->portID;
|
||||
|
||||
/* reset entry age */
|
||||
if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
|
||||
{
|
||||
descriptor->recordData.filteringData.age = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
descriptor->recordData.filteringVlanData.age = 0;
|
||||
}
|
||||
|
||||
ixEthDBReleaseHashNode(searchResult);
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBPortDependencyMapSet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap)
|
||||
{
|
||||
IX_ETH_DB_CHECK_PORT(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_REFERENCE(dependencyPortMap);
|
||||
|
||||
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING);
|
||||
|
||||
/* force bit at offset 255 to 0 (reserved) */
|
||||
dependencyPortMap[31] &= 0xFE;
|
||||
|
||||
COPY_DEPENDENCY_MAP(ixEthDBPortInfo[portID].dependencyPortMap, dependencyPortMap);
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBPortDependencyMapGet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap)
|
||||
{
|
||||
IX_ETH_DB_CHECK_PORT(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_REFERENCE(dependencyPortMap);
|
||||
|
||||
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING);
|
||||
|
||||
COPY_DEPENDENCY_MAP(dependencyPortMap, ixEthDBPortInfo[portID].dependencyPortMap);
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBPortUpdateEnableSet(IxEthDBPortId portID, BOOL enableUpdate)
|
||||
{
|
||||
IX_ETH_DB_CHECK_PORT(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING);
|
||||
|
||||
ixEthDBPortInfo[portID].updateMethod.updateEnabled = enableUpdate;
|
||||
ixEthDBPortInfo[portID].updateMethod.userControlled = true;
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
|
@ -1,651 +0,0 @@
|
|||
/**
|
||||
* @file IxEthDBAPISupport.c
|
||||
*
|
||||
* @brief Public API support functions
|
||||
*
|
||||
* @par
|
||||
* IXP400 SW Release version 2.0
|
||||
*
|
||||
* -- Copyright Notice --
|
||||
*
|
||||
* @par
|
||||
* Copyright 2001-2005, Intel Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
* @par
|
||||
* -- End of Copyright Notice --
|
||||
*/
|
||||
|
||||
#include <IxEthDB.h>
|
||||
#include <IxNpeMh.h>
|
||||
#include <IxFeatureCtrl.h>
|
||||
|
||||
#include "IxEthDB_p.h"
|
||||
#include "IxEthDBMessages_p.h"
|
||||
#include "IxEthDB_p.h"
|
||||
#include "IxEthDBLog_p.h"
|
||||
|
||||
#ifdef IX_UNIT_TEST
|
||||
|
||||
int dbAccessCounter = 0;
|
||||
int overflowEvent = 0;
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* External declaration
|
||||
*/
|
||||
extern HashTable dbHashtable;
|
||||
|
||||
/*
|
||||
* Internal declaration
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
PortInfo ixEthDBPortInfo[IX_ETH_DB_NUMBER_OF_PORTS];
|
||||
|
||||
IX_ETH_DB_PRIVATE
|
||||
struct
|
||||
{
|
||||
BOOL saved;
|
||||
IxEthDBPriorityTable priorityTable;
|
||||
IxEthDBVlanSet vlanMembership;
|
||||
IxEthDBVlanSet transmitTaggingInfo;
|
||||
IxEthDBFrameFilter frameFilter;
|
||||
IxEthDBTaggingAction taggingAction;
|
||||
IxEthDBFirewallMode firewallMode;
|
||||
BOOL stpBlocked;
|
||||
BOOL srcAddressFilterEnabled;
|
||||
UINT32 maxRxFrameSize;
|
||||
UINT32 maxTxFrameSize;
|
||||
} ixEthDBPortState[IX_ETH_DB_NUMBER_OF_PORTS];
|
||||
|
||||
#define IX_ETH_DB_DEFAULT_FRAME_SIZE (1518)
|
||||
|
||||
/**
|
||||
* @brief initializes a port
|
||||
*
|
||||
* @param portID ID of the port to be initialized
|
||||
*
|
||||
* Note that redundant initializations are silently
|
||||
* dealt with and do not constitute an error
|
||||
*
|
||||
* This function is fully documented in the main
|
||||
* header file, IxEthDB.h
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
void ixEthDBPortInit(IxEthDBPortId portID)
|
||||
{
|
||||
PortInfo *portInfo;
|
||||
|
||||
if (portID >= IX_ETH_DB_NUMBER_OF_PORTS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
portInfo = &ixEthDBPortInfo[portID];
|
||||
|
||||
if (ixEthDBSingleEthNpeCheck(portID) != IX_ETH_DB_SUCCESS)
|
||||
{
|
||||
WARNING_LOG("EthDB: Unavailable Eth %d: Cannot initialize EthDB Port.\n", (UINT32) portID);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (portInfo->initialized)
|
||||
{
|
||||
/* redundant */
|
||||
return;
|
||||
}
|
||||
|
||||
/* initialize core fields */
|
||||
portInfo->portID = portID;
|
||||
SET_DEPENDENCY_MAP(portInfo->dependencyPortMap, portID);
|
||||
|
||||
/* default values */
|
||||
portInfo->agingEnabled = false;
|
||||
portInfo->enabled = false;
|
||||
portInfo->macAddressUploaded = false;
|
||||
portInfo->maxRxFrameSize = IX_ETHDB_DEFAULT_FRAME_SIZE;
|
||||
portInfo->maxTxFrameSize = IX_ETHDB_DEFAULT_FRAME_SIZE;
|
||||
|
||||
/* default update control values */
|
||||
portInfo->updateMethod.searchTree = NULL;
|
||||
portInfo->updateMethod.searchTreePendingWrite = false;
|
||||
portInfo->updateMethod.treeInitialized = false;
|
||||
portInfo->updateMethod.updateEnabled = false;
|
||||
portInfo->updateMethod.userControlled = false;
|
||||
|
||||
/* default WiFi parameters */
|
||||
memset(portInfo->bbsid, 0, sizeof (portInfo->bbsid));
|
||||
portInfo->frameControlDurationID = 0;
|
||||
|
||||
/* Ethernet NPE-specific initializations */
|
||||
if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
|
||||
{
|
||||
/* update handler */
|
||||
portInfo->updateMethod.updateHandler = ixEthDBNPEUpdateHandler;
|
||||
}
|
||||
|
||||
/* initialize state save */
|
||||
ixEthDBPortState[portID].saved = false;
|
||||
|
||||
portInfo->initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief enables a port
|
||||
*
|
||||
* @param portID ID of the port to enable
|
||||
*
|
||||
* This function is fully documented in the main
|
||||
* header file, IxEthDB.h
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if enabling was
|
||||
* accomplished, or a meaningful error message otherwise
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBPortEnable(IxEthDBPortId portID)
|
||||
{
|
||||
IxEthDBPortMap triggerPorts;
|
||||
PortInfo *portInfo;
|
||||
|
||||
IX_ETH_DB_CHECK_PORT_EXISTS(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
|
||||
|
||||
portInfo = &ixEthDBPortInfo[portID];
|
||||
|
||||
if (portInfo->enabled)
|
||||
{
|
||||
/* redundant */
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
||||
SET_DEPENDENCY_MAP(triggerPorts, portID);
|
||||
|
||||
/* mark as enabled */
|
||||
portInfo->enabled = true;
|
||||
|
||||
/* Operation stops here when Ethernet Learning is not enabled */
|
||||
if(IX_FEATURE_CTRL_SWCONFIG_DISABLED ==
|
||||
ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING))
|
||||
{
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
||||
if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE && !portInfo->macAddressUploaded)
|
||||
{
|
||||
IX_ETH_DB_SUPPORT_TRACE("DB: (Support) MAC address not set on port %d, enable failed\n", portID);
|
||||
|
||||
/* must use UnicastAddressSet() before enabling an NPE port */
|
||||
return IX_ETH_DB_MAC_UNINITIALIZED;
|
||||
}
|
||||
|
||||
if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
|
||||
{
|
||||
IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Attempting to enable the NPE callback for port %d...\n", portID);
|
||||
|
||||
if (!portInfo->updateMethod.userControlled
|
||||
&& ((portInfo->featureCapability & IX_ETH_DB_FILTERING) != 0))
|
||||
{
|
||||
portInfo->updateMethod.updateEnabled = true;
|
||||
}
|
||||
|
||||
/* if this is first time initialization then we already have
|
||||
write access to the tree and can AccessRelease directly */
|
||||
if (!portInfo->updateMethod.treeInitialized)
|
||||
{
|
||||
IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Initializing tree for port %d\n", portID);
|
||||
|
||||
/* create an initial tree and release access into it */
|
||||
ixEthDBUpdatePortLearningTrees(triggerPorts);
|
||||
|
||||
/* mark tree as being initialized */
|
||||
portInfo->updateMethod.treeInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (ixEthDBPortState[portID].saved)
|
||||
{
|
||||
/* previous configuration data stored, restore state */
|
||||
if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0)
|
||||
{
|
||||
ixEthDBFirewallModeSet(portID, ixEthDBPortState[portID].firewallMode);
|
||||
ixEthDBFirewallInvalidAddressFilterEnable(portID, ixEthDBPortState[portID].srcAddressFilterEnabled);
|
||||
}
|
||||
|
||||
#if 0 /* test-only */
|
||||
if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0)
|
||||
{
|
||||
ixEthDBAcceptableFrameTypeSet(portID, ixEthDBPortState[portID].frameFilter);
|
||||
ixEthDBIngressVlanTaggingEnabledSet(portID, ixEthDBPortState[portID].taggingAction);
|
||||
|
||||
ixEthDBEgressVlanTaggingEnabledSet(portID, ixEthDBPortState[portID].transmitTaggingInfo);
|
||||
ixEthDBPortVlanMembershipSet(portID, ixEthDBPortState[portID].vlanMembership);
|
||||
|
||||
ixEthDBPriorityMappingTableSet(portID, ixEthDBPortState[portID].priorityTable);
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((portInfo->featureCapability & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0)
|
||||
{
|
||||
ixEthDBSpanningTreeBlockingStateSet(portID, ixEthDBPortState[portID].stpBlocked);
|
||||
}
|
||||
|
||||
ixEthDBFilteringPortMaximumRxFrameSizeSet(portID, ixEthDBPortState[portID].maxRxFrameSize);
|
||||
ixEthDBFilteringPortMaximumTxFrameSizeSet(portID, ixEthDBPortState[portID].maxTxFrameSize);
|
||||
|
||||
/* discard previous save */
|
||||
ixEthDBPortState[portID].saved = false;
|
||||
}
|
||||
|
||||
IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Enabling succeeded for port %d\n", portID);
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief disables a port
|
||||
*
|
||||
* @param portID ID of the port to disable
|
||||
*
|
||||
* This function is fully documented in the
|
||||
* main header file, IxEthDB.h
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if disabling was
|
||||
* successful or an appropriate error message
|
||||
* otherwise
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBPortDisable(IxEthDBPortId portID)
|
||||
{
|
||||
HashIterator iterator;
|
||||
IxEthDBPortMap triggerPorts; /* ports who will have deleted records and therefore will need updating */
|
||||
BOOL result;
|
||||
PortInfo *portInfo;
|
||||
IxEthDBFeature learningEnabled;
|
||||
#if 0 /* test-only */
|
||||
IxEthDBPriorityTable classZeroTable;
|
||||
#endif
|
||||
|
||||
IX_ETH_DB_CHECK_PORT_EXISTS(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
|
||||
|
||||
portInfo = &ixEthDBPortInfo[portID];
|
||||
|
||||
if (!portInfo->enabled)
|
||||
{
|
||||
/* redundant */
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
||||
if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
|
||||
{
|
||||
/* save filtering state */
|
||||
ixEthDBPortState[portID].firewallMode = portInfo->firewallMode;
|
||||
ixEthDBPortState[portID].frameFilter = portInfo->frameFilter;
|
||||
ixEthDBPortState[portID].taggingAction = portInfo->taggingAction;
|
||||
ixEthDBPortState[portID].stpBlocked = portInfo->stpBlocked;
|
||||
ixEthDBPortState[portID].srcAddressFilterEnabled = portInfo->srcAddressFilterEnabled;
|
||||
ixEthDBPortState[portID].maxRxFrameSize = portInfo->maxRxFrameSize;
|
||||
ixEthDBPortState[portID].maxTxFrameSize = portInfo->maxTxFrameSize;
|
||||
|
||||
memcpy(ixEthDBPortState[portID].vlanMembership, portInfo->vlanMembership, sizeof (IxEthDBVlanSet));
|
||||
memcpy(ixEthDBPortState[portID].transmitTaggingInfo, portInfo->transmitTaggingInfo, sizeof (IxEthDBVlanSet));
|
||||
memcpy(ixEthDBPortState[portID].priorityTable, portInfo->priorityTable, sizeof (IxEthDBPriorityTable));
|
||||
|
||||
ixEthDBPortState[portID].saved = true;
|
||||
|
||||
/* now turn off all EthDB filtering features on the port */
|
||||
|
||||
#if 0 /* test-only */
|
||||
/* VLAN & QoS */
|
||||
if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0)
|
||||
{
|
||||
ixEthDBPortVlanMembershipRangeAdd((IxEthDBPortId) portID, 0, IX_ETH_DB_802_1Q_MAX_VLAN_ID);
|
||||
ixEthDBEgressVlanRangeTaggingEnabledSet((IxEthDBPortId) portID, 0, IX_ETH_DB_802_1Q_MAX_VLAN_ID, false);
|
||||
ixEthDBAcceptableFrameTypeSet((IxEthDBPortId) portID, IX_ETH_DB_ACCEPT_ALL_FRAMES);
|
||||
ixEthDBIngressVlanTaggingEnabledSet((IxEthDBPortId) portID, IX_ETH_DB_PASS_THROUGH);
|
||||
|
||||
memset(classZeroTable, 0, sizeof (classZeroTable));
|
||||
ixEthDBPriorityMappingTableSet((IxEthDBPortId) portID, classZeroTable);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* STP */
|
||||
if ((portInfo->featureCapability & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0)
|
||||
{
|
||||
ixEthDBSpanningTreeBlockingStateSet((IxEthDBPortId) portID, false);
|
||||
}
|
||||
|
||||
/* Firewall */
|
||||
if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0)
|
||||
{
|
||||
ixEthDBFirewallModeSet((IxEthDBPortId) portID, IX_ETH_DB_FIREWALL_BLACK_LIST);
|
||||
ixEthDBFirewallTableDownload((IxEthDBPortId) portID);
|
||||
ixEthDBFirewallInvalidAddressFilterEnable((IxEthDBPortId) portID, false);
|
||||
}
|
||||
|
||||
/* Frame size filter */
|
||||
ixEthDBFilteringPortMaximumFrameSizeSet((IxEthDBPortId) portID, IX_ETH_DB_DEFAULT_FRAME_SIZE);
|
||||
|
||||
/* WiFi */
|
||||
if ((portInfo->featureCapability & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0)
|
||||
{
|
||||
ixEthDBWiFiConversionTableDownload((IxEthDBPortId) portID);
|
||||
}
|
||||
|
||||
/* save and disable the learning feature bit */
|
||||
learningEnabled = portInfo->featureStatus & IX_ETH_DB_LEARNING;
|
||||
portInfo->featureStatus &= ~IX_ETH_DB_LEARNING;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* save the learning feature bit */
|
||||
learningEnabled = portInfo->featureStatus & IX_ETH_DB_LEARNING;
|
||||
}
|
||||
|
||||
SET_EMPTY_DEPENDENCY_MAP(triggerPorts);
|
||||
|
||||
ixEthDBUpdateLock();
|
||||
|
||||
/* wipe out current entries for this port */
|
||||
BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
|
||||
|
||||
while (IS_ITERATOR_VALID(&iterator))
|
||||
{
|
||||
MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
|
||||
|
||||
/* check if the port match. If so, remove the entry */
|
||||
if (descriptor->portID == portID
|
||||
&& (descriptor->type == IX_ETH_DB_FILTERING_RECORD || descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD)
|
||||
&& !descriptor->recordData.filteringData.staticEntry)
|
||||
{
|
||||
/* delete entry */
|
||||
BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator));
|
||||
|
||||
/* add port to the set of update trigger ports */
|
||||
JOIN_PORT_TO_MAP(triggerPorts, portID);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* move to the next record */
|
||||
BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
|
||||
}
|
||||
}
|
||||
|
||||
if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
|
||||
{
|
||||
if (portInfo->updateMethod.searchTree != NULL)
|
||||
{
|
||||
ixEthDBFreeMacTreeNode(portInfo->updateMethod.searchTree);
|
||||
portInfo->updateMethod.searchTree = NULL;
|
||||
}
|
||||
|
||||
ixEthDBNPEUpdateHandler(portID, IX_ETH_DB_FILTERING_RECORD);
|
||||
}
|
||||
|
||||
/* mark as disabled */
|
||||
portInfo->enabled = false;
|
||||
|
||||
/* disable updates unless the user has specifically altered the default behavior */
|
||||
if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
|
||||
{
|
||||
if (!portInfo->updateMethod.userControlled)
|
||||
{
|
||||
portInfo->updateMethod.updateEnabled = false;
|
||||
}
|
||||
|
||||
/* make sure we re-initialize the NPE learning tree when the port is re-enabled */
|
||||
portInfo->updateMethod.treeInitialized = false;
|
||||
}
|
||||
|
||||
ixEthDBUpdateUnlock();
|
||||
|
||||
/* restore learning feature bit */
|
||||
portInfo->featureStatus |= learningEnabled;
|
||||
|
||||
/* if we've removed any records or lost any events make sure to force an update */
|
||||
IS_EMPTY_DEPENDENCY_MAP(result, triggerPorts);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
ixEthDBUpdatePortLearningTrees(triggerPorts);
|
||||
}
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief sends the updated maximum Tx/Rx frame lengths to the NPE
|
||||
*
|
||||
* @param portID ID of the port to update
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the update completed
|
||||
* successfully or an appropriate error message otherwise
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PRIVATE
|
||||
IxEthDBStatus ixEthDBPortFrameLengthsUpdate(IxEthDBPortId portID)
|
||||
{
|
||||
IxNpeMhMessage message;
|
||||
PortInfo *portInfo = &ixEthDBPortInfo[portID];
|
||||
IX_STATUS result;
|
||||
|
||||
FILL_SETMAXFRAMELENGTHS_MSG(message, portID, portInfo->maxRxFrameSize, portInfo->maxTxFrameSize);
|
||||
|
||||
IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief sets the port maximum Rx frame size
|
||||
*
|
||||
* @param portID ID of the port to set the frame size on
|
||||
* @param maximumRxFrameSize maximum Rx frame size
|
||||
*
|
||||
* This function updates the internal data structures and
|
||||
* calls ixEthDBPortFrameLengthsUpdate() for NPE update.
|
||||
*
|
||||
* This function is fully documented in the main header
|
||||
* file, IxEthDB.h.
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the operation was
|
||||
* successfull or an appropriate error message otherwise
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBFilteringPortMaximumRxFrameSizeSet(IxEthDBPortId portID, UINT32 maximumRxFrameSize)
|
||||
{
|
||||
IX_ETH_DB_CHECK_PORT_EXISTS(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
|
||||
|
||||
if (!ixEthDBPortInfo[portID].initialized)
|
||||
{
|
||||
return IX_ETH_DB_PORT_UNINITIALIZED;
|
||||
}
|
||||
|
||||
if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
|
||||
{
|
||||
if ((maximumRxFrameSize < IX_ETHDB_MIN_NPE_FRAME_SIZE) ||
|
||||
(maximumRxFrameSize > IX_ETHDB_MAX_NPE_FRAME_SIZE))
|
||||
{
|
||||
return IX_ETH_DB_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return IX_ETH_DB_NO_PERMISSION;
|
||||
}
|
||||
|
||||
/* update internal structure */
|
||||
ixEthDBPortInfo[portID].maxRxFrameSize = maximumRxFrameSize;
|
||||
|
||||
/* update the maximum frame size in the NPE */
|
||||
return ixEthDBPortFrameLengthsUpdate(portID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief sets the port maximum Tx frame size
|
||||
*
|
||||
* @param portID ID of the port to set the frame size on
|
||||
* @param maximumTxFrameSize maximum Tx frame size
|
||||
*
|
||||
* This function updates the internal data structures and
|
||||
* calls ixEthDBPortFrameLengthsUpdate() for NPE update.
|
||||
*
|
||||
* This function is fully documented in the main header
|
||||
* file, IxEthDB.h.
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the operation was
|
||||
* successfull or an appropriate error message otherwise
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBFilteringPortMaximumTxFrameSizeSet(IxEthDBPortId portID, UINT32 maximumTxFrameSize)
|
||||
{
|
||||
IX_ETH_DB_CHECK_PORT_EXISTS(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
|
||||
|
||||
if (!ixEthDBPortInfo[portID].initialized)
|
||||
{
|
||||
return IX_ETH_DB_PORT_UNINITIALIZED;
|
||||
}
|
||||
|
||||
if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
|
||||
{
|
||||
if ((maximumTxFrameSize < IX_ETHDB_MIN_NPE_FRAME_SIZE) ||
|
||||
(maximumTxFrameSize > IX_ETHDB_MAX_NPE_FRAME_SIZE))
|
||||
{
|
||||
return IX_ETH_DB_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return IX_ETH_DB_NO_PERMISSION;
|
||||
}
|
||||
|
||||
/* update internal structure */
|
||||
ixEthDBPortInfo[portID].maxTxFrameSize = maximumTxFrameSize;
|
||||
|
||||
/* update the maximum frame size in the NPE */
|
||||
return ixEthDBPortFrameLengthsUpdate(portID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief sets the port maximum Tx and Rx frame sizes
|
||||
*
|
||||
* @param portID ID of the port to set the frame size on
|
||||
* @param maximumFrameSize maximum Tx and Rx frame sizes
|
||||
*
|
||||
* This function updates the internal data structures and
|
||||
* calls ixEthDBPortFrameLengthsUpdate() for NPE update.
|
||||
*
|
||||
* Note that both the maximum Tx and Rx frame size are set
|
||||
* to the same value. This function is kept for compatibility
|
||||
* reasons.
|
||||
*
|
||||
* This function is fully documented in the main header
|
||||
* file, IxEthDB.h.
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the operation was
|
||||
* successfull or an appropriate error message otherwise
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBFilteringPortMaximumFrameSizeSet(IxEthDBPortId portID, UINT32 maximumFrameSize)
|
||||
{
|
||||
IX_ETH_DB_CHECK_PORT_EXISTS(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
|
||||
|
||||
if (!ixEthDBPortInfo[portID].initialized)
|
||||
{
|
||||
return IX_ETH_DB_PORT_UNINITIALIZED;
|
||||
}
|
||||
|
||||
if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
|
||||
{
|
||||
if ((maximumFrameSize < IX_ETHDB_MIN_NPE_FRAME_SIZE) ||
|
||||
(maximumFrameSize > IX_ETHDB_MAX_NPE_FRAME_SIZE))
|
||||
{
|
||||
return IX_ETH_DB_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return IX_ETH_DB_NO_PERMISSION;
|
||||
}
|
||||
|
||||
/* update internal structure */
|
||||
ixEthDBPortInfo[portID].maxRxFrameSize = maximumFrameSize;
|
||||
ixEthDBPortInfo[portID].maxTxFrameSize = maximumFrameSize;
|
||||
|
||||
/* update the maximum frame size in the NPE */
|
||||
return ixEthDBPortFrameLengthsUpdate(portID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief sets the MAC address of an NPE port
|
||||
*
|
||||
* @param portID port ID to set the MAC address on
|
||||
* @param macAddr pointer to the 6-byte MAC address
|
||||
*
|
||||
* This function is called by the EthAcc
|
||||
* ixEthAccUnicastMacAddressSet() and should not be
|
||||
* manually invoked unless required by special circumstances.
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the operation succeeded
|
||||
* or an appropriate error message otherwise
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBPortAddressSet(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
|
||||
{
|
||||
IxNpeMhMessage message;
|
||||
IX_STATUS result;
|
||||
|
||||
/* use this macro instead CHECK_PORT
|
||||
as the port doesn't need to be enabled */
|
||||
IX_ETH_DB_CHECK_PORT_EXISTS(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_REFERENCE(macAddr);
|
||||
|
||||
if (!ixEthDBPortInfo[portID].initialized)
|
||||
{
|
||||
return IX_ETH_DB_PORT_UNINITIALIZED;
|
||||
}
|
||||
|
||||
/* Operation stops here when Ethernet Learning is not enabled */
|
||||
if(IX_FEATURE_CTRL_SWCONFIG_DISABLED ==
|
||||
ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING))
|
||||
{
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
||||
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
|
||||
|
||||
/* exit if the port is not an Ethernet NPE */
|
||||
if (ixEthDBPortDefinitions[portID].type != IX_ETH_NPE)
|
||||
{
|
||||
return IX_ETH_DB_INVALID_PORT;
|
||||
}
|
||||
|
||||
/* populate message */
|
||||
FILL_SETPORTADDRESS_MSG(message, portID, macAddr->macAddress);
|
||||
|
||||
IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Sending SetPortAddress on port %d...\n", portID);
|
||||
|
||||
/* send a SetPortAddress message */
|
||||
IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
|
||||
|
||||
if (result == IX_SUCCESS)
|
||||
{
|
||||
ixEthDBPortInfo[portID].macAddressUploaded = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
|
@ -1,439 +0,0 @@
|
|||
/**
|
||||
* @file IxEthDBDBCore.c
|
||||
*
|
||||
* @brief Database support functions
|
||||
*
|
||||
* @par
|
||||
* IXP400 SW Release version 2.0
|
||||
*
|
||||
* -- Copyright Notice --
|
||||
*
|
||||
* @par
|
||||
* Copyright 2001-2005, Intel Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
* @par
|
||||
* -- End of Copyright Notice --
|
||||
*/
|
||||
|
||||
#include "IxEthDB_p.h"
|
||||
|
||||
/* list of database hashtables */
|
||||
IX_ETH_DB_PUBLIC HashTable dbHashtable;
|
||||
IX_ETH_DB_PUBLIC MatchFunction matchFunctions[IX_ETH_DB_MAX_KEY_INDEX + 1];
|
||||
IX_ETH_DB_PUBLIC BOOL ixEthDBPortUpdateRequired[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1];
|
||||
IX_ETH_DB_PUBLIC UINT32 ixEthDBKeyType[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1];
|
||||
|
||||
/* private initialization flag */
|
||||
IX_ETH_DB_PRIVATE BOOL ethDBInitializationComplete = false;
|
||||
|
||||
/**
|
||||
* @brief initializes EthDB
|
||||
*
|
||||
* This function must be called to initialize the component.
|
||||
*
|
||||
* It does the following things:
|
||||
* - checks the port definition structure
|
||||
* - scans the capabilities of the NPE images and sets the
|
||||
* capabilities of the ports accordingly
|
||||
* - initializes the memory pools internally used in EthDB
|
||||
* for storing database records and handling data
|
||||
* - registers automatic update handlers for add and remove
|
||||
* operations
|
||||
* - registers hashing match functions, depending on key sets
|
||||
* - initializes the main database hashtable
|
||||
* - allocates contiguous memory zones to be used for NPE
|
||||
* updates
|
||||
* - registers the serialize methods used to convert data
|
||||
* into NPE-readable format
|
||||
* - starts the event processor
|
||||
*
|
||||
* Note that this function is documented in the public
|
||||
* component header file, IxEthDB.h.
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS or an appropriate error if the
|
||||
* component failed to initialize correctly
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBInit(void)
|
||||
{
|
||||
IxEthDBStatus result;
|
||||
|
||||
if (ethDBInitializationComplete)
|
||||
{
|
||||
/* redundant */
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
||||
/* trap an invalid port definition structure */
|
||||
IX_ETH_DB_PORTS_ASSERTION;
|
||||
|
||||
/* memory management */
|
||||
ixEthDBInitMemoryPools();
|
||||
|
||||
/* register hashing search methods */
|
||||
ixEthDBMatchMethodsRegister(matchFunctions);
|
||||
|
||||
/* register type-based automatic port updates */
|
||||
ixEthDBUpdateTypeRegister(ixEthDBPortUpdateRequired);
|
||||
|
||||
/* register record to key type mappings */
|
||||
ixEthDBKeyTypeRegister(ixEthDBKeyType);
|
||||
|
||||
/* hash table */
|
||||
ixEthDBInitHash(&dbHashtable, NUM_BUCKETS, ixEthDBEntryXORHash, matchFunctions, (FreeFunction) ixEthDBFreeMacDescriptor);
|
||||
|
||||
/* NPE update zones */
|
||||
ixEthDBNPEUpdateAreasInit();
|
||||
|
||||
/* register record serialization methods */
|
||||
ixEthDBRecordSerializeMethodsRegister();
|
||||
|
||||
/* start the event processor */
|
||||
result = ixEthDBEventProcessorInit();
|
||||
|
||||
/* scan NPE features */
|
||||
if (result == IX_ETH_DB_SUCCESS)
|
||||
{
|
||||
ixEthDBFeatureCapabilityScan();
|
||||
}
|
||||
|
||||
ethDBInitializationComplete = true;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief prepares EthDB for unloading
|
||||
*
|
||||
* This function must be called before removing the
|
||||
* EthDB component from memory (e.g. doing rmmod in
|
||||
* Linux) if the component is to be re-initialized again
|
||||
* without rebooting the platform.
|
||||
*
|
||||
* All the EthDB ports must be disabled before this
|
||||
* function is to be called. Failure to disable all
|
||||
* the ports will return the IX_ETH_DB_BUSY error.
|
||||
*
|
||||
* This function will destroy mutexes, deallocate
|
||||
* memory and stop the event processor.
|
||||
*
|
||||
* Note that this function is fully documented in the
|
||||
* main component header file, IxEthDB.h.
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if de-initialization
|
||||
* completed successfully or an appropriate error
|
||||
* message otherwise
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBUnload(void)
|
||||
{
|
||||
IxEthDBPortId portIndex;
|
||||
|
||||
if (!ethDBInitializationComplete)
|
||||
{
|
||||
/* redundant */
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
||||
/* check if any ports are enabled */
|
||||
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
|
||||
{
|
||||
if (ixEthDBPortInfo[portIndex].enabled)
|
||||
{
|
||||
return IX_ETH_DB_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/* free port resources */
|
||||
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
|
||||
{
|
||||
if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE)
|
||||
{
|
||||
ixOsalMutexDestroy(&ixEthDBPortInfo[portIndex].npeAckLock);
|
||||
}
|
||||
|
||||
ixEthDBPortInfo[portIndex].initialized = false;
|
||||
}
|
||||
|
||||
/* shutdown event processor */
|
||||
ixEthDBStopLearningFunction();
|
||||
|
||||
/* deallocate NPE update zones */
|
||||
ixEthDBNPEUpdateAreasUnload();
|
||||
|
||||
ethDBInitializationComplete = false;
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief adds a new entry to the Ethernet database
|
||||
*
|
||||
* @param newRecordTemplate address of the record template to use
|
||||
* @param updateTrigger port map containing the update triggers
|
||||
* resulting from this update operation
|
||||
*
|
||||
* Creates a new database entry, populates it with the data
|
||||
* copied from the given template and adds the record to the
|
||||
* database hash table.
|
||||
* It also checks whether the new record type is registered to trigger
|
||||
* automatic updates; if it is, the update trigger will contain the
|
||||
* port on which the record insertion was performed, as well as the
|
||||
* old port in case the addition was a record migration (from one port
|
||||
* to the other). The caller can use the updateTrigger to trigger
|
||||
* automatic updates on the ports changed as a result of this addition.
|
||||
*
|
||||
* @retval IX_ETH_DB_SUCCESS addition successful
|
||||
* @retval IX_ETH_DB_NOMEM insertion failed, no memory left in the mac descriptor memory pool
|
||||
* @retval IX_ETH_DB_BUSY database busy, cannot insert due to locking
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBAdd(MacDescriptor *newRecordTemplate, IxEthDBPortMap updateTrigger)
|
||||
{
|
||||
IxEthDBStatus result;
|
||||
MacDescriptor *newDescriptor;
|
||||
IxEthDBPortId originalPortID;
|
||||
HashNode *node = NULL;
|
||||
|
||||
BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, ixEthDBKeyType[newRecordTemplate->type], newRecordTemplate, &node));
|
||||
|
||||
TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER;
|
||||
|
||||
if (node == NULL)
|
||||
{
|
||||
/* not found, create a new one */
|
||||
newDescriptor = ixEthDBAllocMacDescriptor();
|
||||
|
||||
if (newDescriptor == NULL)
|
||||
{
|
||||
return IX_ETH_DB_NOMEM; /* no memory */
|
||||
}
|
||||
|
||||
/* old port does not exist, avoid unnecessary updates */
|
||||
originalPortID = newRecordTemplate->portID;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* a node with the same key exists, will update node */
|
||||
newDescriptor = (MacDescriptor *) node->data;
|
||||
|
||||
/* save original port id */
|
||||
originalPortID = newDescriptor->portID;
|
||||
}
|
||||
|
||||
/* copy/update fields into new record */
|
||||
memcpy(newDescriptor->macAddress, newRecordTemplate->macAddress, sizeof (IxEthDBMacAddr));
|
||||
memcpy(&newDescriptor->recordData, &newRecordTemplate->recordData, sizeof (IxEthDBRecordData));
|
||||
|
||||
newDescriptor->type = newRecordTemplate->type;
|
||||
newDescriptor->portID = newRecordTemplate->portID;
|
||||
newDescriptor->user = newRecordTemplate->user;
|
||||
|
||||
if (node == NULL)
|
||||
{
|
||||
/* new record, insert into hashtable */
|
||||
BUSY_RETRY_WITH_RESULT(ixEthDBAddHashEntry(&dbHashtable, newDescriptor), result);
|
||||
|
||||
if (result != IX_ETH_DB_SUCCESS)
|
||||
{
|
||||
ixEthDBFreeMacDescriptor(newDescriptor);
|
||||
|
||||
return result; /* insertion failed */
|
||||
}
|
||||
}
|
||||
|
||||
if (node != NULL)
|
||||
{
|
||||
/* release access */
|
||||
ixEthDBReleaseHashNode(node);
|
||||
}
|
||||
|
||||
/* trigger add/remove update if required by type */
|
||||
if (updateTrigger != NULL &&
|
||||
ixEthDBPortUpdateRequired[newRecordTemplate->type])
|
||||
{
|
||||
/* add new port to update list */
|
||||
JOIN_PORT_TO_MAP(updateTrigger, newRecordTemplate->portID);
|
||||
|
||||
/* check if record has moved, we'll need to update the old port as well */
|
||||
if (originalPortID != newDescriptor->portID)
|
||||
{
|
||||
JOIN_PORT_TO_MAP(updateTrigger, originalPortID);
|
||||
}
|
||||
}
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief remove a record from the Ethernet database
|
||||
*
|
||||
* @param templateRecord template record used to determine
|
||||
* what record is to be removed
|
||||
* @param updateTrigger port map containing the update triggers
|
||||
* resulting from this update operation
|
||||
*
|
||||
* This function will examine the template record it receives
|
||||
* and attempts to delete a record of the same type and containing
|
||||
* the same keys as the template record. If deletion is successful
|
||||
* and the record type is registered for automatic port updates the
|
||||
* port will also be set in the updateTrigger port map, so that the
|
||||
* client can perform an update of the port.
|
||||
*
|
||||
* @retval IX_ETH_DB_SUCCESS removal was successful
|
||||
* @retval IX_ETH_DB_NO_SUCH_ADDR the record with the given MAC address was not found
|
||||
* @retval IX_ETH_DB_BUSY database busy, cannot remove due to locking
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBRemove(MacDescriptor *templateRecord, IxEthDBPortMap updateTrigger)
|
||||
{
|
||||
IxEthDBStatus result;
|
||||
|
||||
TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER;
|
||||
|
||||
BUSY_RETRY_WITH_RESULT(ixEthDBRemoveHashEntry(&dbHashtable, ixEthDBKeyType[templateRecord->type], templateRecord), result);
|
||||
|
||||
if (result != IX_ETH_DB_SUCCESS)
|
||||
{
|
||||
return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
|
||||
}
|
||||
|
||||
/* trigger add/remove update if required by type */
|
||||
if (updateTrigger != NULL
|
||||
&&ixEthDBPortUpdateRequired[templateRecord->type])
|
||||
{
|
||||
/* add new port to update list */
|
||||
JOIN_PORT_TO_MAP(updateTrigger, templateRecord->portID);
|
||||
}
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief register record key types
|
||||
*
|
||||
* This function registers the appropriate key types,
|
||||
* depending on record types.
|
||||
*
|
||||
* All filtering records use the MAC address as the key.
|
||||
* WiFi and Firewall records use a compound key consisting
|
||||
* in both the MAC address and the port ID.
|
||||
*
|
||||
* @return the number of registered record types
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
UINT32 ixEthDBKeyTypeRegister(UINT32 *keyType)
|
||||
{
|
||||
/* safety */
|
||||
memset(keyType, 0, sizeof (keyType));
|
||||
|
||||
/* register all known record types */
|
||||
keyType[IX_ETH_DB_FILTERING_RECORD] = IX_ETH_DB_MAC_KEY;
|
||||
keyType[IX_ETH_DB_FILTERING_VLAN_RECORD] = IX_ETH_DB_MAC_KEY;
|
||||
keyType[IX_ETH_DB_ALL_FILTERING_RECORDS] = IX_ETH_DB_MAC_KEY;
|
||||
keyType[IX_ETH_DB_WIFI_RECORD] = IX_ETH_DB_MAC_PORT_KEY;
|
||||
keyType[IX_ETH_DB_FIREWALL_RECORD] = IX_ETH_DB_MAC_PORT_KEY;
|
||||
|
||||
return 5;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets a user-defined field into a database record
|
||||
*
|
||||
* Note that this function is fully documented in the main component
|
||||
* header file.
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBUserFieldSet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void *field)
|
||||
{
|
||||
HashNode *result = NULL;
|
||||
|
||||
if (macAddr == NULL)
|
||||
{
|
||||
return IX_ETH_DB_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (recordType == IX_ETH_DB_FILTERING_RECORD)
|
||||
{
|
||||
result = ixEthDBSearch(macAddr, recordType);
|
||||
}
|
||||
else if (recordType == IX_ETH_DB_FILTERING_VLAN_RECORD)
|
||||
{
|
||||
result = ixEthDBVlanSearch(macAddr, vlanID, recordType);
|
||||
}
|
||||
else if (recordType == IX_ETH_DB_WIFI_RECORD || recordType == IX_ETH_DB_FIREWALL_RECORD)
|
||||
{
|
||||
IX_ETH_DB_CHECK_PORT_EXISTS(portID);
|
||||
|
||||
result = ixEthDBPortSearch(macAddr, portID, recordType);
|
||||
}
|
||||
else
|
||||
{
|
||||
return IX_ETH_DB_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (result == NULL)
|
||||
{
|
||||
return IX_ETH_DB_NO_SUCH_ADDR;
|
||||
}
|
||||
|
||||
((MacDescriptor *) result->data)->user = field;
|
||||
|
||||
ixEthDBReleaseHashNode(result);
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieves a user-defined field from a database record
|
||||
*
|
||||
* Note that this function is fully documented in the main component
|
||||
* header file.
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBUserFieldGet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void **field)
|
||||
{
|
||||
HashNode *result = NULL;
|
||||
|
||||
if (macAddr == NULL || field == NULL)
|
||||
{
|
||||
return IX_ETH_DB_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (recordType == IX_ETH_DB_FILTERING_RECORD)
|
||||
{
|
||||
result = ixEthDBSearch(macAddr, recordType);
|
||||
}
|
||||
else if (recordType == IX_ETH_DB_FILTERING_VLAN_RECORD)
|
||||
{
|
||||
result = ixEthDBVlanSearch(macAddr, vlanID, recordType);
|
||||
}
|
||||
else if (recordType == IX_ETH_DB_WIFI_RECORD || recordType == IX_ETH_DB_FIREWALL_RECORD)
|
||||
{
|
||||
IX_ETH_DB_CHECK_PORT_EXISTS(portID);
|
||||
|
||||
result = ixEthDBPortSearch(macAddr, portID, recordType);
|
||||
}
|
||||
else
|
||||
{
|
||||
return IX_ETH_DB_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (result == NULL)
|
||||
{
|
||||
return IX_ETH_DB_NO_SUCH_ADDR;
|
||||
}
|
||||
|
||||
*field = ((MacDescriptor *) result->data)->user;
|
||||
|
||||
ixEthDBReleaseHashNode(result);
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
|
@ -1,496 +0,0 @@
|
|||
/**
|
||||
* @file IxEthDBEvents.c
|
||||
*
|
||||
* @brief Implementation of the event processor component
|
||||
*
|
||||
* @par
|
||||
* IXP400 SW Release version 2.0
|
||||
*
|
||||
* -- Copyright Notice --
|
||||
*
|
||||
* @par
|
||||
* Copyright 2001-2005, Intel Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
* @par
|
||||
* -- End of Copyright Notice --
|
||||
*/
|
||||
|
||||
#include <IxNpeMh.h>
|
||||
#include <IxFeatureCtrl.h>
|
||||
|
||||
#include "IxEthDB_p.h"
|
||||
|
||||
/* forward prototype declarations */
|
||||
IX_ETH_DB_PUBLIC void ixEthDBEventProcessorLoop(void *);
|
||||
IX_ETH_DB_PUBLIC void ixEthDBNPEEventCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg);
|
||||
IX_ETH_DB_PRIVATE void ixEthDBProcessEvent(PortEvent *local_event, IxEthDBPortMap triggerPorts);
|
||||
IX_ETH_DB_PRIVATE IxEthDBStatus ixEthDBTriggerPortUpdate(UINT32 eventType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, BOOL staticEntry);
|
||||
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBStartLearningFunction(void);
|
||||
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBStopLearningFunction(void);
|
||||
|
||||
/* data */
|
||||
IX_ETH_DB_PRIVATE IxOsalSemaphore eventQueueSemaphore;
|
||||
IX_ETH_DB_PRIVATE PortEventQueue eventQueue;
|
||||
IX_ETH_DB_PRIVATE IxOsalMutex eventQueueLock;
|
||||
IX_ETH_DB_PRIVATE IxOsalMutex portUpdateLock;
|
||||
|
||||
IX_ETH_DB_PRIVATE BOOL ixEthDBLearningShutdown = false;
|
||||
IX_ETH_DB_PRIVATE BOOL ixEthDBEventProcessorRunning = false;
|
||||
|
||||
/* imported data */
|
||||
extern HashTable dbHashtable;
|
||||
|
||||
/**
|
||||
* @brief initializes the event processor
|
||||
*
|
||||
* Initializes the event processor queue and processing thread.
|
||||
* Called from ixEthDBInit() DB-subcomponent master init function.
|
||||
*
|
||||
* @warning do not call directly
|
||||
*
|
||||
* @retval IX_ETH_DB_SUCCESS initialization was successful
|
||||
* @retval IX_ETH_DB_FAIL initialization failed (OSAL or mutex init failure)
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBEventProcessorInit(void)
|
||||
{
|
||||
if (ixOsalMutexInit(&portUpdateLock) != IX_SUCCESS)
|
||||
{
|
||||
return IX_ETH_DB_FAIL;
|
||||
}
|
||||
|
||||
if (ixOsalMutexInit(&eventQueueLock) != IX_SUCCESS)
|
||||
{
|
||||
return IX_ETH_DB_FAIL;
|
||||
}
|
||||
|
||||
if (IX_FEATURE_CTRL_SWCONFIG_ENABLED ==
|
||||
ixFeatureCtrlSwConfigurationCheck (IX_FEATURECTRL_ETH_LEARNING))
|
||||
{
|
||||
|
||||
/* start processor loop thread */
|
||||
if (ixEthDBStartLearningFunction() != IX_ETH_DB_SUCCESS)
|
||||
{
|
||||
return IX_ETH_DB_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief initializes the event queue and the event processor
|
||||
*
|
||||
* This function is called by the component initialization
|
||||
* function, ixEthDBInit().
|
||||
*
|
||||
* @warning do not call directly
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the operation completed
|
||||
* successfully or IX_ETH_DB_FAIL otherwise
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBStartLearningFunction(void)
|
||||
{
|
||||
IxOsalThread eventProcessorThread;
|
||||
IxOsalThreadAttr threadAttr;
|
||||
|
||||
threadAttr.name = "EthDB event thread";
|
||||
threadAttr.stackSize = 32 * 1024; /* 32kbytes */
|
||||
threadAttr.priority = 128;
|
||||
|
||||
/* reset event queue */
|
||||
ixOsalMutexLock(&eventQueueLock, IX_OSAL_WAIT_FOREVER);
|
||||
|
||||
RESET_QUEUE(&eventQueue);
|
||||
|
||||
ixOsalMutexUnlock(&eventQueueLock);
|
||||
|
||||
/* init event queue semaphore */
|
||||
if (ixOsalSemaphoreInit(&eventQueueSemaphore, 0) != IX_SUCCESS)
|
||||
{
|
||||
return IX_ETH_DB_FAIL;
|
||||
}
|
||||
|
||||
ixEthDBLearningShutdown = false;
|
||||
|
||||
/* create processor loop thread */
|
||||
if (ixOsalThreadCreate(&eventProcessorThread, &threadAttr, ixEthDBEventProcessorLoop, NULL) != IX_SUCCESS)
|
||||
{
|
||||
return IX_ETH_DB_FAIL;
|
||||
}
|
||||
|
||||
/* start event processor */
|
||||
ixOsalThreadStart(&eventProcessorThread);
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief stops the event processor
|
||||
*
|
||||
* Stops the event processor and frees the event queue semaphore
|
||||
* Called by the component de-initialization function, ixEthDBUnload()
|
||||
*
|
||||
* @warning do not call directly
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the operation completed
|
||||
* successfully or IX_ETH_DB_FAIL otherwise;
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBStopLearningFunction(void)
|
||||
{
|
||||
ixEthDBLearningShutdown = true;
|
||||
|
||||
/* wake up event processing loop to actually process the shutdown event */
|
||||
ixOsalSemaphorePost(&eventQueueSemaphore);
|
||||
|
||||
if (ixOsalSemaphoreDestroy(&eventQueueSemaphore) != IX_SUCCESS)
|
||||
{
|
||||
return IX_ETH_DB_FAIL;
|
||||
}
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief default NPE event processing callback
|
||||
*
|
||||
* @param npeID ID of the NPE that generated the event
|
||||
* @param msg NPE message (encapsulated event)
|
||||
*
|
||||
* Creates an event object on the Ethernet event processor queue
|
||||
* and signals the new event by incrementing the event queue semaphore.
|
||||
* Events are processed by @ref ixEthDBEventProcessorLoop() which runs
|
||||
* at user level.
|
||||
*
|
||||
* @see ixEthDBEventProcessorLoop()
|
||||
*
|
||||
* @warning do not call directly
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
void ixEthDBNPEEventCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg)
|
||||
{
|
||||
PortEvent *local_event;
|
||||
|
||||
IX_ETH_DB_IRQ_EVENTS_TRACE("DB: (Events) new event received by processor callback from port %d, id 0x%X\n", IX_ETH_DB_NPE_TO_PORT_ID(npeID), NPE_MSG_ID(msg), 0, 0, 0, 0);
|
||||
|
||||
if (CAN_ENQUEUE(&eventQueue))
|
||||
{
|
||||
TEST_FIXTURE_LOCK_EVENT_QUEUE;
|
||||
|
||||
local_event = QUEUE_HEAD(&eventQueue);
|
||||
|
||||
/* create event structure on queue */
|
||||
local_event->eventType = NPE_MSG_ID(msg);
|
||||
local_event->portID = IX_ETH_DB_NPE_TO_PORT_ID(npeID);
|
||||
|
||||
/* update queue */
|
||||
PUSH_UPDATE_QUEUE(&eventQueue);
|
||||
|
||||
TEST_FIXTURE_UNLOCK_EVENT_QUEUE;
|
||||
|
||||
IX_ETH_DB_IRQ_EVENTS_TRACE("DB: (Events) Waking up main processor loop...\n", 0, 0, 0, 0, 0, 0);
|
||||
|
||||
/* increment event queue semaphore */
|
||||
ixOsalSemaphorePost(&eventQueueSemaphore);
|
||||
}
|
||||
else
|
||||
{
|
||||
IX_ETH_DB_IRQ_EVENTS_TRACE("DB: (Events) Warning: could not enqueue event (overflow)\n", 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Ethernet event processor loop
|
||||
*
|
||||
* Extracts at most EVENT_PROCESSING_LIMIT batches of events and
|
||||
* sends them for processing to @ref ixEthDBProcessEvent().
|
||||
* Triggers port updates which normally follow learning events.
|
||||
*
|
||||
* @warning do not call directly, executes in separate thread
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
void ixEthDBEventProcessorLoop(void *unused1)
|
||||
{
|
||||
IxEthDBPortMap triggerPorts;
|
||||
IxEthDBPortId portIndex;
|
||||
|
||||
ixEthDBEventProcessorRunning = true;
|
||||
|
||||
IX_ETH_DB_EVENTS_TRACE("DB: (Events) Event processor loop was started\n");
|
||||
|
||||
while (!ixEthDBLearningShutdown)
|
||||
{
|
||||
BOOL keepProcessing = true;
|
||||
UINT32 processedEvents = 0;
|
||||
|
||||
IX_ETH_DB_EVENTS_VERBOSE_TRACE("DB: (Events) Waiting for new learning event...\n");
|
||||
|
||||
ixOsalSemaphoreWait(&eventQueueSemaphore, IX_OSAL_WAIT_FOREVER);
|
||||
|
||||
IX_ETH_DB_EVENTS_VERBOSE_TRACE("DB: (Events) Received new event\n");
|
||||
|
||||
if (!ixEthDBLearningShutdown)
|
||||
{
|
||||
/* port update handling */
|
||||
SET_EMPTY_DEPENDENCY_MAP(triggerPorts);
|
||||
|
||||
while (keepProcessing)
|
||||
{
|
||||
PortEvent local_event;
|
||||
UINT32 intLockKey;
|
||||
|
||||
/* lock queue */
|
||||
ixOsalMutexLock(&eventQueueLock, IX_OSAL_WAIT_FOREVER);
|
||||
|
||||
/* lock NPE interrupts */
|
||||
intLockKey = ixOsalIrqLock();
|
||||
|
||||
/* extract event */
|
||||
local_event = *(QUEUE_TAIL(&eventQueue));
|
||||
|
||||
SHIFT_UPDATE_QUEUE(&eventQueue);
|
||||
|
||||
ixOsalIrqUnlock(intLockKey);
|
||||
|
||||
ixOsalMutexUnlock(&eventQueueLock);
|
||||
|
||||
IX_ETH_DB_EVENTS_TRACE("DB: (Events) Processing event with ID 0x%X\n", local_event.eventType);
|
||||
|
||||
ixEthDBProcessEvent(&local_event, triggerPorts);
|
||||
|
||||
processedEvents++;
|
||||
|
||||
if (processedEvents > EVENT_PROCESSING_LIMIT /* maximum burst reached? */
|
||||
|| ixOsalSemaphoreTryWait(&eventQueueSemaphore) != IX_SUCCESS) /* or empty queue? */
|
||||
{
|
||||
keepProcessing = false;
|
||||
}
|
||||
}
|
||||
|
||||
ixEthDBUpdatePortLearningTrees(triggerPorts);
|
||||
}
|
||||
}
|
||||
|
||||
/* turn off automatic updates */
|
||||
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
|
||||
{
|
||||
ixEthDBPortInfo[portIndex].updateMethod.updateEnabled = false;
|
||||
}
|
||||
|
||||
ixEthDBEventProcessorRunning = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief event processor routine
|
||||
*
|
||||
* @param event event to be processed
|
||||
* @param triggerPorts port map accumulating ports to be updated
|
||||
*
|
||||
* Processes learning events by synchronizing the database with
|
||||
* newly learnt data. Called only by @ref ixEthDBEventProcessorLoop().
|
||||
*
|
||||
* @warning do not call directly
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PRIVATE
|
||||
void ixEthDBProcessEvent(PortEvent *local_event, IxEthDBPortMap triggerPorts)
|
||||
{
|
||||
MacDescriptor recordTemplate;
|
||||
|
||||
switch (local_event->eventType)
|
||||
{
|
||||
case IX_ETH_DB_ADD_FILTERING_RECORD:
|
||||
/* add record */
|
||||
memset(&recordTemplate, 0, sizeof (recordTemplate));
|
||||
memcpy(recordTemplate.macAddress, local_event->macAddr.macAddress, sizeof (IxEthDBMacAddr));
|
||||
|
||||
recordTemplate.type = IX_ETH_DB_FILTERING_RECORD;
|
||||
recordTemplate.portID = local_event->portID;
|
||||
recordTemplate.recordData.filteringData.staticEntry = local_event->staticEntry;
|
||||
|
||||
ixEthDBAdd(&recordTemplate, triggerPorts);
|
||||
|
||||
IX_ETH_DB_EVENTS_TRACE("DB: (Events) Added record on port %d\n", local_event->portID);
|
||||
|
||||
break;
|
||||
|
||||
case IX_ETH_DB_REMOVE_FILTERING_RECORD:
|
||||
/* remove record */
|
||||
memset(&recordTemplate, 0, sizeof (recordTemplate));
|
||||
memcpy(recordTemplate.macAddress, local_event->macAddr.macAddress, sizeof (IxEthDBMacAddr));
|
||||
|
||||
recordTemplate.type = IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD;
|
||||
|
||||
ixEthDBRemove(&recordTemplate, triggerPorts);
|
||||
|
||||
IX_ETH_DB_EVENTS_TRACE("DB: (Events) Removed record on port %d\n", local_event->portID);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
/* can't handle/not interested in this event type */
|
||||
ERROR_LOG("DB: (Events) Event processor received an unknown event type (0x%X)\n", local_event->eventType);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief asynchronously adds a filtering record
|
||||
* by posting an ADD_FILTERING_RECORD event to the event queue
|
||||
*
|
||||
* @param macAddr MAC address of the new record
|
||||
* @param portID port ID of the new record
|
||||
* @param staticEntry true if record is static, false if dynamic
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the event creation was
|
||||
* successfull or IX_ETH_DB_BUSY if the event queue is full
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBTriggerAddPortUpdate(IxEthDBMacAddr *macAddr, IxEthDBPortId portID, BOOL staticEntry)
|
||||
{
|
||||
MacDescriptor reference;
|
||||
|
||||
TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER;
|
||||
|
||||
/* fill search fields */
|
||||
memcpy(reference.macAddress, macAddr, sizeof (IxEthDBMacAddr));
|
||||
reference.portID = portID;
|
||||
|
||||
/* set acceptable record types */
|
||||
reference.type = IX_ETH_DB_ALL_FILTERING_RECORDS;
|
||||
|
||||
if (ixEthDBPeekHashEntry(&dbHashtable, IX_ETH_DB_MAC_PORT_KEY, &reference) == IX_ETH_DB_SUCCESS)
|
||||
{
|
||||
/* already have an identical record */
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ixEthDBTriggerPortUpdate(IX_ETH_DB_ADD_FILTERING_RECORD, macAddr, portID, staticEntry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief asynchronously removes a filtering record
|
||||
* by posting a REMOVE_FILTERING_RECORD event to the event queue
|
||||
*
|
||||
* @param macAddr MAC address of the record to remove
|
||||
* @param portID port ID of the record to remove
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the event creation was
|
||||
* successfull or IX_ETH_DB_BUSY if the event queue is full
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBTriggerRemovePortUpdate(IxEthDBMacAddr *macAddr, IxEthDBPortId portID)
|
||||
{
|
||||
if (ixEthDBPeek(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS) != IX_ETH_DB_NO_SUCH_ADDR)
|
||||
{
|
||||
return ixEthDBTriggerPortUpdate(IX_ETH_DB_REMOVE_FILTERING_RECORD, macAddr, portID, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
return IX_ETH_DB_NO_SUCH_ADDR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief adds an ADD or REMOVE event to the main event queue
|
||||
*
|
||||
* @param eventType event type - IX_ETH_DB_ADD_FILTERING_RECORD
|
||||
* to add and IX_ETH_DB_REMOVE_FILTERING_RECORD to remove a
|
||||
* record.
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the event was successfully
|
||||
* sent or IX_ETH_DB_BUSY if the event queue is full
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PRIVATE
|
||||
IxEthDBStatus ixEthDBTriggerPortUpdate(UINT32 eventType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, BOOL staticEntry)
|
||||
{
|
||||
UINT32 intLockKey;
|
||||
|
||||
/* lock interrupts to protect queue */
|
||||
intLockKey = ixOsalIrqLock();
|
||||
|
||||
if (CAN_ENQUEUE(&eventQueue))
|
||||
{
|
||||
PortEvent *queueEvent = QUEUE_HEAD(&eventQueue);
|
||||
|
||||
/* update fields on the queue */
|
||||
memcpy(queueEvent->macAddr.macAddress, macAddr->macAddress, sizeof (IxEthDBMacAddr));
|
||||
|
||||
queueEvent->eventType = eventType;
|
||||
queueEvent->portID = portID;
|
||||
queueEvent->staticEntry = staticEntry;
|
||||
|
||||
PUSH_UPDATE_QUEUE(&eventQueue);
|
||||
|
||||
/* imcrement event queue semaphore */
|
||||
ixOsalSemaphorePost(&eventQueueSemaphore);
|
||||
|
||||
/* unlock interrupts */
|
||||
ixOsalIrqUnlock(intLockKey);
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
else /* event queue full */
|
||||
{
|
||||
/* unlock interrupts */
|
||||
ixOsalIrqUnlock(intLockKey);
|
||||
|
||||
return IX_ETH_DB_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Locks learning tree updates and port disable
|
||||
*
|
||||
*
|
||||
* This function locks portUpdateLock single mutex. It is primarily used
|
||||
* to avoid executing 'port disable' during ELT maintenance.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
void ixEthDBUpdateLock(void)
|
||||
{
|
||||
ixOsalMutexLock(&portUpdateLock, IX_OSAL_WAIT_FOREVER);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unlocks learning tree updates and port disable
|
||||
*
|
||||
*
|
||||
* This function unlocks a portUpdateLock mutex. It is primarily used
|
||||
* to avoid executing 'port disable' during ELT maintenance.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
void ixEthDBUpdateUnlock(void)
|
||||
{
|
||||
ixOsalMutexUnlock(&portUpdateLock);
|
||||
}
|
||||
|
|
@ -1,638 +0,0 @@
|
|||
/**
|
||||
* @file IxEthDBFeatures.c
|
||||
*
|
||||
* @brief Implementation of the EthDB feature control API
|
||||
*
|
||||
* @par
|
||||
* IXP400 SW Release version 2.0
|
||||
*
|
||||
* -- Copyright Notice --
|
||||
*
|
||||
* @par
|
||||
* Copyright 2001-2005, Intel Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
* @par
|
||||
* -- End of Copyright Notice --
|
||||
*/
|
||||
|
||||
#include "IxNpeDl.h"
|
||||
#include "IxEthDBQoS.h"
|
||||
#include "IxEthDB_p.h"
|
||||
|
||||
/**
|
||||
* @brief scans the capabilities of the loaded NPE images
|
||||
*
|
||||
* This function MUST be called by the ixEthDBInit() function.
|
||||
* No EthDB features (including learning and filtering) are enabled
|
||||
* before this function is called.
|
||||
*
|
||||
* @return none
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
void ixEthDBFeatureCapabilityScan(void)
|
||||
{
|
||||
IxNpeDlImageId imageId, npeAImageId;
|
||||
IxEthDBPortId portIndex;
|
||||
PortInfo *portInfo;
|
||||
IxEthDBPriorityTable defaultPriorityTable;
|
||||
IX_STATUS result;
|
||||
UINT32 queueIndex;
|
||||
UINT32 queueStructureIndex;
|
||||
UINT32 trafficClassDefinitionIndex;
|
||||
|
||||
/* read version of NPE A - required to set the AQM queues for B and C */
|
||||
npeAImageId.functionalityId = 0;
|
||||
ixNpeDlLoadedImageGet(IX_NPEDL_NPEID_NPEA, &npeAImageId);
|
||||
|
||||
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
|
||||
{
|
||||
IxNpeMhMessage msg;
|
||||
|
||||
portInfo = &ixEthDBPortInfo[portIndex];
|
||||
|
||||
/* check and bypass if NPE B or C is fused out */
|
||||
if (ixEthDBSingleEthNpeCheck(portIndex) != IX_ETH_DB_SUCCESS) continue;
|
||||
|
||||
/* all ports are capable of LEARNING by default */
|
||||
portInfo->featureCapability |= IX_ETH_DB_LEARNING;
|
||||
portInfo->featureStatus |= IX_ETH_DB_LEARNING;
|
||||
|
||||
if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE)
|
||||
{
|
||||
|
||||
if (ixNpeDlLoadedImageGet(IX_ETH_DB_PORT_ID_TO_NPE(portIndex), &imageId) != IX_SUCCESS)
|
||||
{
|
||||
WARNING_LOG("DB: (FeatureScan) NpeDl did not provide the image ID for NPE port %d\n", portIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* initialize and empty NPE response mutex */
|
||||
ixOsalMutexInit(&portInfo->npeAckLock);
|
||||
ixOsalMutexLock(&portInfo->npeAckLock, IX_OSAL_WAIT_FOREVER);
|
||||
|
||||
/* check NPE response to GetStatus */
|
||||
msg.data[0] = IX_ETHNPE_NPE_GETSTATUS << 24;
|
||||
msg.data[1] = 0;
|
||||
IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portIndex), msg, result);
|
||||
if (result != IX_SUCCESS)
|
||||
{
|
||||
WARNING_LOG("DB: (FeatureScan) warning, could not send message to the NPE\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (imageId.functionalityId == 0x00
|
||||
|| imageId.functionalityId == 0x03
|
||||
|| imageId.functionalityId == 0x04
|
||||
|| imageId.functionalityId == 0x80)
|
||||
{
|
||||
portInfo->featureCapability |= IX_ETH_DB_FILTERING;
|
||||
portInfo->featureCapability |= IX_ETH_DB_FIREWALL;
|
||||
portInfo->featureCapability |= IX_ETH_DB_SPANNING_TREE_PROTOCOL;
|
||||
}
|
||||
else if (imageId.functionalityId == 0x01
|
||||
|| imageId.functionalityId == 0x81)
|
||||
{
|
||||
portInfo->featureCapability |= IX_ETH_DB_FILTERING;
|
||||
portInfo->featureCapability |= IX_ETH_DB_FIREWALL;
|
||||
portInfo->featureCapability |= IX_ETH_DB_SPANNING_TREE_PROTOCOL;
|
||||
portInfo->featureCapability |= IX_ETH_DB_VLAN_QOS;
|
||||
}
|
||||
else if (imageId.functionalityId == 0x02
|
||||
|| imageId.functionalityId == 0x82)
|
||||
{
|
||||
portInfo->featureCapability |= IX_ETH_DB_WIFI_HEADER_CONVERSION;
|
||||
portInfo->featureCapability |= IX_ETH_DB_FIREWALL;
|
||||
portInfo->featureCapability |= IX_ETH_DB_SPANNING_TREE_PROTOCOL;
|
||||
portInfo->featureCapability |= IX_ETH_DB_VLAN_QOS;
|
||||
}
|
||||
|
||||
/* reset AQM queues */
|
||||
memset(portInfo->ixEthDBTrafficClassAQMAssignments, 0, sizeof (portInfo->ixEthDBTrafficClassAQMAssignments));
|
||||
|
||||
/* ensure there's at least one traffic class record in the definition table, otherwise we have no default case, hence no queues */
|
||||
IX_ENSURE(sizeof (ixEthDBTrafficClassDefinitions) != 0, "DB: no traffic class definitions found, check IxEthDBQoS.h");
|
||||
|
||||
/* find the traffic class definition index compatible with the current NPE A functionality ID */
|
||||
for (trafficClassDefinitionIndex = 0 ;
|
||||
trafficClassDefinitionIndex < ARRAY_SIZE(ixEthDBTrafficClassDefinitions);
|
||||
trafficClassDefinitionIndex++)
|
||||
{
|
||||
if (ixEthDBTrafficClassDefinitions[trafficClassDefinitionIndex][IX_ETH_DB_NPE_A_FUNCTIONALITY_ID_INDEX] == npeAImageId.functionalityId)
|
||||
{
|
||||
/* found it */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* select the default case if we went over the array boundary */
|
||||
if (trafficClassDefinitionIndex == ARRAY_SIZE(ixEthDBTrafficClassDefinitions))
|
||||
{
|
||||
trafficClassDefinitionIndex = 0; /* the first record is the default case */
|
||||
}
|
||||
|
||||
/* select queue assignment structure based on the traffic class configuration index */
|
||||
queueStructureIndex = ixEthDBTrafficClassDefinitions[trafficClassDefinitionIndex][IX_ETH_DB_QUEUE_ASSIGNMENT_INDEX];
|
||||
|
||||
/* only traffic class 0 is active at initialization time */
|
||||
portInfo->ixEthDBTrafficClassCount = 1;
|
||||
|
||||
/* enable port, VLAN and Firewall feature bits to initialize QoS/VLAN/Firewall configuration */
|
||||
portInfo->featureStatus |= IX_ETH_DB_VLAN_QOS;
|
||||
portInfo->featureStatus |= IX_ETH_DB_FIREWALL;
|
||||
portInfo->enabled = true;
|
||||
|
||||
#define CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */
|
||||
#ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */
|
||||
/* set VLAN initial configuration (permissive) */
|
||||
if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0) /* QoS-enabled image */
|
||||
{
|
||||
/* QoS capable */
|
||||
portInfo->ixEthDBTrafficClassAvailable = ixEthDBTrafficClassDefinitions[trafficClassDefinitionIndex][IX_ETH_DB_TRAFFIC_CLASS_COUNT_INDEX];
|
||||
|
||||
/* set AQM queues */
|
||||
for (queueIndex = 0 ; queueIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; queueIndex++)
|
||||
{
|
||||
portInfo->ixEthDBTrafficClassAQMAssignments[queueIndex] = ixEthDBQueueAssignments[queueStructureIndex][queueIndex];
|
||||
}
|
||||
|
||||
/* set default PVID (0) and default traffic class 0 */
|
||||
ixEthDBPortVlanTagSet(portIndex, 0);
|
||||
|
||||
/* enable reception of all frames */
|
||||
ixEthDBAcceptableFrameTypeSet(portIndex, IX_ETH_DB_ACCEPT_ALL_FRAMES);
|
||||
|
||||
/* clear full VLAN membership */
|
||||
ixEthDBPortVlanMembershipRangeRemove(portIndex, 0, IX_ETH_DB_802_1Q_MAX_VLAN_ID);
|
||||
|
||||
/* clear TTI table - no VLAN tagged frames will be transmitted */
|
||||
ixEthDBEgressVlanRangeTaggingEnabledSet(portIndex, 0, 4094, false);
|
||||
|
||||
/* set membership on 0, otherwise no Tx or Rx is working */
|
||||
ixEthDBPortVlanMembershipAdd(portIndex, 0);
|
||||
}
|
||||
else /* QoS not available in this image */
|
||||
#endif /* test-only */
|
||||
{
|
||||
/* initialize traffic class availability (only class 0 is available) */
|
||||
portInfo->ixEthDBTrafficClassAvailable = 1;
|
||||
|
||||
/* point all AQM queues to traffic class 0 */
|
||||
for (queueIndex = 0 ; queueIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; queueIndex++)
|
||||
{
|
||||
portInfo->ixEthDBTrafficClassAQMAssignments[queueIndex] =
|
||||
ixEthDBQueueAssignments[queueStructureIndex][0];
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */
|
||||
/* download priority mapping table and Rx queue configuration */
|
||||
memset (defaultPriorityTable, 0, sizeof (defaultPriorityTable));
|
||||
ixEthDBPriorityMappingTableSet(portIndex, defaultPriorityTable);
|
||||
#endif
|
||||
|
||||
/* by default we turn off invalid source MAC address filtering */
|
||||
ixEthDBFirewallInvalidAddressFilterEnable(portIndex, false);
|
||||
|
||||
/* disable port, VLAN, Firewall feature bits */
|
||||
portInfo->featureStatus &= ~IX_ETH_DB_VLAN_QOS;
|
||||
portInfo->featureStatus &= ~IX_ETH_DB_FIREWALL;
|
||||
portInfo->enabled = false;
|
||||
|
||||
/* enable filtering by default if present */
|
||||
if ((portInfo->featureCapability & IX_ETH_DB_FILTERING) != 0)
|
||||
{
|
||||
portInfo->featureStatus |= IX_ETH_DB_FILTERING;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief returns the capability of a port
|
||||
*
|
||||
* @param portID ID of the port
|
||||
* @param featureSet location to store the port capability in
|
||||
*
|
||||
* This function will save the capability set of the given port
|
||||
* into the given location. Capabilities are bit-ORed, each representing
|
||||
* a bit of the feature set.
|
||||
*
|
||||
* Note that this function is documented in the main component
|
||||
* public header file, IxEthDB.h.
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the operation completed successfully
|
||||
* or IX_ETH_DB_INVALID_PORT if the given port is invalid
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBFeatureCapabilityGet(IxEthDBPortId portID, IxEthDBFeature *featureSet)
|
||||
{
|
||||
IX_ETH_DB_CHECK_PORT_INITIALIZED(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_REFERENCE(featureSet);
|
||||
|
||||
*featureSet = ixEthDBPortInfo[portID].featureCapability;
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief enables or disables a port capability
|
||||
*
|
||||
* @param portID ID of the port
|
||||
* @param feature feature to enable or disable
|
||||
* @param enabled true to enable the selected feature or false to disable it
|
||||
*
|
||||
* Note that this function is documented in the main component
|
||||
* header file, IxEthDB.h.
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the operation completed
|
||||
* successfully or an appropriate error message otherwise
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBFeatureEnable(IxEthDBPortId portID, IxEthDBFeature feature, BOOL enable)
|
||||
{
|
||||
PortInfo *portInfo;
|
||||
IxEthDBPriorityTable defaultPriorityTable;
|
||||
IxEthDBVlanSet vlanSet;
|
||||
IxEthDBStatus status = IX_ETH_DB_SUCCESS;
|
||||
BOOL portEnabled;
|
||||
|
||||
IX_ETH_DB_CHECK_PORT_INITIALIZED(portID);
|
||||
|
||||
portInfo = &ixEthDBPortInfo[portID];
|
||||
portEnabled = portInfo->enabled;
|
||||
|
||||
/* check that only one feature is selected */
|
||||
if (!ixEthDBCheckSingleBitValue(feature))
|
||||
{
|
||||
return IX_ETH_DB_FEATURE_UNAVAILABLE;
|
||||
}
|
||||
|
||||
/* port capable of this feature? */
|
||||
if ((portInfo->featureCapability & feature) == 0)
|
||||
{
|
||||
return IX_ETH_DB_FEATURE_UNAVAILABLE;
|
||||
}
|
||||
|
||||
/* mutual exclusion between learning and WiFi header conversion */
|
||||
if (enable && ((feature | portInfo->featureStatus) & (IX_ETH_DB_FILTERING | IX_ETH_DB_WIFI_HEADER_CONVERSION))
|
||||
== (IX_ETH_DB_FILTERING | IX_ETH_DB_WIFI_HEADER_CONVERSION))
|
||||
{
|
||||
return IX_ETH_DB_NO_PERMISSION;
|
||||
}
|
||||
|
||||
/* learning must be enabled before filtering */
|
||||
if (enable && (feature == IX_ETH_DB_FILTERING) && ((portInfo->featureStatus & IX_ETH_DB_LEARNING) == 0))
|
||||
{
|
||||
return IX_ETH_DB_NO_PERMISSION;
|
||||
}
|
||||
|
||||
/* filtering must be disabled before learning */
|
||||
if (!enable && (feature == IX_ETH_DB_LEARNING) && ((portInfo->featureStatus & IX_ETH_DB_FILTERING) != 0))
|
||||
{
|
||||
return IX_ETH_DB_NO_PERMISSION;
|
||||
}
|
||||
|
||||
/* redundant enabling or disabling */
|
||||
if ((!enable && ((portInfo->featureStatus & feature) == 0))
|
||||
|| (enable && ((portInfo->featureStatus & feature) != 0)))
|
||||
{
|
||||
/* do nothing */
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
||||
/* force port enabled */
|
||||
portInfo->enabled = true;
|
||||
|
||||
if (enable)
|
||||
{
|
||||
/* turn on enable bit */
|
||||
portInfo->featureStatus |= feature;
|
||||
|
||||
#ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */
|
||||
/* if this is VLAN/QoS set the default priority table */
|
||||
if (feature == IX_ETH_DB_VLAN_QOS)
|
||||
{
|
||||
/* turn on VLAN/QoS (most permissive mode):
|
||||
- set default 802.1Q priority mapping table, in accordance to the
|
||||
availability of traffic classes
|
||||
- set the acceptable frame filter to accept all
|
||||
- set the Ingress tagging mode to pass-through
|
||||
- set full VLAN membership list
|
||||
- set full TTI table
|
||||
- set the default 802.1Q tag to 0 (VLAN ID 0, Pri 0, CFI 0)
|
||||
- enable TPID port extraction
|
||||
*/
|
||||
|
||||
portInfo->ixEthDBTrafficClassCount = portInfo->ixEthDBTrafficClassAvailable;
|
||||
|
||||
/* set default 802.1Q priority mapping table - note that C indexing starts from 0, so we substract 1 here */
|
||||
memcpy (defaultPriorityTable,
|
||||
(const void *) ixEthIEEE802_1QUserPriorityToTrafficClassMapping[portInfo->ixEthDBTrafficClassCount - 1],
|
||||
sizeof (defaultPriorityTable));
|
||||
|
||||
/* update priority mapping and AQM queue assignments */
|
||||
status = ixEthDBPriorityMappingTableSet(portID, defaultPriorityTable);
|
||||
|
||||
if (status == IX_ETH_DB_SUCCESS)
|
||||
{
|
||||
status = ixEthDBAcceptableFrameTypeSet(portID, IX_ETH_DB_ACCEPT_ALL_FRAMES);
|
||||
}
|
||||
|
||||
if (status == IX_ETH_DB_SUCCESS)
|
||||
{
|
||||
status = ixEthDBIngressVlanTaggingEnabledSet(portID, IX_ETH_DB_PASS_THROUGH);
|
||||
}
|
||||
|
||||
/* set membership and TTI tables */
|
||||
memset (vlanSet, 0xFF, sizeof (vlanSet));
|
||||
|
||||
if (status == IX_ETH_DB_SUCCESS)
|
||||
{
|
||||
/* use the internal function to bypass PVID check */
|
||||
status = ixEthDBPortVlanTableSet(portID, portInfo->vlanMembership, vlanSet);
|
||||
}
|
||||
|
||||
if (status == IX_ETH_DB_SUCCESS)
|
||||
{
|
||||
/* use the internal function to bypass PVID check */
|
||||
status = ixEthDBPortVlanTableSet(portID, portInfo->transmitTaggingInfo, vlanSet);
|
||||
}
|
||||
|
||||
/* reset the PVID */
|
||||
if (status == IX_ETH_DB_SUCCESS)
|
||||
{
|
||||
status = ixEthDBPortVlanTagSet(portID, 0);
|
||||
}
|
||||
|
||||
/* enable TPID port extraction */
|
||||
if (status == IX_ETH_DB_SUCCESS)
|
||||
{
|
||||
status = ixEthDBVlanPortExtractionEnable(portID, true);
|
||||
}
|
||||
}
|
||||
else if (feature == IX_ETH_DB_FIREWALL)
|
||||
#endif
|
||||
{
|
||||
/* firewall starts in black-list mode unless otherwise configured before *
|
||||
* note that invalid source MAC address filtering is disabled by default */
|
||||
if (portInfo->firewallMode != IX_ETH_DB_FIREWALL_BLACK_LIST
|
||||
&& portInfo->firewallMode != IX_ETH_DB_FIREWALL_WHITE_LIST)
|
||||
{
|
||||
status = ixEthDBFirewallModeSet(portID, IX_ETH_DB_FIREWALL_BLACK_LIST);
|
||||
|
||||
if (status == IX_ETH_DB_SUCCESS)
|
||||
{
|
||||
status = ixEthDBFirewallInvalidAddressFilterEnable(portID, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (status != IX_ETH_DB_SUCCESS)
|
||||
{
|
||||
/* checks failed, disable */
|
||||
portInfo->featureStatus &= ~feature;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* turn off features */
|
||||
if (feature == IX_ETH_DB_FIREWALL)
|
||||
{
|
||||
/* turning off the firewall is equivalent to:
|
||||
- set to black-list mode
|
||||
- clear all the entries and download the new table
|
||||
- turn off the invalid source address checking
|
||||
*/
|
||||
|
||||
status = ixEthDBDatabaseClear(portID, IX_ETH_DB_FIREWALL_RECORD);
|
||||
|
||||
if (status == IX_ETH_DB_SUCCESS)
|
||||
{
|
||||
status = ixEthDBFirewallModeSet(portID, IX_ETH_DB_FIREWALL_BLACK_LIST);
|
||||
}
|
||||
|
||||
if (status == IX_ETH_DB_SUCCESS)
|
||||
{
|
||||
status = ixEthDBFirewallInvalidAddressFilterEnable(portID, false);
|
||||
}
|
||||
|
||||
if (status == IX_ETH_DB_SUCCESS)
|
||||
{
|
||||
status = ixEthDBFirewallTableDownload(portID);
|
||||
}
|
||||
}
|
||||
else if (feature == IX_ETH_DB_WIFI_HEADER_CONVERSION)
|
||||
{
|
||||
/* turn off header conversion */
|
||||
status = ixEthDBDatabaseClear(portID, IX_ETH_DB_WIFI_RECORD);
|
||||
|
||||
if (status == IX_ETH_DB_SUCCESS)
|
||||
{
|
||||
status = ixEthDBWiFiConversionTableDownload(portID);
|
||||
}
|
||||
}
|
||||
#ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */
|
||||
else if (feature == IX_ETH_DB_VLAN_QOS)
|
||||
{
|
||||
/* turn off VLAN/QoS:
|
||||
- set a priority mapping table with one traffic class
|
||||
- set the acceptable frame filter to accept all
|
||||
- set the Ingress tagging mode to pass-through
|
||||
- clear the VLAN membership list
|
||||
- clear the TTI table
|
||||
- set the default 802.1Q tag to 0 (VLAN ID 0, Pri 0, CFI 0)
|
||||
- disable TPID port extraction
|
||||
*/
|
||||
|
||||
/* initialize all => traffic class 0 priority mapping table */
|
||||
memset (defaultPriorityTable, 0, sizeof (defaultPriorityTable));
|
||||
portInfo->ixEthDBTrafficClassCount = 1;
|
||||
status = ixEthDBPriorityMappingTableSet(portID, defaultPriorityTable);
|
||||
|
||||
if (status == IX_ETH_DB_SUCCESS)
|
||||
{
|
||||
status = ixEthDBAcceptableFrameTypeSet(portID, IX_ETH_DB_ACCEPT_ALL_FRAMES);
|
||||
}
|
||||
|
||||
if (status == IX_ETH_DB_SUCCESS)
|
||||
{
|
||||
status = ixEthDBIngressVlanTaggingEnabledSet(portID, IX_ETH_DB_PASS_THROUGH);
|
||||
}
|
||||
|
||||
/* clear membership and TTI tables */
|
||||
memset (vlanSet, 0, sizeof (vlanSet));
|
||||
|
||||
if (status == IX_ETH_DB_SUCCESS)
|
||||
{
|
||||
/* use the internal function to bypass PVID check */
|
||||
status = ixEthDBPortVlanTableSet(portID, portInfo->vlanMembership, vlanSet);
|
||||
}
|
||||
|
||||
if (status == IX_ETH_DB_SUCCESS)
|
||||
{
|
||||
/* use the internal function to bypass PVID check */
|
||||
status = ixEthDBPortVlanTableSet(portID, portInfo->transmitTaggingInfo, vlanSet);
|
||||
}
|
||||
|
||||
/* reset the PVID */
|
||||
if (status == IX_ETH_DB_SUCCESS)
|
||||
{
|
||||
status = ixEthDBPortVlanTagSet(portID, 0);
|
||||
}
|
||||
|
||||
/* disable TPID port extraction */
|
||||
if (status == IX_ETH_DB_SUCCESS)
|
||||
{
|
||||
status = ixEthDBVlanPortExtractionEnable(portID, false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (status == IX_ETH_DB_SUCCESS)
|
||||
{
|
||||
/* checks passed, disable */
|
||||
portInfo->featureStatus &= ~feature;
|
||||
}
|
||||
}
|
||||
|
||||
/* restore port enabled state */
|
||||
portInfo->enabled = portEnabled;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief returns the status of a feature
|
||||
*
|
||||
* @param portID port ID
|
||||
* @param present location to store a boolean value indicating
|
||||
* if the feature is present (true) or not (false)
|
||||
* @param enabled location to store a booleam value indicating
|
||||
* if the feature is present (true) or not (false)
|
||||
*
|
||||
* Note that this function is documented in the main component
|
||||
* header file, IxEthDB.h.
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the operation completed
|
||||
* successfully or an appropriate error message otherwise
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBFeatureStatusGet(IxEthDBPortId portID, IxEthDBFeature feature, BOOL *present, BOOL *enabled)
|
||||
{
|
||||
PortInfo *portInfo;
|
||||
|
||||
IX_ETH_DB_CHECK_PORT(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_REFERENCE(present);
|
||||
|
||||
IX_ETH_DB_CHECK_REFERENCE(enabled);
|
||||
|
||||
portInfo = &ixEthDBPortInfo[portID];
|
||||
|
||||
*present = (portInfo->featureCapability & feature) != 0;
|
||||
*enabled = (portInfo->featureStatus & feature) != 0;
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief returns the value of an EthDB property
|
||||
*
|
||||
* @param portID ID of the port
|
||||
* @param feature feature owning the property
|
||||
* @param property ID of the property
|
||||
* @param type location to store the property type into
|
||||
* @param value location to store the property value into
|
||||
*
|
||||
* Note that this function is documented in the main component
|
||||
* header file, IxEthDB.h.
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the operation completed
|
||||
* successfully or an appropriate error message otherwise
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBFeaturePropertyGet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, IxEthDBPropertyType *type, void *value)
|
||||
{
|
||||
IX_ETH_DB_CHECK_PORT_EXISTS(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_REFERENCE(type);
|
||||
|
||||
IX_ETH_DB_CHECK_REFERENCE(value);
|
||||
|
||||
if (feature == IX_ETH_DB_VLAN_QOS)
|
||||
{
|
||||
if (property == IX_ETH_DB_QOS_TRAFFIC_CLASS_COUNT_PROPERTY)
|
||||
{
|
||||
* (UINT32 *) value = ixEthDBPortInfo[portID].ixEthDBTrafficClassCount;
|
||||
*type = IX_ETH_DB_INTEGER_PROPERTY;
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
else if (property >= IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY
|
||||
&& property <= IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY)
|
||||
{
|
||||
UINT32 classDelta = property - IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY;
|
||||
|
||||
if (classDelta >= ixEthDBPortInfo[portID].ixEthDBTrafficClassCount)
|
||||
{
|
||||
return IX_ETH_DB_FAIL;
|
||||
}
|
||||
|
||||
* (UINT32 *) value = ixEthDBPortInfo[portID].ixEthDBTrafficClassAQMAssignments[classDelta];
|
||||
*type = IX_ETH_DB_INTEGER_PROPERTY;
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return IX_ETH_DB_INVALID_ARG;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief sets the value of an EthDB property
|
||||
*
|
||||
* @param portID ID of the port
|
||||
* @param feature feature owning the property
|
||||
* @param property ID of the property
|
||||
* @param value location containing the property value
|
||||
*
|
||||
* This function implements a private property intended
|
||||
* only for EthAcc usage. Upon setting the IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE
|
||||
* property (the value is ignored), the availability of traffic classes is
|
||||
* frozen to whatever traffic class structure is currently in use.
|
||||
* This means that if VLAN_QOS has been enabled before EthAcc
|
||||
* initialization then all the defined traffic classes will be available;
|
||||
* otherwise only one traffic class (0) will be available.
|
||||
*
|
||||
* Note that this function is documented in the main component
|
||||
* header file, IxEthDB.h as not accepting any parameters. The
|
||||
* current implementation is only intended for the private use of EthAcc.
|
||||
*
|
||||
* Also note that once this function is called the effect is irreversible,
|
||||
* unless EthDB is complete unloaded and re-initialized.
|
||||
*
|
||||
* @return IX_ETH_DB_INVALID_ARG (no read-write properties are
|
||||
* supported in this release)
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBFeaturePropertySet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, void *value)
|
||||
{
|
||||
IX_ETH_DB_CHECK_PORT_EXISTS(portID);
|
||||
|
||||
if ((feature == IX_ETH_DB_VLAN_QOS) && (property == IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE))
|
||||
{
|
||||
ixEthDBPortInfo[portID].ixEthDBTrafficClassAvailable = ixEthDBPortInfo[portID].ixEthDBTrafficClassCount;
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
||||
return IX_ETH_DB_INVALID_ARG;
|
||||
}
|
|
@ -1,242 +0,0 @@
|
|||
/**
|
||||
* @file IxEthDBFirewall.c
|
||||
*
|
||||
* @brief Implementation of the firewall API
|
||||
*
|
||||
* @par
|
||||
* IXP400 SW Release version 2.0
|
||||
*
|
||||
* -- Copyright Notice --
|
||||
*
|
||||
* @par
|
||||
* Copyright 2001-2005, Intel Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
* @par
|
||||
* -- End of Copyright Notice --
|
||||
*/
|
||||
|
||||
|
||||
#include "IxEthDB_p.h"
|
||||
|
||||
/**
|
||||
* @brief updates the NPE firewall operating mode and
|
||||
* firewall address table
|
||||
*
|
||||
* @param portID ID of the port
|
||||
* @param epDelta initial entry point for binary searches (NPE optimization)
|
||||
* @param address address of the firewall MAC address table
|
||||
*
|
||||
* This function will send a message to the NPE configuring the
|
||||
* firewall mode (white list or black list), invalid source
|
||||
* address filtering and downloading a new MAC address database
|
||||
* to be used for firewall matching.
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the operation completed
|
||||
* successfully or IX_ETH_DB_FAIL otherwise
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBFirewallUpdate(IxEthDBPortId portID, void *address, UINT32 epDelta)
|
||||
{
|
||||
IxNpeMhMessage message;
|
||||
IX_STATUS result;
|
||||
|
||||
UINT32 mode = 0;
|
||||
PortInfo *portInfo = &ixEthDBPortInfo[portID];
|
||||
|
||||
mode = (portInfo->srcAddressFilterEnabled != false) << 1 | (portInfo->firewallMode == IX_ETH_DB_FIREWALL_WHITE_LIST);
|
||||
|
||||
FILL_SETFIREWALLMODE_MSG(message,
|
||||
IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID),
|
||||
epDelta,
|
||||
mode,
|
||||
IX_OSAL_MMU_VIRT_TO_PHYS(address));
|
||||
|
||||
IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief configures the firewall white list/black list
|
||||
* access mode
|
||||
*
|
||||
* @param portID ID of the port
|
||||
* @param mode firewall filtering mode (IX_ETH_DB_FIREWALL_WHITE_LIST
|
||||
* or IX_ETH_DB_FIREWALL_BLACK_LIST)
|
||||
*
|
||||
* Note that this function is documented in the main component
|
||||
* header file, IxEthDB.h.
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the operation completed
|
||||
* successfully or an appropriate error message otherwise
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBFirewallModeSet(IxEthDBPortId portID, IxEthDBFirewallMode mode)
|
||||
{
|
||||
IX_ETH_DB_CHECK_PORT(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL);
|
||||
|
||||
if (mode != IX_ETH_DB_FIREWALL_WHITE_LIST
|
||||
&& mode != IX_ETH_DB_FIREWALL_BLACK_LIST)
|
||||
{
|
||||
return IX_ETH_DB_INVALID_ARG;
|
||||
}
|
||||
|
||||
ixEthDBPortInfo[portID].firewallMode = mode;
|
||||
|
||||
return ixEthDBFirewallTableDownload(portID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief enables or disables the invalid source MAC address filter
|
||||
*
|
||||
* @param portID ID of the port
|
||||
* @param enable true to enable invalid source MAC address filtering
|
||||
* or false to disable it
|
||||
*
|
||||
* The invalid source MAC address filter will discard, when enabled,
|
||||
* frames whose source MAC address is a multicast or the broadcast MAC
|
||||
* address.
|
||||
*
|
||||
* Note that this function is documented in the main component
|
||||
* header file, IxEthDB.h.
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the operation completed
|
||||
* successfully or an appropriate error message otherwise
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBFirewallInvalidAddressFilterEnable(IxEthDBPortId portID, BOOL enable)
|
||||
{
|
||||
IX_ETH_DB_CHECK_PORT(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL);
|
||||
|
||||
ixEthDBPortInfo[portID].srcAddressFilterEnabled = enable;
|
||||
|
||||
return ixEthDBFirewallTableDownload(portID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief adds a firewall record
|
||||
*
|
||||
* @param portID ID of the port
|
||||
* @param macAddr MAC address of the new record
|
||||
*
|
||||
* This function will add a new firewall record
|
||||
* on the specified port, using the specified
|
||||
* MAC address. If the record already exists this
|
||||
* function will silently return IX_ETH_DB_SUCCESS,
|
||||
* although no duplicate records are added.
|
||||
*
|
||||
* Note that this function is documented in the main
|
||||
* component header file, IxEthDB.h.
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the operation completed
|
||||
* successfully or an appropriate error message otherwise
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBFirewallEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
|
||||
{
|
||||
MacDescriptor recordTemplate;
|
||||
|
||||
IX_ETH_DB_CHECK_PORT(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_REFERENCE(macAddr);
|
||||
|
||||
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL);
|
||||
|
||||
memcpy(recordTemplate.macAddress, macAddr, sizeof (IxEthDBMacAddr));
|
||||
|
||||
recordTemplate.type = IX_ETH_DB_FIREWALL_RECORD;
|
||||
recordTemplate.portID = portID;
|
||||
|
||||
return ixEthDBAdd(&recordTemplate, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief removes a firewall record
|
||||
*
|
||||
* @param portID ID of the port
|
||||
* @param macAddr MAC address of the record to remove
|
||||
*
|
||||
* This function will attempt to remove a firewall
|
||||
* record from the given port, using the specified
|
||||
* MAC address.
|
||||
*
|
||||
* Note that this function is documented in the main
|
||||
* component header file, IxEthDB.h.
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the operation completed
|
||||
* successfully of an appropriate error message otherwise
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBFirewallEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
|
||||
{
|
||||
MacDescriptor recordTemplate;
|
||||
|
||||
IX_ETH_DB_CHECK_PORT(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_REFERENCE(macAddr);
|
||||
|
||||
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL);
|
||||
|
||||
memcpy(recordTemplate.macAddress, macAddr, sizeof (IxEthDBMacAddr));
|
||||
|
||||
recordTemplate.type = IX_ETH_DB_FIREWALL_RECORD;
|
||||
recordTemplate.portID = portID;
|
||||
|
||||
return ixEthDBRemove(&recordTemplate, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief downloads the firewall address table to an NPE
|
||||
*
|
||||
* @param portID ID of the port
|
||||
*
|
||||
* This function will download the firewall address table to
|
||||
* an NPE port.
|
||||
*
|
||||
* Note that this function is documented in the main
|
||||
* component header file, IxEthDB.h.
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the operation completed
|
||||
* successfully or IX_ETH_DB_FAIL otherwise
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBFirewallTableDownload(IxEthDBPortId portID)
|
||||
{
|
||||
IxEthDBPortMap query;
|
||||
IxEthDBStatus result;
|
||||
|
||||
IX_ETH_DB_CHECK_PORT(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL);
|
||||
|
||||
SET_DEPENDENCY_MAP(query, portID);
|
||||
|
||||
ixEthDBUpdateLock();
|
||||
|
||||
ixEthDBPortInfo[portID].updateMethod.searchTree = ixEthDBQuery(NULL, query, IX_ETH_DB_FIREWALL_RECORD, MAX_FW_SIZE);
|
||||
|
||||
result = ixEthDBNPEUpdateHandler(portID, IX_ETH_DB_FIREWALL_RECORD);
|
||||
|
||||
ixEthDBUpdateUnlock();
|
||||
|
||||
return result;
|
||||
}
|
|
@ -1,618 +0,0 @@
|
|||
/**
|
||||
* @file ethHash.c
|
||||
*
|
||||
* @brief Hashtable implementation
|
||||
*
|
||||
* @par
|
||||
* IXP400 SW Release version 2.0
|
||||
*
|
||||
* -- Copyright Notice --
|
||||
*
|
||||
* @par
|
||||
* Copyright 2001-2005, Intel Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
* @par
|
||||
* -- End of Copyright Notice --
|
||||
*/
|
||||
|
||||
|
||||
#include "IxEthDB_p.h"
|
||||
#include "IxEthDBLocks_p.h"
|
||||
|
||||
/**
|
||||
* @addtogroup EthDB
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief initializes a hash table object
|
||||
*
|
||||
* @param hashTable uninitialized hash table structure
|
||||
* @param numBuckets number of buckets to use
|
||||
* @param entryHashFunction hash function used
|
||||
* to hash entire hash node data block (for adding)
|
||||
* @param matchFunctions array of match functions, indexed on type,
|
||||
* used to differentiate records with the same hash value
|
||||
* @param freeFunction function used to free node data blocks
|
||||
*
|
||||
* Initializes the given hash table object.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
void ixEthDBInitHash(HashTable *hashTable,
|
||||
UINT32 numBuckets,
|
||||
HashFunction entryHashFunction,
|
||||
MatchFunction *matchFunctions,
|
||||
FreeFunction freeFunction)
|
||||
{
|
||||
UINT32 bucketIndex;
|
||||
UINT32 hashSize = numBuckets * sizeof(HashNode *);
|
||||
|
||||
/* entry hashing, matching and freeing methods */
|
||||
hashTable->entryHashFunction = entryHashFunction;
|
||||
hashTable->matchFunctions = matchFunctions;
|
||||
hashTable->freeFunction = freeFunction;
|
||||
|
||||
/* buckets */
|
||||
hashTable->numBuckets = numBuckets;
|
||||
|
||||
/* set to 0 all buckets */
|
||||
memset(hashTable->hashBuckets, 0, hashSize);
|
||||
|
||||
/* init bucket locks - note that initially all mutexes are unlocked after MutexInit()*/
|
||||
for (bucketIndex = 0 ; bucketIndex < numBuckets ; bucketIndex++)
|
||||
{
|
||||
ixOsalFastMutexInit(&hashTable->bucketLocks[bucketIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief adds an entry to the hash table
|
||||
*
|
||||
* @param hashTable hash table to add the entry to
|
||||
* @param entry entry to add
|
||||
*
|
||||
* The entry will be hashed using the entry hashing function and added to the
|
||||
* hash table, unless a locking blockage occurs, in which case the caller
|
||||
* should retry.
|
||||
*
|
||||
* @retval IX_ETH_DB_SUCCESS if adding <i>entry</i> has succeeded
|
||||
* @retval IX_ETH_DB_NOMEM if there's no memory left in the hash node pool
|
||||
* @retval IX_ETH_DB_BUSY if there's a locking failure on the insertion path
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBAddHashEntry(HashTable *hashTable, void *entry)
|
||||
{
|
||||
UINT32 hashValue = hashTable->entryHashFunction(entry);
|
||||
UINT32 bucketIndex = hashValue % hashTable->numBuckets;
|
||||
HashNode *bucket = hashTable->hashBuckets[bucketIndex];
|
||||
HashNode *newNode;
|
||||
|
||||
LockStack locks;
|
||||
|
||||
INIT_STACK(&locks);
|
||||
|
||||
/* lock bucket */
|
||||
PUSH_LOCK(&locks, &hashTable->bucketLocks[bucketIndex]);
|
||||
|
||||
/* lock insertion element (first in chain), if any */
|
||||
if (bucket != NULL)
|
||||
{
|
||||
PUSH_LOCK(&locks, &bucket->lock);
|
||||
}
|
||||
|
||||
/* get new node */
|
||||
newNode = ixEthDBAllocHashNode();
|
||||
|
||||
if (newNode == NULL)
|
||||
{
|
||||
/* unlock everything */
|
||||
UNROLL_STACK(&locks);
|
||||
|
||||
return IX_ETH_DB_NOMEM;
|
||||
}
|
||||
|
||||
/* init lock - note that mutexes are unlocked after MutexInit */
|
||||
ixOsalFastMutexInit(&newNode->lock);
|
||||
|
||||
/* populate new link */
|
||||
newNode->data = entry;
|
||||
|
||||
/* add to bucket */
|
||||
newNode->next = bucket;
|
||||
hashTable->hashBuckets[bucketIndex] = newNode;
|
||||
|
||||
/* unlock bucket and insertion point */
|
||||
UNROLL_STACK(&locks);
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief removes an entry from the hashtable
|
||||
*
|
||||
* @param hashTable hash table to remove entry from
|
||||
* @param keyType type of record key used for matching
|
||||
* @param reference reference key used to identify the entry
|
||||
*
|
||||
* The reference key will be hashed using the key hashing function,
|
||||
* the entry is searched using the hashed value and then examined
|
||||
* against the reference entry using the match function. A positive
|
||||
* match will trigger the deletion of the entry.
|
||||
* Locking failures are reported and the caller should retry.
|
||||
*
|
||||
* @retval IX_ETH_DB_SUCCESS if the removal was successful
|
||||
* @retval IX_ETH_DB_NO_SUCH_ADDR if the entry was not found
|
||||
* @retval IX_ETH_DB_BUSY if a locking failure occured during the process
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IxEthDBStatus ixEthDBRemoveHashEntry(HashTable *hashTable, int keyType, void *reference)
|
||||
{
|
||||
UINT32 hashValue = hashTable->entryHashFunction(reference);
|
||||
UINT32 bucketIndex = hashValue % hashTable->numBuckets;
|
||||
HashNode *node = hashTable->hashBuckets[bucketIndex];
|
||||
HashNode *previousNode = NULL;
|
||||
|
||||
LockStack locks;
|
||||
|
||||
INIT_STACK(&locks);
|
||||
|
||||
while (node != NULL)
|
||||
{
|
||||
/* try to lock node */
|
||||
PUSH_LOCK(&locks, &node->lock);
|
||||
|
||||
if (hashTable->matchFunctions[keyType](reference, node->data))
|
||||
{
|
||||
/* found entry */
|
||||
if (node->next != NULL)
|
||||
{
|
||||
PUSH_LOCK(&locks, &node->next->lock);
|
||||
}
|
||||
|
||||
if (previousNode == NULL)
|
||||
{
|
||||
/* node is head of chain */
|
||||
PUSH_LOCK(&locks, &hashTable->bucketLocks[bucketIndex]);
|
||||
|
||||
hashTable->hashBuckets[bucketIndex] = node->next;
|
||||
|
||||
POP_LOCK(&locks);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* relink */
|
||||
previousNode->next = node->next;
|
||||
}
|
||||
|
||||
UNROLL_STACK(&locks);
|
||||
|
||||
/* free node */
|
||||
hashTable->freeFunction(node->data);
|
||||
ixEthDBFreeHashNode(node);
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (previousNode != NULL)
|
||||
{
|
||||
/* unlock previous node */
|
||||
SHIFT_STACK(&locks);
|
||||
}
|
||||
|
||||
/* advance to next element in chain */
|
||||
previousNode = node;
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
|
||||
UNROLL_STACK(&locks);
|
||||
|
||||
/* not found */
|
||||
return IX_ETH_DB_NO_SUCH_ADDR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief retrieves an entry from the hash table
|
||||
*
|
||||
* @param hashTable hash table to perform the search into
|
||||
* @param reference search key (a MAC address)
|
||||
* @param keyType type of record key used for matching
|
||||
* @param searchResult pointer where a reference to the located hash node
|
||||
* is placed
|
||||
*
|
||||
* Searches the entry with the same key as <i>reference</i> and places the
|
||||
* pointer to the resulting node in <i>searchResult</i>.
|
||||
* An implicit write access lock is granted after a search, which gives the
|
||||
* caller the opportunity to modify the entry.
|
||||
* Access should be released as soon as possible using @ref ixEthDBReleaseHashNode().
|
||||
*
|
||||
* @see ixEthDBReleaseHashNode()
|
||||
*
|
||||
* @retval IX_ETH_DB_SUCCESS if the search was completed successfully
|
||||
* @retval IX_ETH_DB_NO_SUCH_ADDRESS if no entry with the given key was found
|
||||
* @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case
|
||||
* the caller should retry
|
||||
*
|
||||
* @warning unless the return value is <b>IX_ETH_DB_SUCCESS</b> the searchResult
|
||||
* location is NOT modified and therefore using a NULL comparison test when the
|
||||
* value was not properly initialized would be an error
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IxEthDBStatus ixEthDBSearchHashEntry(HashTable *hashTable, int keyType, void *reference, HashNode **searchResult)
|
||||
{
|
||||
UINT32 hashValue;
|
||||
HashNode *node;
|
||||
|
||||
hashValue = hashTable->entryHashFunction(reference);
|
||||
node = hashTable->hashBuckets[hashValue % hashTable->numBuckets];
|
||||
|
||||
while (node != NULL)
|
||||
{
|
||||
TRY_LOCK(&node->lock);
|
||||
|
||||
if (hashTable->matchFunctions[keyType](reference, node->data))
|
||||
{
|
||||
*searchResult = node;
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
UNLOCK(&node->lock);
|
||||
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* not found */
|
||||
return IX_ETH_DB_NO_SUCH_ADDR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief reports the existence of an entry in the hash table
|
||||
*
|
||||
* @param hashTable hash table to perform the search into
|
||||
* @param reference search key (a MAC address)
|
||||
* @param keyType type of record key used for matching
|
||||
*
|
||||
* Searches the entry with the same key as <i>reference</i>.
|
||||
* No implicit write access lock is granted after a search, hence the
|
||||
* caller cannot access or modify the entry. The result is only temporary.
|
||||
*
|
||||
* @see ixEthDBReleaseHashNode()
|
||||
*
|
||||
* @retval IX_ETH_DB_SUCCESS if the search was completed successfully
|
||||
* @retval IX_ETH_DB_NO_SUCH_ADDRESS if no entry with the given key was found
|
||||
* @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case
|
||||
* the caller should retry
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IxEthDBStatus ixEthDBPeekHashEntry(HashTable *hashTable, int keyType, void *reference)
|
||||
{
|
||||
UINT32 hashValue;
|
||||
HashNode *node;
|
||||
|
||||
hashValue = hashTable->entryHashFunction(reference);
|
||||
node = hashTable->hashBuckets[hashValue % hashTable->numBuckets];
|
||||
|
||||
while (node != NULL)
|
||||
{
|
||||
TRY_LOCK(&node->lock);
|
||||
|
||||
if (hashTable->matchFunctions[keyType](reference, node->data))
|
||||
{
|
||||
UNLOCK(&node->lock);
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
UNLOCK(&node->lock);
|
||||
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* not found */
|
||||
return IX_ETH_DB_NO_SUCH_ADDR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief releases the write access lock
|
||||
*
|
||||
* @pre the node should have been obtained via @ref ixEthDBSearchHashEntry()
|
||||
*
|
||||
* @see ixEthDBSearchHashEntry()
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
void ixEthDBReleaseHashNode(HashNode *node)
|
||||
{
|
||||
UNLOCK(&node->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief initializes a hash iterator
|
||||
*
|
||||
* @param hashTable hash table to be iterated
|
||||
* @param iterator iterator object
|
||||
*
|
||||
* If the initialization is successful the iterator will point to the
|
||||
* first hash table record (if any).
|
||||
* Testing if the iterator has not passed the end of the table should be
|
||||
* done using the IS_ITERATOR_VALID(iteratorPtr) macro.
|
||||
* An implicit write access lock is granted on the entry pointed by the iterator.
|
||||
* The access is automatically revoked when the iterator is incremented.
|
||||
* If the caller decides to terminate the iteration before the end of the table is
|
||||
* passed then the manual access release method, @ref ixEthDBReleaseHashIterator,
|
||||
* must be called.
|
||||
*
|
||||
* @see ixEthDBReleaseHashIterator()
|
||||
*
|
||||
* @retval IX_ETH_DB_SUCCESS if initialization was successful and the iterator points
|
||||
* to the first valid table node
|
||||
* @retval IX_ETH_DB_FAIL if the table is empty
|
||||
* @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case the caller
|
||||
* should retry
|
||||
*
|
||||
* @warning do not use ixEthDBReleaseHashNode() on entries pointed by the iterator, as this
|
||||
* might place the database in a permanent invalid lock state
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IxEthDBStatus ixEthDBInitHashIterator(HashTable *hashTable, HashIterator *iterator)
|
||||
{
|
||||
iterator->bucketIndex = 0;
|
||||
iterator->node = NULL;
|
||||
iterator->previousNode = NULL;
|
||||
|
||||
return ixEthDBIncrementHashIterator(hashTable, iterator);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief releases the write access locks of the iterator nodes
|
||||
*
|
||||
* @warning use of this function is required only when the caller terminates an iteration
|
||||
* before reaching the end of the table
|
||||
*
|
||||
* @see ixEthDBInitHashIterator()
|
||||
* @see ixEthDBIncrementHashIterator()
|
||||
*
|
||||
* @param iterator iterator whose node(s) should be unlocked
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
void ixEthDBReleaseHashIterator(HashIterator *iterator)
|
||||
{
|
||||
if (iterator->previousNode != NULL)
|
||||
{
|
||||
UNLOCK(&iterator->previousNode->lock);
|
||||
}
|
||||
|
||||
if (iterator->node != NULL)
|
||||
{
|
||||
UNLOCK(&iterator->node->lock);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief incremenents an iterator so that it points to the next valid entry of the table
|
||||
* (if any)
|
||||
*
|
||||
* @param hashTable hash table to iterate
|
||||
* @param iterator iterator object
|
||||
*
|
||||
* @pre the iterator object must be initialized using @ref ixEthDBInitHashIterator()
|
||||
*
|
||||
* If the increment operation is successful the iterator will point to the
|
||||
* next hash table record (if any).
|
||||
* Testing if the iterator has not passed the end of the table should be
|
||||
* done using the IS_ITERATOR_VALID(iteratorPtr) macro.
|
||||
* An implicit write access lock is granted on the entry pointed by the iterator.
|
||||
* The access is automatically revoked when the iterator is re-incremented.
|
||||
* If the caller decides to terminate the iteration before the end of the table is
|
||||
* passed then the manual access release method, @ref ixEthDBReleaseHashIterator,
|
||||
* must be called.
|
||||
* Is is guaranteed that no other thread can remove or change the iterated entry until
|
||||
* the iterator is incremented successfully.
|
||||
*
|
||||
* @see ixEthDBReleaseHashIterator()
|
||||
*
|
||||
* @retval IX_ETH_DB_SUCCESS if the operation was successful and the iterator points
|
||||
* to the next valid table node
|
||||
* @retval IX_ETH_DB_FAIL if the iterator has passed the end of the table
|
||||
* @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case the caller
|
||||
* should retry
|
||||
*
|
||||
* @warning do not use ixEthDBReleaseHashNode() on entries pointed by the iterator, as this
|
||||
* might place the database in a permanent invalid lock state
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IxEthDBStatus ixEthDBIncrementHashIterator(HashTable *hashTable, HashIterator *iterator)
|
||||
{
|
||||
/* unless iterator is just initialized... */
|
||||
if (iterator->node != NULL)
|
||||
{
|
||||
/* try next in chain */
|
||||
if (iterator->node->next != NULL)
|
||||
{
|
||||
TRY_LOCK(&iterator->node->next->lock);
|
||||
|
||||
if (iterator->previousNode != NULL)
|
||||
{
|
||||
UNLOCK(&iterator->previousNode->lock);
|
||||
}
|
||||
|
||||
iterator->previousNode = iterator->node;
|
||||
iterator->node = iterator->node->next;
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* last in chain, prepare for next bucket */
|
||||
iterator->bucketIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
/* try next used bucket */
|
||||
for (; iterator->bucketIndex < hashTable->numBuckets ; iterator->bucketIndex++)
|
||||
{
|
||||
HashNode **nodePtr = &(hashTable->hashBuckets[iterator->bucketIndex]);
|
||||
HashNode *node = *nodePtr;
|
||||
#if (CPU!=SIMSPARCSOLARIS) && !defined (__wince)
|
||||
if (((iterator->bucketIndex & IX_ETHDB_BUCKET_INDEX_MASK) == 0) &&
|
||||
(iterator->bucketIndex < (hashTable->numBuckets - IX_ETHDB_BUCKETPTR_AHEAD)))
|
||||
{
|
||||
/* preload next cache line (2 cache line ahead) */
|
||||
nodePtr += IX_ETHDB_BUCKETPTR_AHEAD;
|
||||
__asm__ ("pld [%0];\n": : "r" (nodePtr));
|
||||
}
|
||||
#endif
|
||||
if (node != NULL)
|
||||
{
|
||||
TRY_LOCK(&node->lock);
|
||||
|
||||
/* unlock last one or two nodes in the previous chain */
|
||||
if (iterator->node != NULL)
|
||||
{
|
||||
UNLOCK(&iterator->node->lock);
|
||||
|
||||
if (iterator->previousNode != NULL)
|
||||
{
|
||||
UNLOCK(&iterator->previousNode->lock);
|
||||
}
|
||||
}
|
||||
|
||||
/* redirect iterator */
|
||||
iterator->previousNode = NULL;
|
||||
iterator->node = node;
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/* could not advance iterator */
|
||||
if (iterator->node != NULL)
|
||||
{
|
||||
UNLOCK(&iterator->node->lock);
|
||||
|
||||
if (iterator->previousNode != NULL)
|
||||
{
|
||||
UNLOCK(&iterator->previousNode->lock);
|
||||
}
|
||||
|
||||
iterator->node = NULL;
|
||||
}
|
||||
|
||||
return IX_ETH_DB_END;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief removes an entry pointed by an iterator
|
||||
*
|
||||
* @param hashTable iterated hash table
|
||||
* @param iterator iterator object
|
||||
*
|
||||
* Removes the entry currently pointed by the iterator and repositions the iterator
|
||||
* on the next valid entry (if any). Handles locking issues automatically and
|
||||
* implicitely grants write access lock to the new pointed entry.
|
||||
* Failures due to concurrent threads having write access locks in the same region
|
||||
* preserve the state of the database and the iterator object, leaving the caller
|
||||
* free to retry without loss of access. It is guaranteed that only the thread owning
|
||||
* the iterator can remove the object pointed by the iterator.
|
||||
*
|
||||
* @retval IX_ETH_DB_SUCCESS if removal has succeeded
|
||||
* @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case the caller
|
||||
* should retry
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IxEthDBStatus ixEthDBRemoveEntryAtHashIterator(HashTable *hashTable, HashIterator *iterator)
|
||||
{
|
||||
HashIterator nextIteratorPos;
|
||||
LockStack locks;
|
||||
|
||||
INIT_STACK(&locks);
|
||||
|
||||
/* set initial bucket index for next position */
|
||||
nextIteratorPos.bucketIndex = iterator->bucketIndex;
|
||||
|
||||
/* compute iterator position before removing anything and lock ahead */
|
||||
if (iterator->node->next != NULL)
|
||||
{
|
||||
PUSH_LOCK(&locks, &iterator->node->next->lock);
|
||||
|
||||
/* reposition on the next node in the chain */
|
||||
nextIteratorPos.node = iterator->node->next;
|
||||
nextIteratorPos.previousNode = iterator->previousNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* try next chain - don't know yet if we'll find anything */
|
||||
nextIteratorPos.node = NULL;
|
||||
|
||||
/* if we find something it's a chain head */
|
||||
nextIteratorPos.previousNode = NULL;
|
||||
|
||||
/* browse up in the buckets to find a non-null chain */
|
||||
while (++nextIteratorPos.bucketIndex < hashTable->numBuckets)
|
||||
{
|
||||
nextIteratorPos.node = hashTable->hashBuckets[nextIteratorPos.bucketIndex];
|
||||
|
||||
if (nextIteratorPos.node != NULL)
|
||||
{
|
||||
/* found a non-empty chain, try to lock head */
|
||||
PUSH_LOCK(&locks, &nextIteratorPos.node->lock);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* restore links over the to-be-deleted item */
|
||||
if (iterator->previousNode == NULL)
|
||||
{
|
||||
/* first in chain, lock bucket */
|
||||
PUSH_LOCK(&locks, &hashTable->bucketLocks[iterator->bucketIndex]);
|
||||
|
||||
hashTable->hashBuckets[iterator->bucketIndex] = iterator->node->next;
|
||||
|
||||
POP_LOCK(&locks);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* relink */
|
||||
iterator->previousNode->next = iterator->node->next;
|
||||
|
||||
/* unlock last remaining node in current chain when moving between chains */
|
||||
if (iterator->node->next == NULL)
|
||||
{
|
||||
UNLOCK(&iterator->previousNode->lock);
|
||||
}
|
||||
}
|
||||
|
||||
/* delete entry */
|
||||
hashTable->freeFunction(iterator->node->data);
|
||||
ixEthDBFreeHashNode(iterator->node);
|
||||
|
||||
/* reposition iterator */
|
||||
*iterator = nextIteratorPos;
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
|
@ -1,125 +0,0 @@
|
|||
/**
|
||||
* @file IxEthDBLearning.c
|
||||
*
|
||||
* @par
|
||||
* IXP400 SW Release version 2.0
|
||||
*
|
||||
* -- Copyright Notice --
|
||||
*
|
||||
* @par
|
||||
* Copyright 2001-2005, Intel Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
* @par
|
||||
* -- End of Copyright Notice --
|
||||
*/
|
||||
|
||||
#include "IxEthDB_p.h"
|
||||
|
||||
/**
|
||||
* @brief hashes the mac address in a mac descriptor with a XOR function
|
||||
*
|
||||
* @param entry pointer to a mac descriptor to be hashed
|
||||
*
|
||||
* This function only extracts the mac address and employs ixEthDBKeyXORHash()
|
||||
* to do the actual hashing.
|
||||
* Used only to add a whole entry to a hash table, as opposed to searching which
|
||||
* takes only a key and uses the key hashing directly.
|
||||
*
|
||||
* @see ixEthDBKeyXORHash()
|
||||
*
|
||||
* @return the hash value
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
UINT32 ixEthDBEntryXORHash(void *entry)
|
||||
{
|
||||
MacDescriptor *descriptor = (MacDescriptor *) entry;
|
||||
|
||||
return ixEthDBKeyXORHash(descriptor->macAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief hashes a mac address
|
||||
*
|
||||
* @param key pointer to a 6 byte structure (typically an IxEthDBMacAddr pointer)
|
||||
* to be hashed
|
||||
*
|
||||
* Given a 6 bytes MAC address, the hash used is:
|
||||
*
|
||||
* hash(MAC[0:5]) = MAC[0:1] ^ MAC[2:3] ^ MAC[4:5]
|
||||
*
|
||||
* Used by the hash table to search and remove entries based
|
||||
* solely on their keys (mac addresses).
|
||||
*
|
||||
* @return the hash value
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
UINT32 ixEthDBKeyXORHash(void *key)
|
||||
{
|
||||
UINT32 hashValue;
|
||||
UINT8 *value = (UINT8 *) key;
|
||||
|
||||
hashValue = (value[5] << 8) | value[4];
|
||||
hashValue ^= (value[3] << 8) | value[2];
|
||||
hashValue ^= (value[1] << 8) | value[0];
|
||||
|
||||
return hashValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief mac descriptor match function
|
||||
*
|
||||
* @param reference mac address (typically an IxEthDBMacAddr pointer) structure
|
||||
* @param entry pointer to a mac descriptor whose key (mac address) is to be
|
||||
* matched against the reference key
|
||||
*
|
||||
* Used by the hash table to retrieve entries. Hashing entries can produce
|
||||
* collisions, i.e. descriptors with different mac addresses and the same
|
||||
* hash value, where this function is used to differentiate entries.
|
||||
*
|
||||
* @retval true if the entry matches the reference key (equal addresses)
|
||||
* @retval false if the entry does not match the reference key
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
BOOL ixEthDBAddressMatch(void *reference, void *entry)
|
||||
{
|
||||
return (ixEthDBAddressCompare(reference, ((MacDescriptor *) entry)->macAddress) == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief compares two mac addresses
|
||||
*
|
||||
* @param mac1 first mac address to compare
|
||||
* @param mac2 second mac address to compare
|
||||
*
|
||||
* This comparison works in a similar way to strcmp, producing similar results.
|
||||
* Used to insert values keyed on mac addresses into binary search trees.
|
||||
*
|
||||
* @retval -1 if mac1 < mac2
|
||||
* @retval 0 if ma1 == mac2
|
||||
* @retval 1 if mac1 > mac2
|
||||
*/
|
||||
UINT32 ixEthDBAddressCompare(UINT8 *mac1, UINT8 *mac2)
|
||||
{
|
||||
UINT32 local_index;
|
||||
|
||||
for (local_index = 0 ; local_index < IX_IEEE803_MAC_ADDRESS_SIZE ; local_index++)
|
||||
{
|
||||
if (mac1[local_index] > mac2[local_index])
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (mac1[local_index] < mac2[local_index])
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,625 +0,0 @@
|
|||
/**
|
||||
* @file IxEthDBDBMem.c
|
||||
*
|
||||
* @brief Memory handling routines for the MAC address database
|
||||
*
|
||||
* @par
|
||||
* IXP400 SW Release version 2.0
|
||||
*
|
||||
* -- Copyright Notice --
|
||||
*
|
||||
* @par
|
||||
* Copyright 2001-2005, Intel Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
* @par
|
||||
* -- End of Copyright Notice --
|
||||
*/
|
||||
|
||||
|
||||
#include "IxEthDB_p.h"
|
||||
|
||||
IX_ETH_DB_PRIVATE HashNode *nodePool = NULL;
|
||||
IX_ETH_DB_PRIVATE MacDescriptor *macPool = NULL;
|
||||
IX_ETH_DB_PRIVATE MacTreeNode *treePool = NULL;
|
||||
|
||||
IX_ETH_DB_PRIVATE HashNode nodePoolArea[NODE_POOL_SIZE];
|
||||
IX_ETH_DB_PRIVATE MacDescriptor macPoolArea[MAC_POOL_SIZE];
|
||||
IX_ETH_DB_PRIVATE MacTreeNode treePoolArea[TREE_POOL_SIZE];
|
||||
|
||||
IX_ETH_DB_PRIVATE IxOsalMutex nodePoolLock;
|
||||
IX_ETH_DB_PRIVATE IxOsalMutex macPoolLock;
|
||||
IX_ETH_DB_PRIVATE IxOsalMutex treePoolLock;
|
||||
|
||||
#define LOCK_NODE_POOL { ixOsalMutexLock(&nodePoolLock, IX_OSAL_WAIT_FOREVER); }
|
||||
#define UNLOCK_NODE_POOL { ixOsalMutexUnlock(&nodePoolLock); }
|
||||
|
||||
#define LOCK_MAC_POOL { ixOsalMutexLock(&macPoolLock, IX_OSAL_WAIT_FOREVER); }
|
||||
#define UNLOCK_MAC_POOL { ixOsalMutexUnlock(&macPoolLock); }
|
||||
|
||||
#define LOCK_TREE_POOL { ixOsalMutexLock(&treePoolLock, IX_OSAL_WAIT_FOREVER); }
|
||||
#define UNLOCK_TREE_POOL { ixOsalMutexUnlock(&treePoolLock); }
|
||||
|
||||
/* private function prototypes */
|
||||
IX_ETH_DB_PRIVATE MacDescriptor* ixEthDBPoolAllocMacDescriptor(void);
|
||||
IX_ETH_DB_PRIVATE void ixEthDBPoolFreeMacDescriptor(MacDescriptor *macDescriptor);
|
||||
|
||||
/**
|
||||
* @addtogroup EthMemoryManagement
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief initializes the memory pools used by the ethernet database component
|
||||
*
|
||||
* Initializes the hash table node, mac descriptor and mac tree node pools.
|
||||
* Called at initialization time by @ref ixEthDBInit().
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
void ixEthDBInitMemoryPools(void)
|
||||
{
|
||||
int local_index;
|
||||
|
||||
/* HashNode pool */
|
||||
ixOsalMutexInit(&nodePoolLock);
|
||||
|
||||
for (local_index = 0 ; local_index < NODE_POOL_SIZE ; local_index++)
|
||||
{
|
||||
HashNode *freeNode = &nodePoolArea[local_index];
|
||||
|
||||
freeNode->nextFree = nodePool;
|
||||
nodePool = freeNode;
|
||||
}
|
||||
|
||||
/* MacDescriptor pool */
|
||||
ixOsalMutexInit(&macPoolLock);
|
||||
|
||||
for (local_index = 0 ; local_index < MAC_POOL_SIZE ; local_index++)
|
||||
{
|
||||
MacDescriptor *freeDescriptor = &macPoolArea[local_index];
|
||||
|
||||
freeDescriptor->nextFree = macPool;
|
||||
macPool = freeDescriptor;
|
||||
}
|
||||
|
||||
/* MacTreeNode pool */
|
||||
ixOsalMutexInit(&treePoolLock);
|
||||
|
||||
for (local_index = 0 ; local_index < TREE_POOL_SIZE ; local_index++)
|
||||
{
|
||||
MacTreeNode *freeNode = &treePoolArea[local_index];
|
||||
|
||||
freeNode->nextFree = treePool;
|
||||
treePool = freeNode;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief allocates a hash node from the pool
|
||||
*
|
||||
* Allocates a hash node and resets its value.
|
||||
*
|
||||
* @return the allocated hash node or NULL if the pool is empty
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
HashNode* ixEthDBAllocHashNode(void)
|
||||
{
|
||||
HashNode *allocatedNode = NULL;
|
||||
|
||||
if (nodePool != NULL)
|
||||
{
|
||||
LOCK_NODE_POOL;
|
||||
|
||||
allocatedNode = nodePool;
|
||||
nodePool = nodePool->nextFree;
|
||||
|
||||
UNLOCK_NODE_POOL;
|
||||
|
||||
memset(allocatedNode, 0, sizeof(HashNode));
|
||||
}
|
||||
|
||||
return allocatedNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief frees a hash node into the pool
|
||||
*
|
||||
* @param hashNode node to be freed
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
void ixEthDBFreeHashNode(HashNode *hashNode)
|
||||
{
|
||||
if (hashNode != NULL)
|
||||
{
|
||||
LOCK_NODE_POOL;
|
||||
|
||||
hashNode->nextFree = nodePool;
|
||||
nodePool = hashNode;
|
||||
|
||||
UNLOCK_NODE_POOL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief allocates a mac descriptor from the pool
|
||||
*
|
||||
* Allocates a mac descriptor and resets its value.
|
||||
* This function is not used directly, instead @ref ixEthDBAllocMacDescriptor()
|
||||
* is used, which keeps track of the pointer reference count.
|
||||
*
|
||||
* @see ixEthDBAllocMacDescriptor()
|
||||
*
|
||||
* @warning this function is not used directly by any other function
|
||||
* apart from ixEthDBAllocMacDescriptor()
|
||||
*
|
||||
* @return the allocated mac descriptor or NULL if the pool is empty
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PRIVATE
|
||||
MacDescriptor* ixEthDBPoolAllocMacDescriptor(void)
|
||||
{
|
||||
MacDescriptor *allocatedDescriptor = NULL;
|
||||
|
||||
if (macPool != NULL)
|
||||
{
|
||||
LOCK_MAC_POOL;
|
||||
|
||||
allocatedDescriptor = macPool;
|
||||
macPool = macPool->nextFree;
|
||||
|
||||
UNLOCK_MAC_POOL;
|
||||
|
||||
memset(allocatedDescriptor, 0, sizeof(MacDescriptor));
|
||||
}
|
||||
|
||||
return allocatedDescriptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief allocates and initializes a mac descriptor smart pointer
|
||||
*
|
||||
* Uses @ref ixEthDBPoolAllocMacDescriptor() to allocate a mac descriptor
|
||||
* from the pool and initializes its reference count.
|
||||
*
|
||||
* @see ixEthDBPoolAllocMacDescriptor()
|
||||
*
|
||||
* @return the allocated mac descriptor or NULL if the pool is empty
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
MacDescriptor* ixEthDBAllocMacDescriptor(void)
|
||||
{
|
||||
MacDescriptor *allocatedDescriptor = ixEthDBPoolAllocMacDescriptor();
|
||||
|
||||
if (allocatedDescriptor != NULL)
|
||||
{
|
||||
LOCK_MAC_POOL;
|
||||
|
||||
allocatedDescriptor->refCount++;
|
||||
|
||||
UNLOCK_MAC_POOL;
|
||||
}
|
||||
|
||||
return allocatedDescriptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief frees a mac descriptor back into the pool
|
||||
*
|
||||
* @param macDescriptor mac descriptor to be freed
|
||||
*
|
||||
* @warning this function is not to be called by anyone but
|
||||
* ixEthDBFreeMacDescriptor()
|
||||
*
|
||||
* @see ixEthDBFreeMacDescriptor()
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PRIVATE
|
||||
void ixEthDBPoolFreeMacDescriptor(MacDescriptor *macDescriptor)
|
||||
{
|
||||
LOCK_MAC_POOL;
|
||||
|
||||
macDescriptor->nextFree = macPool;
|
||||
macPool = macDescriptor;
|
||||
|
||||
UNLOCK_MAC_POOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief frees or reduces the usage count of a mac descriptor smart pointer
|
||||
*
|
||||
* If the reference count reaches 0 (structure is no longer used anywhere)
|
||||
* then the descriptor is freed back into the pool using ixEthDBPoolFreeMacDescriptor().
|
||||
*
|
||||
* @see ixEthDBPoolFreeMacDescriptor()
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
void ixEthDBFreeMacDescriptor(MacDescriptor *macDescriptor)
|
||||
{
|
||||
if (macDescriptor != NULL)
|
||||
{
|
||||
LOCK_MAC_POOL;
|
||||
|
||||
if (macDescriptor->refCount > 0)
|
||||
{
|
||||
macDescriptor->refCount--;
|
||||
|
||||
if (macDescriptor->refCount == 0)
|
||||
{
|
||||
UNLOCK_MAC_POOL;
|
||||
|
||||
ixEthDBPoolFreeMacDescriptor(macDescriptor);
|
||||
}
|
||||
else
|
||||
{
|
||||
UNLOCK_MAC_POOL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UNLOCK_MAC_POOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief clones a mac descriptor smart pointer
|
||||
*
|
||||
* @param macDescriptor mac descriptor to clone
|
||||
*
|
||||
* Increments the usage count of the smart pointer
|
||||
*
|
||||
* @returns the cloned smart pointer
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
MacDescriptor* ixEthDBCloneMacDescriptor(MacDescriptor *macDescriptor)
|
||||
{
|
||||
LOCK_MAC_POOL;
|
||||
|
||||
if (macDescriptor->refCount == 0)
|
||||
{
|
||||
UNLOCK_MAC_POOL;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
macDescriptor->refCount++;
|
||||
|
||||
UNLOCK_MAC_POOL;
|
||||
|
||||
return macDescriptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief allocates a mac tree node from the pool
|
||||
*
|
||||
* Allocates and initializes a mac tree node from the pool.
|
||||
*
|
||||
* @return the allocated mac tree node or NULL if the pool is empty
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
MacTreeNode* ixEthDBAllocMacTreeNode(void)
|
||||
{
|
||||
MacTreeNode *allocatedNode = NULL;
|
||||
|
||||
if (treePool != NULL)
|
||||
{
|
||||
LOCK_TREE_POOL;
|
||||
|
||||
allocatedNode = treePool;
|
||||
treePool = treePool->nextFree;
|
||||
|
||||
UNLOCK_TREE_POOL;
|
||||
|
||||
memset(allocatedNode, 0, sizeof(MacTreeNode));
|
||||
}
|
||||
|
||||
return allocatedNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief frees a mac tree node back into the pool
|
||||
*
|
||||
* @param macNode mac tree node to be freed
|
||||
*
|
||||
* @warning not to be used except from ixEthDBFreeMacTreeNode().
|
||||
*
|
||||
* @see ixEthDBFreeMacTreeNode()
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
void ixEthDBPoolFreeMacTreeNode(MacTreeNode *macNode)
|
||||
{
|
||||
if (macNode != NULL)
|
||||
{
|
||||
LOCK_TREE_POOL;
|
||||
|
||||
macNode->nextFree = treePool;
|
||||
treePool = macNode;
|
||||
|
||||
UNLOCK_TREE_POOL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief frees or reduces the usage count of a mac tree node smart pointer
|
||||
*
|
||||
* @param macNode mac tree node to free
|
||||
*
|
||||
* Reduces the usage count of the given mac node. If the usage count
|
||||
* reaches 0 the node is freed back into the pool using ixEthDBPoolFreeMacTreeNode()
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
void ixEthDBFreeMacTreeNode(MacTreeNode *macNode)
|
||||
{
|
||||
if (macNode->descriptor != NULL)
|
||||
{
|
||||
ixEthDBFreeMacDescriptor(macNode->descriptor);
|
||||
}
|
||||
|
||||
if (macNode->left != NULL)
|
||||
{
|
||||
ixEthDBFreeMacTreeNode(macNode->left);
|
||||
}
|
||||
|
||||
if (macNode->right != NULL)
|
||||
{
|
||||
ixEthDBFreeMacTreeNode(macNode->right);
|
||||
}
|
||||
|
||||
ixEthDBPoolFreeMacTreeNode(macNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief clones a mac tree node
|
||||
*
|
||||
* @param macNode mac tree node to be cloned
|
||||
*
|
||||
* Increments the usage count of the node, <i>its associated descriptor
|
||||
* and <b>recursively</b> of all its child nodes</i>.
|
||||
*
|
||||
* @warning this function is recursive and clones whole trees/subtrees, use only for
|
||||
* root nodes
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
MacTreeNode* ixEthDBCloneMacTreeNode(MacTreeNode *macNode)
|
||||
{
|
||||
if (macNode != NULL)
|
||||
{
|
||||
MacTreeNode *clonedMacNode = ixEthDBAllocMacTreeNode();
|
||||
|
||||
if (clonedMacNode != NULL)
|
||||
{
|
||||
if (macNode->right != NULL)
|
||||
{
|
||||
clonedMacNode->right = ixEthDBCloneMacTreeNode(macNode->right);
|
||||
}
|
||||
|
||||
if (macNode->left != NULL)
|
||||
{
|
||||
clonedMacNode->left = ixEthDBCloneMacTreeNode(macNode->left);
|
||||
}
|
||||
|
||||
if (macNode->descriptor != NULL)
|
||||
{
|
||||
clonedMacNode->descriptor = ixEthDBCloneMacDescriptor(macNode->descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
return clonedMacNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
/* Debug statistical functions for memory usage */
|
||||
|
||||
extern HashTable dbHashtable;
|
||||
int ixEthDBNumHashElements(void);
|
||||
|
||||
int ixEthDBNumHashElements(void)
|
||||
{
|
||||
UINT32 bucketIndex;
|
||||
int numElements = 0;
|
||||
HashTable *hashTable = &dbHashtable;
|
||||
|
||||
for (bucketIndex = 0 ; bucketIndex < hashTable->numBuckets ; bucketIndex++)
|
||||
{
|
||||
if (hashTable->hashBuckets[bucketIndex] != NULL)
|
||||
{
|
||||
HashNode *node = hashTable->hashBuckets[bucketIndex];
|
||||
|
||||
while (node != NULL)
|
||||
{
|
||||
numElements++;
|
||||
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return numElements;
|
||||
}
|
||||
|
||||
UINT32 ixEthDBSearchTreeUsageGet(MacTreeNode *tree)
|
||||
{
|
||||
if (tree == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1 /* this node */ + ixEthDBSearchTreeUsageGet(tree->left) + ixEthDBSearchTreeUsageGet(tree->right);
|
||||
}
|
||||
}
|
||||
|
||||
int ixEthDBShowMemoryStatus(void)
|
||||
{
|
||||
MacDescriptor *mac;
|
||||
MacTreeNode *tree;
|
||||
HashNode *node;
|
||||
|
||||
int macCounter = 0;
|
||||
int treeCounter = 0;
|
||||
int nodeCounter = 0;
|
||||
|
||||
int totalTreeUsage = 0;
|
||||
int totalDescriptorUsage = 0;
|
||||
int totalCloneDescriptorUsage = 0;
|
||||
int totalNodeUsage = 0;
|
||||
|
||||
UINT32 portIndex;
|
||||
|
||||
LOCK_NODE_POOL;
|
||||
LOCK_MAC_POOL;
|
||||
LOCK_TREE_POOL;
|
||||
|
||||
mac = macPool;
|
||||
tree = treePool;
|
||||
node = nodePool;
|
||||
|
||||
while (mac != NULL)
|
||||
{
|
||||
macCounter++;
|
||||
|
||||
mac = mac->nextFree;
|
||||
|
||||
if (macCounter > MAC_POOL_SIZE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (tree != NULL)
|
||||
{
|
||||
treeCounter++;
|
||||
|
||||
tree = tree->nextFree;
|
||||
|
||||
if (treeCounter > TREE_POOL_SIZE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (node != NULL)
|
||||
{
|
||||
nodeCounter++;
|
||||
|
||||
node = node->nextFree;
|
||||
|
||||
if (nodeCounter > NODE_POOL_SIZE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
|
||||
{
|
||||
int treeUsage = ixEthDBSearchTreeUsageGet(ixEthDBPortInfo[portIndex].updateMethod.searchTree);
|
||||
|
||||
totalTreeUsage += treeUsage;
|
||||
totalCloneDescriptorUsage += treeUsage; /* each tree node contains a descriptor */
|
||||
}
|
||||
|
||||
totalNodeUsage = ixEthDBNumHashElements();
|
||||
totalDescriptorUsage += totalNodeUsage; /* each hash table entry contains a descriptor */
|
||||
|
||||
UNLOCK_NODE_POOL;
|
||||
UNLOCK_MAC_POOL;
|
||||
UNLOCK_TREE_POOL;
|
||||
|
||||
printf("Ethernet database memory usage stats:\n\n");
|
||||
|
||||
if (macCounter <= MAC_POOL_SIZE)
|
||||
{
|
||||
printf("\tMAC descriptor pool : %d free out of %d entries (%d%%)\n", macCounter, MAC_POOL_SIZE, macCounter * 100 / MAC_POOL_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\tMAC descriptor pool : invalid state (ring within the pool), normally %d entries\n", MAC_POOL_SIZE);
|
||||
}
|
||||
|
||||
if (treeCounter <= TREE_POOL_SIZE)
|
||||
{
|
||||
printf("\tTree node pool : %d free out of %d entries (%d%%)\n", treeCounter, TREE_POOL_SIZE, treeCounter * 100 / TREE_POOL_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\tTREE descriptor pool : invalid state (ring within the pool), normally %d entries\n", TREE_POOL_SIZE);
|
||||
}
|
||||
|
||||
if (nodeCounter <= NODE_POOL_SIZE)
|
||||
{
|
||||
printf("\tHash node pool : %d free out of %d entries (%d%%)\n", nodeCounter, NODE_POOL_SIZE, nodeCounter * 100 / NODE_POOL_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\tNODE descriptor pool : invalid state (ring within the pool), normally %d entries\n", NODE_POOL_SIZE);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
printf("\tMAC descriptor usage : %d entries, %d cloned\n", totalDescriptorUsage, totalCloneDescriptorUsage);
|
||||
printf("\tTree node usage : %d entries\n", totalTreeUsage);
|
||||
printf("\tHash node usage : %d entries\n", totalNodeUsage);
|
||||
printf("\n");
|
||||
|
||||
/* search for duplicate nodes in the mac pool */
|
||||
{
|
||||
MacDescriptor *reference = macPool;
|
||||
|
||||
while (reference != NULL)
|
||||
{
|
||||
MacDescriptor *comparison = reference->nextFree;
|
||||
|
||||
while (comparison != NULL)
|
||||
{
|
||||
if (reference == comparison)
|
||||
{
|
||||
printf("Warning: reached a duplicate (%p), invalid MAC pool state\n", reference);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
comparison = comparison->nextFree;
|
||||
}
|
||||
|
||||
reference = reference->nextFree;
|
||||
}
|
||||
}
|
||||
|
||||
printf("No duplicates found in the MAC pool (sanity check ok)\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* NDEBUG */
|
||||
|
||||
/**
|
||||
* @} EthMemoryManagement
|
||||
*/
|
|
@ -1,695 +0,0 @@
|
|||
/**
|
||||
* @file IxEthDBDBNPEAdaptor.c
|
||||
*
|
||||
* @brief Routines that read and write learning/search trees in NPE-specific format
|
||||
*
|
||||
* @par
|
||||
* IXP400 SW Release version 2.0
|
||||
*
|
||||
* -- Copyright Notice --
|
||||
*
|
||||
* @par
|
||||
* Copyright 2001-2005, Intel Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
* @par
|
||||
* -- End of Copyright Notice --
|
||||
*/
|
||||
|
||||
#include "IxEthDB_p.h"
|
||||
#include "IxEthDBLog_p.h"
|
||||
|
||||
/* forward prototype declarations */
|
||||
IX_ETH_DB_PUBLIC void ixEthDBELTShow(IxEthDBPortId portID);
|
||||
IX_ETH_DB_PUBLIC void ixEthDBShowNpeMsgHistory(void);
|
||||
|
||||
/* data */
|
||||
UINT8* ixEthDBNPEUpdateArea[IX_ETH_DB_NUMBER_OF_PORTS];
|
||||
UINT32 dumpEltSize;
|
||||
|
||||
/* private data */
|
||||
IX_ETH_DB_PRIVATE IxEthDBNoteWriteFn ixEthDBNPENodeWrite[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1];
|
||||
|
||||
#define IX_ETH_DB_MAX_DELTA_ZONES (6) /* at most 6 EP Delta zones, according to NPE FS */
|
||||
IX_ETH_DB_PRIVATE UINT32 ixEthDBEPDeltaOffset[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1][IX_ETH_DB_MAX_DELTA_ZONES];
|
||||
IX_ETH_DB_PRIVATE UINT32 ixEthDBEPDelta[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1][IX_ETH_DB_MAX_DELTA_ZONES];
|
||||
|
||||
/**
|
||||
* @brief allocates non-cached or contiguous NPE tree update areas for all the ports
|
||||
*
|
||||
* This function is called only once at initialization time from
|
||||
* @ref ixEthDBInit().
|
||||
*
|
||||
* @warning do not call manually
|
||||
*
|
||||
* @see ixEthDBInit()
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
void ixEthDBNPEUpdateAreasInit(void)
|
||||
{
|
||||
UINT32 portIndex;
|
||||
PortUpdateMethod *update;
|
||||
|
||||
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
|
||||
{
|
||||
update = &ixEthDBPortInfo[portIndex].updateMethod;
|
||||
|
||||
if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE)
|
||||
{
|
||||
update->npeUpdateZone = IX_OSAL_CACHE_DMA_MALLOC(FULL_ELT_BYTE_SIZE);
|
||||
update->npeGwUpdateZone = IX_OSAL_CACHE_DMA_MALLOC(FULL_GW_BYTE_SIZE);
|
||||
update->vlanUpdateZone = IX_OSAL_CACHE_DMA_MALLOC(FULL_VLAN_BYTE_SIZE);
|
||||
|
||||
if (update->npeUpdateZone == NULL
|
||||
|| update->npeGwUpdateZone == NULL
|
||||
|| update->vlanUpdateZone == NULL)
|
||||
{
|
||||
ERROR_LOG("Fatal error: IX_ACC_DRV_DMA_MALLOC() returned NULL, no NPE update zones available\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(update->npeUpdateZone, 0, FULL_ELT_BYTE_SIZE);
|
||||
memset(update->npeGwUpdateZone, 0, FULL_GW_BYTE_SIZE);
|
||||
memset(update->vlanUpdateZone, 0, FULL_VLAN_BYTE_SIZE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* unused */
|
||||
update->npeUpdateZone = NULL;
|
||||
update->npeGwUpdateZone = NULL;
|
||||
update->vlanUpdateZone = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief deallocates the NPE update areas for all the ports
|
||||
*
|
||||
* This function is called at component de-initialization time
|
||||
* by @ref ixEthDBUnload().
|
||||
*
|
||||
* @warning do not call manually
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
void ixEthDBNPEUpdateAreasUnload(void)
|
||||
{
|
||||
UINT32 portIndex;
|
||||
|
||||
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
|
||||
{
|
||||
if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE)
|
||||
{
|
||||
IX_OSAL_CACHE_DMA_FREE(ixEthDBPortInfo[portIndex].updateMethod.npeUpdateZone);
|
||||
IX_OSAL_CACHE_DMA_FREE(ixEthDBPortInfo[portIndex].updateMethod.npeGwUpdateZone);
|
||||
IX_OSAL_CACHE_DMA_FREE(ixEthDBPortInfo[portIndex].updateMethod.vlanUpdateZone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief general-purpose NPE callback function
|
||||
*
|
||||
* @param npeID NPE ID
|
||||
* @param msg NPE message
|
||||
*
|
||||
* This function will unblock the caller by unlocking
|
||||
* the npeAckLock mutex defined for each NPE port
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
void ixEthDBNpeMsgAck(IxNpeMhNpeId npeID, IxNpeMhMessage msg)
|
||||
{
|
||||
IxEthDBPortId portID = IX_ETH_DB_NPE_TO_PORT_ID(npeID);
|
||||
PortInfo *portInfo;
|
||||
|
||||
if (portID >= IX_ETH_DB_NUMBER_OF_PORTS)
|
||||
{
|
||||
/* invalid port */
|
||||
return;
|
||||
}
|
||||
|
||||
if (ixEthDBPortDefinitions[portID].type != IX_ETH_NPE)
|
||||
{
|
||||
/* not an NPE */
|
||||
return;
|
||||
}
|
||||
|
||||
portInfo = &ixEthDBPortInfo[portID];
|
||||
|
||||
ixOsalMutexUnlock(&portInfo->npeAckLock);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief synchronizes the database with tree
|
||||
*
|
||||
* @param portID port ID of the NPE whose tree is to be scanned
|
||||
* @param eltBaseAddress memory base address of the NPE serialized tree
|
||||
* @param eltSize size in bytes of the NPE serialized tree
|
||||
*
|
||||
* Scans the NPE learning tree and resets the age of active database records.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
void ixEthDBNPESyncScan(IxEthDBPortId portID, void *eltBaseAddress, UINT32 eltSize)
|
||||
{
|
||||
UINT32 eltEntryOffset;
|
||||
UINT32 entryPortID;
|
||||
|
||||
/* invalidate cache */
|
||||
IX_OSAL_CACHE_INVALIDATE(eltBaseAddress, eltSize);
|
||||
|
||||
for (eltEntryOffset = ELT_ROOT_OFFSET ; eltEntryOffset < eltSize ; eltEntryOffset += ELT_ENTRY_SIZE)
|
||||
{
|
||||
/* (eltBaseAddress + eltEntryOffset) points to a valid NPE tree node
|
||||
*
|
||||
* the format of the node is MAC[6 bytes]:PortID[1 byte]:Reserved[6 bits]:Active[1 bit]:Valid[1 bit]
|
||||
* therefore we can just use the pointer for database searches as only the first 6 bytes are checked
|
||||
*/
|
||||
void *eltNodeAddress = (void *) ((UINT32) eltBaseAddress + eltEntryOffset);
|
||||
|
||||
/* debug */
|
||||
IX_ETH_DB_NPE_VERBOSE_TRACE("DB: (NPEAdaptor) checking node at offset %d...\n", eltEntryOffset / ELT_ENTRY_SIZE);
|
||||
|
||||
if (IX_EDB_NPE_NODE_VALID(eltNodeAddress) != true)
|
||||
{
|
||||
IX_ETH_DB_NPE_VERBOSE_TRACE("\t... node is empty\n");
|
||||
}
|
||||
else if (eltEntryOffset == ELT_ROOT_OFFSET)
|
||||
{
|
||||
IX_ETH_DB_NPE_VERBOSE_TRACE("\t... node is root\n");
|
||||
}
|
||||
|
||||
if (IX_EDB_NPE_NODE_VALID(eltNodeAddress))
|
||||
{
|
||||
entryPortID = IX_ETH_DB_NPE_LOGICAL_ID_TO_PORT_ID(IX_EDB_NPE_NODE_PORT_ID(eltNodeAddress));
|
||||
|
||||
/* check only active entries belonging to this port */
|
||||
if (ixEthDBPortInfo[portID].agingEnabled && IX_EDB_NPE_NODE_ACTIVE(eltNodeAddress) && (portID == entryPortID)
|
||||
&& ((ixEthDBPortDefinitions[portID].capabilities & IX_ETH_ENTRY_AGING) == 0))
|
||||
{
|
||||
/* search record */
|
||||
HashNode *node = ixEthDBSearch((IxEthDBMacAddr *) eltNodeAddress, IX_ETH_DB_ALL_FILTERING_RECORDS);
|
||||
|
||||
/* safety check, maybe user deleted record right before sync? */
|
||||
if (node != NULL)
|
||||
{
|
||||
/* found record */
|
||||
MacDescriptor *descriptor = (MacDescriptor *) node->data;
|
||||
|
||||
IX_ETH_DB_NPE_VERBOSE_TRACE("DB: (NPEAdaptor) synced entry [%s] already in the database, updating fields\n", mac2string(eltNodeAddress));
|
||||
|
||||
/* reset age - set to -1 so that maintenance will restore it to 0 (or more) when incrementing */
|
||||
if (!descriptor->recordData.filteringData.staticEntry)
|
||||
{
|
||||
if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
|
||||
{
|
||||
descriptor->recordData.filteringData.age = AGE_RESET;
|
||||
}
|
||||
else if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD)
|
||||
{
|
||||
descriptor->recordData.filteringVlanData.age = AGE_RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/* end transaction */
|
||||
ixEthDBReleaseHashNode(node);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IX_ETH_DB_NPE_VERBOSE_TRACE("\t... found portID %d, we check only port %d\n", entryPortID, portID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief writes a search tree in NPE format
|
||||
*
|
||||
* @param type type of records to be written into the NPE update zone
|
||||
* @param totalSize maximum size of the linearized tree
|
||||
* @param baseAddress memory base address where to write the NPE tree into
|
||||
* @param tree search tree to write in NPE format
|
||||
* @param blocks number of written 64-byte blocks
|
||||
* @param startIndex optimal binary search start index
|
||||
*
|
||||
* Serializes the given tree in NPE linear format
|
||||
*
|
||||
* @return none
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
void ixEthDBNPETreeWrite(IxEthDBRecordType type, UINT32 totalSize, void *baseAddress, MacTreeNode *tree, UINT32 *epDelta, UINT32 *blocks)
|
||||
{
|
||||
MacTreeNodeStack *stack;
|
||||
UINT32 maxOffset = 0;
|
||||
UINT32 emptyOffset;
|
||||
|
||||
stack = ixOsalCacheDmaMalloc(sizeof (MacTreeNodeStack));
|
||||
|
||||
if (stack == NULL)
|
||||
{
|
||||
ERROR_LOG("DB: (NPEAdaptor) failed to allocate the node stack for learning tree linearization, out of memory?\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* zero out empty root */
|
||||
memset(baseAddress, 0, ELT_ENTRY_SIZE);
|
||||
|
||||
NODE_STACK_INIT(stack);
|
||||
|
||||
if (tree != NULL)
|
||||
{
|
||||
/* push tree root at offset 1 */
|
||||
NODE_STACK_PUSH(stack, tree, 1);
|
||||
|
||||
maxOffset = 1;
|
||||
}
|
||||
|
||||
while (NODE_STACK_NONEMPTY(stack))
|
||||
{
|
||||
MacTreeNode *node;
|
||||
UINT32 offset;
|
||||
|
||||
NODE_STACK_POP(stack, node, offset);
|
||||
|
||||
/* update maximum offset */
|
||||
if (offset > maxOffset)
|
||||
{
|
||||
maxOffset = offset;
|
||||
}
|
||||
|
||||
IX_ETH_DB_NPE_VERBOSE_TRACE("DB: (NPEAdaptor) writing MAC [%s] at offset %d\n", mac2string(node->descriptor->macAddress), offset);
|
||||
|
||||
/* add node to NPE ELT at position indicated by offset */
|
||||
if (offset < MAX_ELT_SIZE)
|
||||
{
|
||||
ixEthDBNPENodeWrite[type]((void *) (((UINT32) baseAddress) + offset * ELT_ENTRY_SIZE), node);
|
||||
}
|
||||
|
||||
if (node->left != NULL)
|
||||
{
|
||||
NODE_STACK_PUSH(stack, node->left, LEFT_CHILD_OFFSET(offset));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ensure this entry is zeroed */
|
||||
memset((void *) ((UINT32) baseAddress + LEFT_CHILD_OFFSET(offset) * ELT_ENTRY_SIZE), 0, ELT_ENTRY_SIZE);
|
||||
}
|
||||
|
||||
if (node->right != NULL)
|
||||
{
|
||||
NODE_STACK_PUSH(stack, node->right, RIGHT_CHILD_OFFSET(offset));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ensure this entry is zeroed */
|
||||
memset((void *) ((UINT32) baseAddress + RIGHT_CHILD_OFFSET(offset) * ELT_ENTRY_SIZE), 0, ELT_ENTRY_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
emptyOffset = maxOffset + 1;
|
||||
|
||||
/* zero out rest of the tree */
|
||||
IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Emptying tree from offset %d, address 0x%08X, %d bytes\n",
|
||||
emptyOffset, ((UINT32) baseAddress) + emptyOffset * ELT_ENTRY_SIZE, totalSize - (emptyOffset * ELT_ENTRY_SIZE));
|
||||
|
||||
if (emptyOffset < MAX_ELT_SIZE - 1)
|
||||
{
|
||||
memset((void *) (((UINT32) baseAddress) + (emptyOffset * ELT_ENTRY_SIZE)), 0, totalSize - (emptyOffset * ELT_ENTRY_SIZE));
|
||||
}
|
||||
|
||||
/* flush cache */
|
||||
IX_OSAL_CACHE_FLUSH(baseAddress, totalSize);
|
||||
|
||||
/* debug */
|
||||
IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Ethernet learning/filtering tree XScale wrote at address 0x%08X (max %d bytes):\n\n",
|
||||
(UINT32) baseAddress, FULL_ELT_BYTE_SIZE);
|
||||
|
||||
IX_ETH_DB_NPE_DUMP_ELT(baseAddress, FULL_ELT_BYTE_SIZE);
|
||||
|
||||
/* compute number of 64-byte blocks */
|
||||
if (blocks != NULL)
|
||||
{
|
||||
*blocks = maxOffset != 0 ? 1 + maxOffset / 8 : 0;
|
||||
|
||||
IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Wrote %d 64-byte blocks\n", *blocks);
|
||||
}
|
||||
|
||||
/* compute epDelta - start index for binary search */
|
||||
if (epDelta != NULL)
|
||||
{
|
||||
UINT32 deltaIndex = 0;
|
||||
|
||||
*epDelta = 0;
|
||||
|
||||
for (; deltaIndex < IX_ETH_DB_MAX_DELTA_ZONES ; deltaIndex ++)
|
||||
{
|
||||
if (ixEthDBEPDeltaOffset[type][deltaIndex] >= maxOffset)
|
||||
{
|
||||
*epDelta = ixEthDBEPDelta[type][deltaIndex];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Computed epDelta %d (based on maxOffset %d)\n", *epDelta, maxOffset);
|
||||
}
|
||||
|
||||
ixOsalCacheDmaFree(stack);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief implements a dummy node serialization function
|
||||
*
|
||||
* @param address address of where the node is to be serialized (unused)
|
||||
* @param node tree node to be serialized (unused)
|
||||
*
|
||||
* This function is registered for safety reasons and should
|
||||
* never be called. It will display an error message if this
|
||||
* function is called.
|
||||
*
|
||||
* @return none
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PRIVATE
|
||||
void ixEthDBNullSerialize(void *address, MacTreeNode *node)
|
||||
{
|
||||
IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Warning, the NullSerialize function was called, wrong record type?\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief writes a filtering entry in NPE linear format
|
||||
*
|
||||
* @param address memory address to write node to
|
||||
* @param node node to be written
|
||||
*
|
||||
* Used by @ref ixEthDBNPETreeWrite to liniarize a search tree
|
||||
* in NPE-readable format.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PRIVATE
|
||||
void ixEthDBNPELearningNodeWrite(void *address, MacTreeNode *node)
|
||||
{
|
||||
/* copy mac address */
|
||||
memcpy(address, node->descriptor->macAddress, IX_IEEE803_MAC_ADDRESS_SIZE);
|
||||
|
||||
/* copy port ID */
|
||||
NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_PORT_ID_OFFSET) = IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(node->descriptor->portID);
|
||||
|
||||
/* copy flags (valid and not active, as the NPE sets it to active) and clear reserved section (bits 2-7) */
|
||||
NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_FLAGS_OFFSET) = (UINT8) IX_EDB_FLAGS_INACTIVE_VALID;
|
||||
|
||||
IX_ETH_DB_NPE_VERBOSE_TRACE("DB: (NPEAdaptor) writing ELT node 0x%08x:0x%08x\n", * (UINT32 *) address, * (((UINT32 *) (address)) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief writes a WiFi header conversion record in
|
||||
* NPE linear format
|
||||
*
|
||||
* @param address memory address to write node to
|
||||
* @param node node to be written
|
||||
*
|
||||
* Used by @ref ixEthDBNPETreeWrite to liniarize a search tree
|
||||
* in NPE-readable format.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PRIVATE
|
||||
void ixEthDBNPEWiFiNodeWrite(void *address, MacTreeNode *node)
|
||||
{
|
||||
/* copy mac address */
|
||||
memcpy(address, node->descriptor->macAddress, IX_IEEE803_MAC_ADDRESS_SIZE);
|
||||
|
||||
/* copy index */
|
||||
NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_WIFI_INDEX_OFFSET) = node->descriptor->recordData.wifiData.gwAddressIndex;
|
||||
|
||||
/* copy flags (type and valid) */
|
||||
NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_WIFI_FLAGS_OFFSET) = node->descriptor->recordData.wifiData.type << 1 | IX_EDB_FLAGS_VALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief writes a WiFi gateway header conversion record in
|
||||
* NPE linear format
|
||||
*
|
||||
* @param address memory address to write node to
|
||||
* @param node node to be written
|
||||
*
|
||||
* Used by @ref ixEthDBNPETreeWrite to liniarize a search tree
|
||||
* in NPE-readable format.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
void ixEthDBNPEGatewayNodeWrite(void *address, MacTreeNode *node)
|
||||
{
|
||||
/* copy mac address */
|
||||
memcpy(address, node->descriptor->recordData.wifiData.gwMacAddress, IX_IEEE803_MAC_ADDRESS_SIZE);
|
||||
|
||||
/* set reserved field, two bytes */
|
||||
NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_FW_RESERVED_OFFSET) = 0;
|
||||
NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_FW_RESERVED_OFFSET + 1) = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief writes a firewall record in
|
||||
* NPE linear format
|
||||
*
|
||||
* @param address memory address to write node to
|
||||
* @param node node to be written
|
||||
*
|
||||
* Used by @ref ixEthDBNPETreeWrite to liniarize a search tree
|
||||
* in NPE-readable format.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PRIVATE
|
||||
void ixEthDBNPEFirewallNodeWrite(void *address, MacTreeNode *node)
|
||||
{
|
||||
/* set reserved field */
|
||||
NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_FW_RESERVED_OFFSET) = 0;
|
||||
|
||||
/* set flags */
|
||||
NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_FW_FLAGS_OFFSET) = IX_EDB_FLAGS_VALID;
|
||||
|
||||
/* copy mac address */
|
||||
memcpy((void *) ((UINT32) address + IX_EDB_NPE_NODE_FW_ADDR_OFFSET), node->descriptor->macAddress, IX_IEEE803_MAC_ADDRESS_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief registers the NPE serialization methods
|
||||
*
|
||||
* This functions registers NPE serialization methods
|
||||
* for writing the following types of records in NPE
|
||||
* readable linear format:
|
||||
* - filtering records
|
||||
* - WiFi header conversion records
|
||||
* - WiFi gateway header conversion records
|
||||
* - firewall records
|
||||
*
|
||||
* Note that this function should be called by the
|
||||
* component initialization function.
|
||||
*
|
||||
* @return number of registered record types
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
UINT32 ixEthDBRecordSerializeMethodsRegister()
|
||||
{
|
||||
int i;
|
||||
|
||||
/* safety - register a blank method for everybody first */
|
||||
for ( i = 0 ; i < IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1 ; i++)
|
||||
{
|
||||
ixEthDBNPENodeWrite[i] = ixEthDBNullSerialize;
|
||||
}
|
||||
|
||||
/* register real methods */
|
||||
ixEthDBNPENodeWrite[IX_ETH_DB_FILTERING_RECORD] = ixEthDBNPELearningNodeWrite;
|
||||
ixEthDBNPENodeWrite[IX_ETH_DB_FILTERING_VLAN_RECORD] = ixEthDBNPELearningNodeWrite;
|
||||
ixEthDBNPENodeWrite[IX_ETH_DB_WIFI_RECORD] = ixEthDBNPEWiFiNodeWrite;
|
||||
ixEthDBNPENodeWrite[IX_ETH_DB_FIREWALL_RECORD] = ixEthDBNPEFirewallNodeWrite;
|
||||
ixEthDBNPENodeWrite[IX_ETH_DB_GATEWAY_RECORD] = ixEthDBNPEGatewayNodeWrite;
|
||||
|
||||
/* EP Delta arrays */
|
||||
memset(ixEthDBEPDeltaOffset, 0, sizeof (ixEthDBEPDeltaOffset));
|
||||
memset(ixEthDBEPDelta, 0, sizeof (ixEthDBEPDelta));
|
||||
|
||||
/* filtering records */
|
||||
ixEthDBEPDeltaOffset[IX_ETH_DB_FILTERING_RECORD][0] = 1;
|
||||
ixEthDBEPDelta[IX_ETH_DB_FILTERING_RECORD][0] = 0;
|
||||
|
||||
ixEthDBEPDeltaOffset[IX_ETH_DB_FILTERING_RECORD][1] = 3;
|
||||
ixEthDBEPDelta[IX_ETH_DB_FILTERING_RECORD][1] = 7;
|
||||
|
||||
ixEthDBEPDeltaOffset[IX_ETH_DB_FILTERING_RECORD][2] = 511;
|
||||
ixEthDBEPDelta[IX_ETH_DB_FILTERING_RECORD][2] = 14;
|
||||
|
||||
/* wifi records */
|
||||
ixEthDBEPDeltaOffset[IX_ETH_DB_WIFI_RECORD][0] = 1;
|
||||
ixEthDBEPDelta[IX_ETH_DB_WIFI_RECORD][0] = 0;
|
||||
|
||||
ixEthDBEPDeltaOffset[IX_ETH_DB_WIFI_RECORD][1] = 3;
|
||||
ixEthDBEPDelta[IX_ETH_DB_WIFI_RECORD][1] = 7;
|
||||
|
||||
ixEthDBEPDeltaOffset[IX_ETH_DB_WIFI_RECORD][2] = 511;
|
||||
ixEthDBEPDelta[IX_ETH_DB_WIFI_RECORD][2] = 14;
|
||||
|
||||
/* firewall records */
|
||||
ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][0] = 0;
|
||||
ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][0] = 0;
|
||||
|
||||
ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][1] = 1;
|
||||
ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][1] = 5;
|
||||
|
||||
ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][2] = 3;
|
||||
ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][2] = 13;
|
||||
|
||||
ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][3] = 7;
|
||||
ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][3] = 21;
|
||||
|
||||
ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][4] = 15;
|
||||
ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][4] = 29;
|
||||
|
||||
ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][5] = 31;
|
||||
ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][5] = 37;
|
||||
|
||||
return 5; /* 5 methods registered */
|
||||
}
|
||||
|
||||
#ifndef IX_NDEBUG
|
||||
|
||||
IX_ETH_DB_PUBLIC UINT32 npeMsgHistory[IX_ETH_DB_NPE_MSG_HISTORY_DEPTH][2];
|
||||
IX_ETH_DB_PUBLIC UINT32 npeMsgHistoryLen = 0;
|
||||
|
||||
/**
|
||||
* When compiled in DEBUG mode, this function can be used to display
|
||||
* the history of messages sent to the NPEs (up to 100).
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
void ixEthDBShowNpeMsgHistory()
|
||||
{
|
||||
UINT32 i = 0;
|
||||
UINT32 base, len;
|
||||
|
||||
if (npeMsgHistoryLen <= IX_ETH_DB_NPE_MSG_HISTORY_DEPTH)
|
||||
{
|
||||
base = 0;
|
||||
len = npeMsgHistoryLen;
|
||||
}
|
||||
else
|
||||
{
|
||||
base = npeMsgHistoryLen % IX_ETH_DB_NPE_MSG_HISTORY_DEPTH;
|
||||
len = IX_ETH_DB_NPE_MSG_HISTORY_DEPTH;
|
||||
}
|
||||
|
||||
printf("NPE message history [last %d messages, from least to most recent]:\n", len);
|
||||
|
||||
for (; i < len ; i++)
|
||||
{
|
||||
UINT32 pos = (base + i) % IX_ETH_DB_NPE_MSG_HISTORY_DEPTH;
|
||||
printf("msg[%d]: 0x%08x:0x%08x\n", i, npeMsgHistory[pos][0], npeMsgHistory[pos][1]);
|
||||
}
|
||||
}
|
||||
|
||||
IX_ETH_DB_PUBLIC
|
||||
void ixEthDBELTShow(IxEthDBPortId portID)
|
||||
{
|
||||
IxNpeMhMessage message;
|
||||
IX_STATUS result;
|
||||
|
||||
/* send EDB_GetMACAddressDatabase message */
|
||||
FILL_GETMACADDRESSDATABASE(message,
|
||||
0 /* reserved */,
|
||||
IX_OSAL_MMU_VIRT_TO_PHYS(ixEthDBPortInfo[portID].updateMethod.npeUpdateZone));
|
||||
|
||||
IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
|
||||
|
||||
if (result == IX_SUCCESS)
|
||||
{
|
||||
/* analyze NPE copy */
|
||||
UINT32 eltEntryOffset;
|
||||
UINT32 entryPortID;
|
||||
|
||||
UINT32 eltBaseAddress = (UINT32) ixEthDBPortInfo[portID].updateMethod.npeUpdateZone;
|
||||
UINT32 eltSize = FULL_ELT_BYTE_SIZE;
|
||||
|
||||
/* invalidate cache */
|
||||
IX_OSAL_CACHE_INVALIDATE((void *) eltBaseAddress, eltSize);
|
||||
|
||||
printf("Listing records in main learning tree for port %d\n", portID);
|
||||
|
||||
for (eltEntryOffset = ELT_ROOT_OFFSET ; eltEntryOffset < eltSize ; eltEntryOffset += ELT_ENTRY_SIZE)
|
||||
{
|
||||
/* (eltBaseAddress + eltEntryOffset) points to a valid NPE tree node
|
||||
*
|
||||
* the format of the node is MAC[6 bytes]:PortID[1 byte]:Reserved[6 bits]:Active[1 bit]:Valid[1 bit]
|
||||
* therefore we can just use the pointer for database searches as only the first 6 bytes are checked
|
||||
*/
|
||||
void *eltNodeAddress = (void *) ((UINT32) eltBaseAddress + eltEntryOffset);
|
||||
|
||||
if (IX_EDB_NPE_NODE_VALID(eltNodeAddress))
|
||||
{
|
||||
HashNode *node;
|
||||
|
||||
entryPortID = IX_ETH_DB_NPE_LOGICAL_ID_TO_PORT_ID(IX_EDB_NPE_NODE_PORT_ID(eltNodeAddress));
|
||||
|
||||
/* search record */
|
||||
node = ixEthDBSearch((IxEthDBMacAddr *) eltNodeAddress, IX_ETH_DB_ALL_RECORD_TYPES);
|
||||
|
||||
printf("%s - port %d - %s ", mac2string((unsigned char *) eltNodeAddress), entryPortID,
|
||||
IX_EDB_NPE_NODE_ACTIVE(eltNodeAddress) ? "active" : "inactive");
|
||||
|
||||
/* safety check, maybe user deleted record right before sync? */
|
||||
if (node != NULL)
|
||||
{
|
||||
/* found record */
|
||||
MacDescriptor *descriptor = (MacDescriptor *) node->data;
|
||||
|
||||
printf("- %s ",
|
||||
descriptor->type == IX_ETH_DB_FILTERING_RECORD ? "filtering" :
|
||||
descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD ? "vlan" :
|
||||
descriptor->type == IX_ETH_DB_WIFI_RECORD ? "wifi" : "other (check main DB)");
|
||||
|
||||
if (descriptor->type == IX_ETH_DB_FILTERING_RECORD) printf("- age %d - %s ",
|
||||
descriptor->recordData.filteringData.age,
|
||||
descriptor->recordData.filteringData.staticEntry ? "static" : "dynamic");
|
||||
|
||||
if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD) printf("- age %d - %s - tci %d ",
|
||||
descriptor->recordData.filteringVlanData.age,
|
||||
descriptor->recordData.filteringVlanData.staticEntry ? "static" : "dynamic",
|
||||
descriptor->recordData.filteringVlanData.ieee802_1qTag);
|
||||
|
||||
/* end transaction */
|
||||
ixEthDBReleaseHashNode(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("- not synced");
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ixOsalLog(IX_OSAL_LOG_LVL_FATAL, IX_OSAL_LOG_DEV_STDOUT,
|
||||
"EthDB: (ShowELT) Could not complete action (communication failure)\n",
|
||||
portID, 0, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,716 +0,0 @@
|
|||
/**
|
||||
* @file IxEthDBDBPortUpdate.c
|
||||
*
|
||||
* @brief Implementation of dependency and port update handling
|
||||
*
|
||||
* @par
|
||||
* IXP400 SW Release version 2.0
|
||||
*
|
||||
* -- Copyright Notice --
|
||||
*
|
||||
* @par
|
||||
* Copyright 2001-2005, Intel Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
* @par
|
||||
* -- End of Copyright Notice --
|
||||
*/
|
||||
|
||||
#include "IxEthDB_p.h"
|
||||
|
||||
/* forward prototype declarations */
|
||||
IX_ETH_DB_PRIVATE MacTreeNode* ixEthDBTreeInsert(MacTreeNode *searchTree, MacDescriptor *descriptor);
|
||||
IX_ETH_DB_PRIVATE void ixEthDBCreateTrees(IxEthDBPortMap updatePorts);
|
||||
IX_ETH_DB_PRIVATE MacTreeNode* ixEthDBTreeRebalance(MacTreeNode *searchTree);
|
||||
IX_ETH_DB_PRIVATE void ixEthDBRebalanceTreeToVine(MacTreeNode *root, UINT32 *size);
|
||||
IX_ETH_DB_PRIVATE void ixEthDBRebalanceVineToTree(MacTreeNode *root, UINT32 size);
|
||||
IX_ETH_DB_PRIVATE void ixEthDBRebalanceCompression(MacTreeNode *root, UINT32 count);
|
||||
IX_ETH_DB_PRIVATE UINT32 ixEthDBRebalanceLog2Floor(UINT32 x);
|
||||
|
||||
extern HashTable dbHashtable;
|
||||
|
||||
/**
|
||||
* @brief register types requiring automatic updates
|
||||
*
|
||||
* @param typeArray array indexed on record types, each
|
||||
* element indicating whether the record type requires an
|
||||
* automatic update (true) or not (false)
|
||||
*
|
||||
* Automatic updates are done for registered record types
|
||||
* upon adding, updating (that is, updating the record portID)
|
||||
* and removing records. Whenever an automatic update is triggered
|
||||
* the appropriate ports will be provided with new database
|
||||
* information.
|
||||
*
|
||||
* It is assumed that the typeArray parameter is allocated large
|
||||
* enough to hold all the user defined types. Also, the type
|
||||
* array should be initialized to false as this function only
|
||||
* caters for types which do require automatic updates.
|
||||
*
|
||||
* Note that this function should be called by the component
|
||||
* initialization function.
|
||||
*
|
||||
* @return number of record types registered for automatic
|
||||
* updates
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
UINT32 ixEthDBUpdateTypeRegister(BOOL *typeArray)
|
||||
{
|
||||
typeArray[IX_ETH_DB_FILTERING_RECORD] = true;
|
||||
typeArray[IX_ETH_DB_FILTERING_VLAN_RECORD] = true;
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief computes dependencies and triggers port learning tree updates
|
||||
*
|
||||
* @param triggerPorts port map consisting in the ports which triggered the update
|
||||
*
|
||||
* This function browses through all the ports and determines how to waterfall the update
|
||||
* event from the trigger ports to all other ports depending on them.
|
||||
*
|
||||
* Once the list of ports to be updated is determined this function
|
||||
* calls @ref ixEthDBCreateTrees.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
void ixEthDBUpdatePortLearningTrees(IxEthDBPortMap triggerPorts)
|
||||
{
|
||||
IxEthDBPortMap updatePorts;
|
||||
UINT32 portIndex;
|
||||
|
||||
ixEthDBUpdateLock();
|
||||
|
||||
SET_EMPTY_DEPENDENCY_MAP(updatePorts);
|
||||
|
||||
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
|
||||
{
|
||||
PortInfo *port = &ixEthDBPortInfo[portIndex];
|
||||
BOOL mapsCollide;
|
||||
|
||||
MAPS_COLLIDE(mapsCollide, triggerPorts, port->dependencyPortMap);
|
||||
|
||||
if (mapsCollide /* do triggers influence this port? */
|
||||
&& !IS_PORT_INCLUDED(portIndex, updatePorts) /* and it's not already in the update list */
|
||||
&& port->updateMethod.updateEnabled) /* and we're allowed to update it */
|
||||
{
|
||||
IX_ETH_DB_UPDATE_TRACE("DB: (Update) Adding port %d to update set\n", portIndex);
|
||||
|
||||
JOIN_PORT_TO_MAP(updatePorts, portIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
IX_ETH_DB_UPDATE_TRACE("DB: (Update) Didn't add port %d to update set, reasons follow:\n", portIndex);
|
||||
|
||||
if (!mapsCollide)
|
||||
{
|
||||
IX_ETH_DB_UPDATE_TRACE("\tMaps don't collide on port %d\n", portIndex);
|
||||
}
|
||||
|
||||
if (IS_PORT_INCLUDED(portIndex, updatePorts))
|
||||
{
|
||||
IX_ETH_DB_UPDATE_TRACE("\tPort %d is already in the update set\n", portIndex);
|
||||
}
|
||||
|
||||
if (!port->updateMethod.updateEnabled)
|
||||
{
|
||||
IX_ETH_DB_UPDATE_TRACE("\tPort %d doesn't have updateEnabled set\n", portIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IX_ETH_DB_UPDATE_TRACE("DB: (Update) Updating port set\n");
|
||||
|
||||
ixEthDBCreateTrees(updatePorts);
|
||||
|
||||
ixEthDBUpdateUnlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief creates learning trees and calls the port update handlers
|
||||
*
|
||||
* @param updatePorts set of ports in need of learning trees
|
||||
*
|
||||
* This function determines the optimal method of creating learning
|
||||
* trees using a minimal number of database queries, keeping in mind
|
||||
* that different ports can either use the same learning trees or they
|
||||
* can partially share them. The actual tree building routine is
|
||||
* @ref ixEthDBQuery.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PRIVATE
|
||||
void ixEthDBCreateTrees(IxEthDBPortMap updatePorts)
|
||||
{
|
||||
UINT32 portIndex;
|
||||
BOOL result;
|
||||
BOOL portsLeft = true;
|
||||
|
||||
while (portsLeft)
|
||||
{
|
||||
/* get port with minimal dependency map and NULL search tree */
|
||||
UINT32 minPortIndex = MAX_PORT_SIZE;
|
||||
UINT32 minimalSize = MAX_PORT_SIZE;
|
||||
|
||||
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
|
||||
{
|
||||
UINT32 size;
|
||||
PortInfo *port = &ixEthDBPortInfo[portIndex];
|
||||
|
||||
/* generate trees only for ports that need them */
|
||||
if (!port->updateMethod.searchTreePendingWrite && IS_PORT_INCLUDED(portIndex, updatePorts))
|
||||
{
|
||||
GET_MAP_SIZE(port->dependencyPortMap, size);
|
||||
|
||||
IX_ETH_DB_UPDATE_TRACE("DB: (Update) Dependency map for port %d: size %d\n",
|
||||
portIndex, size);
|
||||
|
||||
if (size < minimalSize)
|
||||
{
|
||||
minPortIndex = portIndex;
|
||||
minimalSize = size;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IX_ETH_DB_UPDATE_TRACE("DB: (Update) Skipped port %d from tree diff (%s)\n", portIndex,
|
||||
port->updateMethod.searchTreePendingWrite ? "pending write access" : "ignored by query");
|
||||
}
|
||||
}
|
||||
|
||||
/* if a port was found than minimalSize is not MAX_PORT_SIZE */
|
||||
if (minimalSize != MAX_PORT_SIZE)
|
||||
{
|
||||
/* minPortIndex is the port we seek */
|
||||
PortInfo *port = &ixEthDBPortInfo[minPortIndex];
|
||||
|
||||
IxEthDBPortMap query;
|
||||
MacTreeNode *baseTree;
|
||||
|
||||
/* now try to find a port with minimal map difference */
|
||||
PortInfo *minimalDiffPort = NULL;
|
||||
UINT32 minimalDiff = MAX_PORT_SIZE;
|
||||
|
||||
IX_ETH_DB_UPDATE_TRACE("DB: (Update) Minimal size port is %d\n", minPortIndex);
|
||||
|
||||
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
|
||||
{
|
||||
PortInfo *diffPort = &ixEthDBPortInfo[portIndex];
|
||||
BOOL mapIsSubset;
|
||||
|
||||
IS_MAP_SUBSET(mapIsSubset, diffPort->dependencyPortMap, port->dependencyPortMap);
|
||||
|
||||
|
||||
if (portIndex != minPortIndex
|
||||
&& diffPort->updateMethod.searchTree != NULL
|
||||
&& mapIsSubset)
|
||||
{
|
||||
/* compute size and pick only minimal size difference */
|
||||
UINT32 diffPortSize;
|
||||
UINT32 sizeDifference;
|
||||
|
||||
GET_MAP_SIZE(diffPort->dependencyPortMap, diffPortSize);
|
||||
|
||||
IX_ETH_DB_UPDATE_TRACE("DB: (Update) Checking port %d for differences...\n", portIndex);
|
||||
|
||||
sizeDifference = minimalSize - diffPortSize;
|
||||
|
||||
if (sizeDifference < minimalDiff)
|
||||
{
|
||||
minimalDiffPort = diffPort;
|
||||
minimalDiff = sizeDifference;
|
||||
|
||||
IX_ETH_DB_UPDATE_TRACE("DB: (Update) Minimal difference 0x%x was found on port %d\n",
|
||||
minimalDiff, portIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* check if filtering is enabled on this port */
|
||||
if ((port->featureStatus & IX_ETH_DB_FILTERING) != 0)
|
||||
{
|
||||
/* if minimalDiff is not MAX_PORT_SIZE minimalDiffPort points to the most similar port */
|
||||
if (minimalDiff != MAX_PORT_SIZE)
|
||||
{
|
||||
baseTree = ixEthDBCloneMacTreeNode(minimalDiffPort->updateMethod.searchTree);
|
||||
DIFF_MAPS(query, port->dependencyPortMap , minimalDiffPort->dependencyPortMap);
|
||||
|
||||
IX_ETH_DB_UPDATE_TRACE("DB: (Update) Found minimal diff, extending tree %d on query\n",
|
||||
minimalDiffPort->portID);
|
||||
}
|
||||
else /* .. otherwise no similar port was found, build tree from scratch */
|
||||
{
|
||||
baseTree = NULL;
|
||||
|
||||
COPY_DEPENDENCY_MAP(query, port->dependencyPortMap);
|
||||
|
||||
IX_ETH_DB_UPDATE_TRACE("DB: (Update) No similar diff, creating tree from query\n");
|
||||
}
|
||||
|
||||
IS_EMPTY_DEPENDENCY_MAP(result, query);
|
||||
|
||||
if (!result) /* otherwise we don't need anything more on top of the cloned tree */
|
||||
{
|
||||
IX_ETH_DB_UPDATE_TRACE("DB: (Update) Adding query tree to port %d\n", minPortIndex);
|
||||
|
||||
/* build learning tree */
|
||||
port->updateMethod.searchTree = ixEthDBQuery(baseTree, query, IX_ETH_DB_ALL_FILTERING_RECORDS, MAX_ELT_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
IX_ETH_DB_UPDATE_TRACE("DB: (Update) Query is empty, assuming identical nearest tree\n");
|
||||
|
||||
port->updateMethod.searchTree = baseTree;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* filtering is not enabled, will download an empty tree */
|
||||
if (port->updateMethod.searchTree != NULL)
|
||||
{
|
||||
ixEthDBFreeMacTreeNode(port->updateMethod.searchTree);
|
||||
}
|
||||
|
||||
port->updateMethod.searchTree = NULL;
|
||||
}
|
||||
|
||||
/* mark tree as valid */
|
||||
port->updateMethod.searchTreePendingWrite = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
portsLeft = false;
|
||||
|
||||
IX_ETH_DB_UPDATE_TRACE("DB: (Update) No trees to create this round\n");
|
||||
}
|
||||
}
|
||||
|
||||
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
|
||||
{
|
||||
PortInfo *updatePort = &ixEthDBPortInfo[portIndex];
|
||||
|
||||
if (updatePort->updateMethod.searchTreePendingWrite)
|
||||
{
|
||||
IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) Starting procedure to upload new search tree (%snull) into NPE %d\n",
|
||||
updatePort->updateMethod.searchTree != NULL ? "not " : "",
|
||||
portIndex);
|
||||
|
||||
updatePort->updateMethod.updateHandler(portIndex, IX_ETH_DB_FILTERING_RECORD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief standard NPE update handler
|
||||
*
|
||||
* @param portID id of the port to be updated
|
||||
* @param type record type to be pushed during this update
|
||||
*
|
||||
* The NPE update handler manages updating the NPE databases
|
||||
* given a certain record type.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBNPEUpdateHandler(IxEthDBPortId portID, IxEthDBRecordType type)
|
||||
{
|
||||
UINT32 epDelta, blockCount;
|
||||
IxNpeMhMessage message;
|
||||
UINT32 treeSize = 0;
|
||||
PortInfo *port = &ixEthDBPortInfo[portID];
|
||||
|
||||
/* size selection and type check */
|
||||
if (type == IX_ETH_DB_FILTERING_RECORD || type == IX_ETH_DB_WIFI_RECORD)
|
||||
{
|
||||
treeSize = FULL_ELT_BYTE_SIZE;
|
||||
}
|
||||
else if (type == IX_ETH_DB_FIREWALL_RECORD)
|
||||
{
|
||||
treeSize = FULL_FW_BYTE_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return IX_ETH_DB_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* serialize tree into memory */
|
||||
ixEthDBNPETreeWrite(type, treeSize, port->updateMethod.npeUpdateZone, port->updateMethod.searchTree, &epDelta, &blockCount);
|
||||
|
||||
/* free internal copy */
|
||||
if (port->updateMethod.searchTree != NULL)
|
||||
{
|
||||
ixEthDBFreeMacTreeNode(port->updateMethod.searchTree);
|
||||
}
|
||||
|
||||
/* forget last used search tree */
|
||||
port->updateMethod.searchTree = NULL;
|
||||
port->updateMethod.searchTreePendingWrite = false;
|
||||
|
||||
/* dependending on the update type we do different things */
|
||||
if (type == IX_ETH_DB_FILTERING_RECORD || type == IX_ETH_DB_WIFI_RECORD)
|
||||
{
|
||||
IX_STATUS result;
|
||||
|
||||
FILL_SETMACADDRESSDATABASE_MSG(message, IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID),
|
||||
epDelta, blockCount,
|
||||
IX_OSAL_MMU_VIRT_TO_PHYS(port->updateMethod.npeUpdateZone));
|
||||
|
||||
IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
|
||||
|
||||
if (result == IX_SUCCESS)
|
||||
{
|
||||
IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) Finished downloading NPE tree on port %d\n", portID);
|
||||
}
|
||||
else
|
||||
{
|
||||
ixEthDBPortInfo[portID].agingEnabled = false;
|
||||
ixEthDBPortInfo[portID].updateMethod.updateEnabled = false;
|
||||
ixEthDBPortInfo[portID].updateMethod.userControlled = true;
|
||||
|
||||
ERROR_LOG("EthDB: (PortUpdate) disabling aging and updates on port %d (assumed dead)\n", portID);
|
||||
|
||||
ixEthDBDatabaseClear(portID, IX_ETH_DB_ALL_RECORD_TYPES);
|
||||
|
||||
return IX_ETH_DB_FAIL;
|
||||
}
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
else if (type == IX_ETH_DB_FIREWALL_RECORD)
|
||||
{
|
||||
return ixEthDBFirewallUpdate(portID, port->updateMethod.npeUpdateZone, epDelta);
|
||||
}
|
||||
|
||||
return IX_ETH_DB_INVALID_ARG;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief queries the database for a set of records to be inserted into a given tree
|
||||
*
|
||||
* @param searchTree pointer to a tree where insertions will be performed; can be NULL
|
||||
* @param query set of ports that a database record must match to be inserted into the tree
|
||||
*
|
||||
* The query method browses through the database, extracts all the descriptors matching
|
||||
* the given query parameter and inserts them into the given learning tree.
|
||||
* Note that this is an append procedure, the given tree needs not to be empty.
|
||||
* A "descriptor matching the query" is a descriptor whose port id is in the query map.
|
||||
* If the given tree is empty (NULL) a new tree is created and returned.
|
||||
*
|
||||
* @return the tree root
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
MacTreeNode* ixEthDBQuery(MacTreeNode *searchTree, IxEthDBPortMap query, IxEthDBRecordType recordFilter, UINT32 maxEntries)
|
||||
{
|
||||
HashIterator iterator;
|
||||
UINT32 entryCount = 0;
|
||||
|
||||
/* browse database */
|
||||
BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
|
||||
|
||||
while (IS_ITERATOR_VALID(&iterator))
|
||||
{
|
||||
MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
|
||||
|
||||
IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) querying [%s]:%d on port map ... ",
|
||||
mac2string(descriptor->macAddress),
|
||||
descriptor->portID);
|
||||
|
||||
if ((descriptor->type & recordFilter) != 0
|
||||
&& IS_PORT_INCLUDED(descriptor->portID, query))
|
||||
{
|
||||
MacDescriptor *descriptorClone = ixEthDBCloneMacDescriptor(descriptor);
|
||||
|
||||
IX_ETH_DB_UPDATE_TRACE("match\n");
|
||||
|
||||
if (descriptorClone != NULL)
|
||||
{
|
||||
/* add descriptor to tree */
|
||||
searchTree = ixEthDBTreeInsert(searchTree, descriptorClone);
|
||||
|
||||
entryCount++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IX_ETH_DB_UPDATE_TRACE("no match\n");
|
||||
}
|
||||
|
||||
if (entryCount < maxEntries)
|
||||
{
|
||||
/* advance to the next record */
|
||||
BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* the NPE won't accept more entries so we can stop now */
|
||||
ixEthDBReleaseHashIterator(&iterator);
|
||||
|
||||
IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) number of elements reached maximum supported by port\n");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) query inserted %d records in the search tree\n", entryCount);
|
||||
|
||||
return ixEthDBTreeRebalance(searchTree);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief inserts a mac descriptor into an tree
|
||||
*
|
||||
* @param searchTree tree where the insertion is to be performed (may be NULL)
|
||||
* @param descriptor descriptor to insert into tree
|
||||
*
|
||||
* @return the tree root
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PRIVATE
|
||||
MacTreeNode* ixEthDBTreeInsert(MacTreeNode *searchTree, MacDescriptor *descriptor)
|
||||
{
|
||||
MacTreeNode *currentNode = searchTree;
|
||||
MacTreeNode *insertLocation = NULL;
|
||||
MacTreeNode *newNode;
|
||||
INT32 insertPosition = RIGHT;
|
||||
|
||||
if (descriptor == NULL)
|
||||
{
|
||||
return searchTree;
|
||||
}
|
||||
|
||||
/* create a new node */
|
||||
newNode = ixEthDBAllocMacTreeNode();
|
||||
|
||||
if (newNode == NULL)
|
||||
{
|
||||
/* out of memory */
|
||||
ERROR_LOG("Warning: ixEthDBAllocMacTreeNode returned NULL in file %s:%d (out of memory?)\n", __FILE__, __LINE__);
|
||||
|
||||
ixEthDBFreeMacDescriptor(descriptor);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* populate node */
|
||||
newNode->descriptor = descriptor;
|
||||
|
||||
/* an empty initial tree is a special case */
|
||||
if (searchTree == NULL)
|
||||
{
|
||||
return newNode;
|
||||
}
|
||||
|
||||
/* get insertion location */
|
||||
while (insertLocation == NULL)
|
||||
{
|
||||
MacTreeNode *nextNode;
|
||||
|
||||
/* compare given key with current node key */
|
||||
insertPosition = ixEthDBAddressCompare(descriptor->macAddress, currentNode->descriptor->macAddress);
|
||||
|
||||
/* navigate down */
|
||||
if (insertPosition == RIGHT)
|
||||
{
|
||||
nextNode = currentNode->right;
|
||||
}
|
||||
else if (insertPosition == LEFT)
|
||||
{
|
||||
nextNode = currentNode->left;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* error, duplicate key */
|
||||
ERROR_LOG("Warning: trapped insertion of a duplicate MAC address in an NPE search tree\n");
|
||||
|
||||
/* this will free the MAC descriptor as well */
|
||||
ixEthDBFreeMacTreeNode(newNode);
|
||||
|
||||
return searchTree;
|
||||
}
|
||||
|
||||
/* when we can no longer dive through the tree we found the insertion place */
|
||||
if (nextNode != NULL)
|
||||
{
|
||||
currentNode = nextNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
insertLocation = currentNode;
|
||||
}
|
||||
}
|
||||
|
||||
/* insert node */
|
||||
if (insertPosition == RIGHT)
|
||||
{
|
||||
insertLocation->right = newNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
insertLocation->left = newNode;
|
||||
}
|
||||
|
||||
return searchTree;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief balance a tree
|
||||
*
|
||||
* @param searchTree tree to balance
|
||||
*
|
||||
* Converts a tree into a balanced tree and returns the root of
|
||||
* the balanced tree. The resulting tree is <i>route balanced</i>
|
||||
* not <i>perfectly balanced</i>. This makes no difference to the
|
||||
* average tree search time which is the same in both cases, O(log2(n)).
|
||||
*
|
||||
* @return root of the balanced tree or NULL if there's no memory left
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PRIVATE
|
||||
MacTreeNode* ixEthDBTreeRebalance(MacTreeNode *searchTree)
|
||||
{
|
||||
MacTreeNode *pseudoRoot = ixEthDBAllocMacTreeNode();
|
||||
UINT32 size;
|
||||
|
||||
if (pseudoRoot == NULL)
|
||||
{
|
||||
/* out of memory */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pseudoRoot->right = searchTree;
|
||||
|
||||
ixEthDBRebalanceTreeToVine(pseudoRoot, &size);
|
||||
ixEthDBRebalanceVineToTree(pseudoRoot, size);
|
||||
|
||||
searchTree = pseudoRoot->right;
|
||||
|
||||
/* remove pseudoRoot right branch, otherwise it will free the entire tree */
|
||||
pseudoRoot->right = NULL;
|
||||
|
||||
ixEthDBFreeMacTreeNode(pseudoRoot);
|
||||
|
||||
return searchTree;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief converts a tree into a vine
|
||||
*
|
||||
* @param root root of tree to convert
|
||||
* @param size depth of vine (equal to the number of nodes in the tree)
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PRIVATE
|
||||
void ixEthDBRebalanceTreeToVine(MacTreeNode *root, UINT32 *size)
|
||||
{
|
||||
MacTreeNode *vineTail = root;
|
||||
MacTreeNode *remainder = vineTail->right;
|
||||
MacTreeNode *tempPtr;
|
||||
|
||||
*size = 0;
|
||||
|
||||
while (remainder != NULL)
|
||||
{
|
||||
if (remainder->left == NULL)
|
||||
{
|
||||
/* move tail down one */
|
||||
vineTail = remainder;
|
||||
remainder = remainder->right;
|
||||
(*size)++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* rotate around remainder */
|
||||
tempPtr = remainder->left;
|
||||
remainder->left = tempPtr->right;
|
||||
tempPtr->right = remainder;
|
||||
remainder = tempPtr;
|
||||
vineTail->right = tempPtr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief converts a vine into a balanced tree
|
||||
*
|
||||
* @param root vine to convert
|
||||
* @param size depth of vine
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PRIVATE
|
||||
void ixEthDBRebalanceVineToTree(MacTreeNode *root, UINT32 size)
|
||||
{
|
||||
UINT32 leafCount = size + 1 - (1 << ixEthDBRebalanceLog2Floor(size + 1));
|
||||
|
||||
ixEthDBRebalanceCompression(root, leafCount);
|
||||
|
||||
size = size - leafCount;
|
||||
|
||||
while (size > 1)
|
||||
{
|
||||
ixEthDBRebalanceCompression(root, size / 2);
|
||||
|
||||
size /= 2;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief compresses a vine/tree stage into a more balanced vine/tree
|
||||
*
|
||||
* @param root root of the tree to compress
|
||||
* @param count number of "spine" nodes
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PRIVATE
|
||||
void ixEthDBRebalanceCompression(MacTreeNode *root, UINT32 count)
|
||||
{
|
||||
MacTreeNode *scanner = root;
|
||||
MacTreeNode *child;
|
||||
UINT32 local_index;
|
||||
|
||||
for (local_index = 0 ; local_index < count ; local_index++)
|
||||
{
|
||||
child = scanner->right;
|
||||
scanner->right = child->right;
|
||||
scanner = scanner->right;
|
||||
child->right = scanner->left;
|
||||
scanner->left = child;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief computes |_log2(x)_| (a.k.a. floor(log2(x)))
|
||||
*
|
||||
* @param x number to compute |_log2(x)_| for
|
||||
*
|
||||
* @return |_log2(x)_|
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PRIVATE
|
||||
UINT32 ixEthDBRebalanceLog2Floor(UINT32 x)
|
||||
{
|
||||
UINT32 log = 0;
|
||||
UINT32 val = 1;
|
||||
|
||||
while (val < x)
|
||||
{
|
||||
log++;
|
||||
val <<= 1;
|
||||
}
|
||||
|
||||
return val == x ? log : log - 1;
|
||||
}
|
||||
|
|
@ -1,628 +0,0 @@
|
|||
/**
|
||||
* @file IxEthDBAPI.c
|
||||
*
|
||||
* @brief Implementation of the public API
|
||||
*
|
||||
* @par
|
||||
* IXP400 SW Release version 2.0
|
||||
*
|
||||
* -- Copyright Notice --
|
||||
*
|
||||
* @par
|
||||
* Copyright 2001-2005, Intel Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
* @par
|
||||
* -- End of Copyright Notice --
|
||||
*/
|
||||
|
||||
#include "IxEthDB_p.h"
|
||||
|
||||
extern HashTable dbHashtable;
|
||||
IX_ETH_DB_PRIVATE void ixEthDBPortInfoShow(IxEthDBPortId portID, IxEthDBRecordType recordFilter);
|
||||
IX_ETH_DB_PRIVATE IxEthDBStatus ixEthDBHeaderShow(IxEthDBRecordType recordFilter);
|
||||
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBDependencyPortMapShow(IxEthDBPortId portID, IxEthDBPortMap map);
|
||||
|
||||
/**
|
||||
* @brief displays a port dependency map
|
||||
*
|
||||
* @param portID ID of the port
|
||||
* @param map port map to display
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the operation completed
|
||||
* successfully
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBDependencyPortMapShow(IxEthDBPortId portID, IxEthDBPortMap map)
|
||||
{
|
||||
UINT32 portIndex;
|
||||
BOOL mapSelf = true, mapNone = true, firstPort = true;
|
||||
|
||||
/* dependency port maps */
|
||||
printf("Dependency port map: ");
|
||||
|
||||
/* browse the port map */
|
||||
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
|
||||
{
|
||||
if (IS_PORT_INCLUDED(portIndex, map))
|
||||
{
|
||||
mapNone = false;
|
||||
|
||||
if (portIndex != portID)
|
||||
{
|
||||
mapSelf = false;
|
||||
}
|
||||
|
||||
printf("%s%d", firstPort ? "{" : ", ", portIndex);
|
||||
|
||||
firstPort = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (mapNone)
|
||||
{
|
||||
mapSelf = false;
|
||||
}
|
||||
|
||||
printf("%s (%s)\n", firstPort ? "" : "}", mapSelf ? "self" : mapNone ? "none" : "group");
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief displays all the filtering records belonging to a port
|
||||
*
|
||||
* @param portID ID of the port to display
|
||||
*
|
||||
* Note that this function is documented in the main component
|
||||
* header file, IxEthDB.h.
|
||||
*
|
||||
* @warning deprecated, use @ref ixEthDBFilteringDatabaseShowRecords()
|
||||
* instead. Calling this function is equivalent to calling
|
||||
* ixEthDBFilteringDatabaseShowRecords(portID, IX_ETH_DB_FILTERING_RECORD)
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBFilteringDatabaseShow(IxEthDBPortId portID)
|
||||
{
|
||||
IxEthDBStatus local_result;
|
||||
HashIterator iterator;
|
||||
PortInfo *portInfo;
|
||||
UINT32 recordCount = 0;
|
||||
|
||||
IX_ETH_DB_CHECK_PORT(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
|
||||
|
||||
portInfo = &ixEthDBPortInfo[portID];
|
||||
|
||||
/* display table header */
|
||||
printf("Ethernet database records for port ID [%d]\n", portID);
|
||||
|
||||
ixEthDBDependencyPortMapShow(portID, portInfo->dependencyPortMap);
|
||||
|
||||
if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
|
||||
{
|
||||
printf("NPE updates are %s\n\n", portInfo->updateMethod.updateEnabled ? "enabled" : "disabled");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("updates disabled (not an NPE)\n\n");
|
||||
}
|
||||
|
||||
printf(" MAC address | Age | Type \n");
|
||||
printf("___________________________________\n");
|
||||
|
||||
/* browse database */
|
||||
BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
|
||||
|
||||
while (IS_ITERATOR_VALID(&iterator))
|
||||
{
|
||||
MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
|
||||
|
||||
if (descriptor->portID == portID && descriptor->type == IX_ETH_DB_FILTERING_RECORD)
|
||||
{
|
||||
recordCount++;
|
||||
|
||||
/* display entry */
|
||||
printf(" %02X:%02X:%02X:%02X:%02X:%02X | %5d | %s\n",
|
||||
descriptor->macAddress[0],
|
||||
descriptor->macAddress[1],
|
||||
descriptor->macAddress[2],
|
||||
descriptor->macAddress[3],
|
||||
descriptor->macAddress[4],
|
||||
descriptor->macAddress[5],
|
||||
descriptor->recordData.filteringData.age,
|
||||
descriptor->recordData.filteringData.staticEntry ? "static" : "dynamic");
|
||||
}
|
||||
|
||||
/* move to the next record */
|
||||
BUSY_RETRY_WITH_RESULT(ixEthDBIncrementHashIterator(&dbHashtable, &iterator), local_result);
|
||||
|
||||
/* debug */
|
||||
if (local_result == IX_ETH_DB_BUSY)
|
||||
{
|
||||
return IX_ETH_DB_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
/* display number of records */
|
||||
printf("\nFound %d records\n", recordCount);
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief displays all the filtering records belonging to all the ports
|
||||
*
|
||||
* Note that this function is documented in the main component
|
||||
* header file, IxEthDB.h.
|
||||
*
|
||||
* @warning deprecated, use @ref ixEthDBFilteringDatabaseShowRecords()
|
||||
* instead. Calling this function is equivalent to calling
|
||||
* ixEthDBFilteringDatabaseShowRecords(IX_ETH_DB_ALL_PORTS, IX_ETH_DB_FILTERING_RECORD)
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
void ixEthDBFilteringDatabaseShowAll()
|
||||
{
|
||||
IxEthDBPortId portIndex;
|
||||
|
||||
printf("\nEthernet learning/filtering database: listing %d ports\n\n", (UINT32) IX_ETH_DB_NUMBER_OF_PORTS);
|
||||
|
||||
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
|
||||
{
|
||||
ixEthDBFilteringDatabaseShow(portIndex);
|
||||
|
||||
if (portIndex < IX_ETH_DB_NUMBER_OF_PORTS - 1)
|
||||
{
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief displays one record in a format depending on the record filter
|
||||
*
|
||||
* @param descriptor pointer to the record
|
||||
* @param recordFilter format filter
|
||||
*
|
||||
* This function will display the fields in a record depending on the
|
||||
* selected record filter.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PRIVATE
|
||||
void ixEthDBRecordShow(MacDescriptor *descriptor, IxEthDBRecordType recordFilter)
|
||||
{
|
||||
if (recordFilter == IX_ETH_DB_FILTERING_VLAN_RECORD
|
||||
|| recordFilter == (IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD))
|
||||
{
|
||||
/* display VLAN record header - leave this commented code in place, its purpose is to align the print format with the header
|
||||
printf(" MAC address | Age | Type | VLAN ID | CFI | QoS class \n");
|
||||
printf("___________________________________________________________________\n"); */
|
||||
|
||||
if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD)
|
||||
{
|
||||
printf("%02X:%02X:%02X:%02X:%02X:%02X | %3d | %s | %d | %d | %d\n",
|
||||
descriptor->macAddress[0],
|
||||
descriptor->macAddress[1],
|
||||
descriptor->macAddress[2],
|
||||
descriptor->macAddress[3],
|
||||
descriptor->macAddress[4],
|
||||
descriptor->macAddress[5],
|
||||
descriptor->recordData.filteringVlanData.age,
|
||||
descriptor->recordData.filteringVlanData.staticEntry ? "static" : "dynamic",
|
||||
IX_ETH_DB_GET_VLAN_ID(descriptor->recordData.filteringVlanData.ieee802_1qTag),
|
||||
(descriptor->recordData.filteringVlanData.ieee802_1qTag & 0x1000) >> 12,
|
||||
IX_ETH_DB_GET_QOS_PRIORITY(descriptor->recordData.filteringVlanData.ieee802_1qTag));
|
||||
}
|
||||
else if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
|
||||
{
|
||||
printf("%02X:%02X:%02X:%02X:%02X:%02X | %3d | %s | - | - | -\n",
|
||||
descriptor->macAddress[0],
|
||||
descriptor->macAddress[1],
|
||||
descriptor->macAddress[2],
|
||||
descriptor->macAddress[3],
|
||||
descriptor->macAddress[4],
|
||||
descriptor->macAddress[5],
|
||||
descriptor->recordData.filteringData.age,
|
||||
descriptor->recordData.filteringData.staticEntry ? "static" : "dynamic");
|
||||
}
|
||||
}
|
||||
else if (recordFilter == IX_ETH_DB_FILTERING_RECORD)
|
||||
{
|
||||
/* display filtering record header - leave this commented code in place, its purpose is to align the print format with the header
|
||||
printf(" MAC address | Age | Type \n");
|
||||
printf("_______________________________________\n"); */
|
||||
|
||||
if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
|
||||
{
|
||||
printf("%02X:%02X:%02X:%02X:%02X:%02X | %3d | %s \n",
|
||||
descriptor->macAddress[0],
|
||||
descriptor->macAddress[1],
|
||||
descriptor->macAddress[2],
|
||||
descriptor->macAddress[3],
|
||||
descriptor->macAddress[4],
|
||||
descriptor->macAddress[5],
|
||||
descriptor->recordData.filteringData.age,
|
||||
descriptor->recordData.filteringData.staticEntry ? "static" : "dynamic");
|
||||
}
|
||||
}
|
||||
else if (recordFilter == IX_ETH_DB_WIFI_RECORD)
|
||||
{
|
||||
/* display WiFi record header - leave this commented code in place, its purpose is to align the print format with the header
|
||||
printf(" MAC address | GW MAC address \n");
|
||||
printf("_______________________________________\n"); */
|
||||
|
||||
if (descriptor->type == IX_ETH_DB_WIFI_RECORD)
|
||||
{
|
||||
if (descriptor->recordData.wifiData.type == IX_ETH_DB_WIFI_AP_TO_AP)
|
||||
{
|
||||
/* gateway address present */
|
||||
printf("%02X:%02X:%02X:%02X:%02X:%02X | %02X:%02X:%02X:%02X:%02X:%02X \n",
|
||||
descriptor->macAddress[0],
|
||||
descriptor->macAddress[1],
|
||||
descriptor->macAddress[2],
|
||||
descriptor->macAddress[3],
|
||||
descriptor->macAddress[4],
|
||||
descriptor->macAddress[5],
|
||||
descriptor->recordData.wifiData.gwMacAddress[0],
|
||||
descriptor->recordData.wifiData.gwMacAddress[1],
|
||||
descriptor->recordData.wifiData.gwMacAddress[2],
|
||||
descriptor->recordData.wifiData.gwMacAddress[3],
|
||||
descriptor->recordData.wifiData.gwMacAddress[4],
|
||||
descriptor->recordData.wifiData.gwMacAddress[5]);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no gateway */
|
||||
printf("%02X:%02X:%02X:%02X:%02X:%02X | ----no gateway----- \n",
|
||||
descriptor->macAddress[0],
|
||||
descriptor->macAddress[1],
|
||||
descriptor->macAddress[2],
|
||||
descriptor->macAddress[3],
|
||||
descriptor->macAddress[4],
|
||||
descriptor->macAddress[5]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (recordFilter == IX_ETH_DB_FIREWALL_RECORD)
|
||||
{
|
||||
/* display Firewall record header - leave this commented code in place, its purpose is to align the print format with the header
|
||||
printf(" MAC address \n");
|
||||
printf("__________________\n"); */
|
||||
|
||||
if (descriptor->type == IX_ETH_DB_FIREWALL_RECORD)
|
||||
{
|
||||
printf("%02X:%02X:%02X:%02X:%02X:%02X \n",
|
||||
descriptor->macAddress[0],
|
||||
descriptor->macAddress[1],
|
||||
descriptor->macAddress[2],
|
||||
descriptor->macAddress[3],
|
||||
descriptor->macAddress[4],
|
||||
descriptor->macAddress[5]);
|
||||
}
|
||||
}
|
||||
else if (recordFilter == IX_ETH_DB_ALL_RECORD_TYPES)
|
||||
{
|
||||
/* display composite record header - leave this commented code in place, its purpose is to align the print format with the header
|
||||
printf(" MAC address | Record | Age| Type | VLAN |CFI| QoS | GW MAC address \n");
|
||||
printf("_______________________________________________________________________________\n"); */
|
||||
|
||||
if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD)
|
||||
{
|
||||
printf("%02X:%02X:%02X:%02X:%02X:%02X | VLAN | %2d | %s | %4d | %1d | %1d | -----------------\n",
|
||||
descriptor->macAddress[0],
|
||||
descriptor->macAddress[1],
|
||||
descriptor->macAddress[2],
|
||||
descriptor->macAddress[3],
|
||||
descriptor->macAddress[4],
|
||||
descriptor->macAddress[5],
|
||||
descriptor->recordData.filteringVlanData.age,
|
||||
descriptor->recordData.filteringVlanData.staticEntry ? "static " : "dynamic",
|
||||
IX_ETH_DB_GET_VLAN_ID(descriptor->recordData.filteringVlanData.ieee802_1qTag),
|
||||
(descriptor->recordData.filteringVlanData.ieee802_1qTag & 0x1000) >> 12,
|
||||
IX_ETH_DB_GET_QOS_PRIORITY(descriptor->recordData.filteringVlanData.ieee802_1qTag));
|
||||
}
|
||||
else if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
|
||||
{
|
||||
printf("%02X:%02X:%02X:%02X:%02X:%02X | Filter | %2d | %s | ---- | - | --- | -----------------\n",
|
||||
descriptor->macAddress[0],
|
||||
descriptor->macAddress[1],
|
||||
descriptor->macAddress[2],
|
||||
descriptor->macAddress[3],
|
||||
descriptor->macAddress[4],
|
||||
descriptor->macAddress[5],
|
||||
descriptor->recordData.filteringData.age,
|
||||
descriptor->recordData.filteringData.staticEntry ? "static " : "dynamic");
|
||||
}
|
||||
else if (descriptor->type == IX_ETH_DB_WIFI_RECORD)
|
||||
{
|
||||
if (descriptor->recordData.wifiData.type == IX_ETH_DB_WIFI_AP_TO_AP)
|
||||
{
|
||||
/* gateway address present */
|
||||
printf("%02X:%02X:%02X:%02X:%02X:%02X | WiFi | -- | AP=>AP | ---- | - | --- | %02X:%02X:%02X:%02X:%02X:%02X\n",
|
||||
descriptor->macAddress[0],
|
||||
descriptor->macAddress[1],
|
||||
descriptor->macAddress[2],
|
||||
descriptor->macAddress[3],
|
||||
descriptor->macAddress[4],
|
||||
descriptor->macAddress[5],
|
||||
descriptor->recordData.wifiData.gwMacAddress[0],
|
||||
descriptor->recordData.wifiData.gwMacAddress[1],
|
||||
descriptor->recordData.wifiData.gwMacAddress[2],
|
||||
descriptor->recordData.wifiData.gwMacAddress[3],
|
||||
descriptor->recordData.wifiData.gwMacAddress[4],
|
||||
descriptor->recordData.wifiData.gwMacAddress[5]);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no gateway */
|
||||
printf("%02X:%02X:%02X:%02X:%02X:%02X | WiFi | -- | AP=>ST | ---- | - | --- | -- no gateway -- \n",
|
||||
descriptor->macAddress[0],
|
||||
descriptor->macAddress[1],
|
||||
descriptor->macAddress[2],
|
||||
descriptor->macAddress[3],
|
||||
descriptor->macAddress[4],
|
||||
descriptor->macAddress[5]);
|
||||
}
|
||||
}
|
||||
else if (descriptor->type == IX_ETH_DB_FIREWALL_RECORD)
|
||||
{
|
||||
printf("%02X:%02X:%02X:%02X:%02X:%02X | FW | -- | ------- | ---- | - | --- | -----------------\n",
|
||||
descriptor->macAddress[0],
|
||||
descriptor->macAddress[1],
|
||||
descriptor->macAddress[2],
|
||||
descriptor->macAddress[3],
|
||||
descriptor->macAddress[4],
|
||||
descriptor->macAddress[5]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("invalid record filter\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief displays the status, records and configuration information of a port
|
||||
*
|
||||
* @param portID ID of the port
|
||||
* @param recordFilter record filter to display
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PRIVATE
|
||||
void ixEthDBPortInfoShow(IxEthDBPortId portID, IxEthDBRecordType recordFilter)
|
||||
{
|
||||
PortInfo *portInfo = &ixEthDBPortInfo[portID];
|
||||
UINT32 recordCount = 0;
|
||||
HashIterator iterator;
|
||||
IxEthDBStatus local_result;
|
||||
|
||||
/* display port status */
|
||||
printf("== Port ID %d ==\n", portID);
|
||||
|
||||
/* display capabilities */
|
||||
printf("- Capabilities: ");
|
||||
|
||||
if ((portInfo->featureCapability & IX_ETH_DB_LEARNING) != 0)
|
||||
{
|
||||
printf("Learning (%s) ", ((portInfo->featureStatus & IX_ETH_DB_LEARNING) != 0) ? "on" : "off");
|
||||
}
|
||||
|
||||
if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0)
|
||||
{
|
||||
printf("VLAN/QoS (%s) ", ((portInfo->featureStatus & IX_ETH_DB_VLAN_QOS) != 0) ? "on" : "off");
|
||||
}
|
||||
|
||||
if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0)
|
||||
{
|
||||
printf("Firewall (%s) ", ((portInfo->featureStatus & IX_ETH_DB_FIREWALL) != 0) ? "on" : "off");
|
||||
}
|
||||
|
||||
if ((portInfo->featureCapability & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0)
|
||||
{
|
||||
printf("WiFi (%s) ", ((portInfo->featureStatus & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0) ? "on" : "off");
|
||||
}
|
||||
|
||||
if ((portInfo->featureCapability & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0)
|
||||
{
|
||||
printf("STP (%s) ", ((portInfo->featureStatus & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0) ? "on" : "off");
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
/* dependency map */
|
||||
ixEthDBDependencyPortMapShow(portID, portInfo->dependencyPortMap);
|
||||
|
||||
/* NPE dynamic updates */
|
||||
if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
|
||||
{
|
||||
printf(" - NPE dynamic update is %s\n", portInfo->updateMethod.updateEnabled ? "enabled" : "disabled");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(" - dynamic update disabled (not an NPE)\n");
|
||||
}
|
||||
|
||||
if ((portInfo->featureCapability & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0)
|
||||
{
|
||||
if ((portInfo->featureStatus & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0)
|
||||
{
|
||||
/* WiFi header conversion */
|
||||
if ((portInfo->frameControlDurationID
|
||||
+ portInfo->bbsid[0]
|
||||
+ portInfo->bbsid[1]
|
||||
+ portInfo->bbsid[2]
|
||||
+ portInfo->bbsid[3]
|
||||
+ portInfo->bbsid[4]
|
||||
+ portInfo->bbsid[5]) == 0)
|
||||
{
|
||||
printf(" - WiFi header conversion not configured\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(" - WiFi header conversion: BBSID [%02X:%02X:%02X:%02X:%02X:%02X], Frame Control 0x%X, Duration/ID 0x%X\n",
|
||||
portInfo->bbsid[0],
|
||||
portInfo->bbsid[1],
|
||||
portInfo->bbsid[2],
|
||||
portInfo->bbsid[3],
|
||||
portInfo->bbsid[4],
|
||||
portInfo->bbsid[5],
|
||||
portInfo->frameControlDurationID >> 16,
|
||||
portInfo->frameControlDurationID & 0xFFFF);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(" - WiFi header conversion not enabled\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Firewall */
|
||||
if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0)
|
||||
{
|
||||
if ((portInfo->featureStatus & IX_ETH_DB_FIREWALL) != 0)
|
||||
{
|
||||
printf(" - Firewall is in %s-list mode\n", portInfo->firewallMode == IX_ETH_DB_FIREWALL_BLACK_LIST ? "black" : "white");
|
||||
printf(" - Invalid source MAC address filtering is %s\n", portInfo->srcAddressFilterEnabled ? "enabled" : "disabled");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(" - Firewall not enabled\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* browse database if asked to display records */
|
||||
if (recordFilter != IX_ETH_DB_NO_RECORD_TYPE)
|
||||
{
|
||||
printf("\n");
|
||||
ixEthDBHeaderShow(recordFilter);
|
||||
|
||||
BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
|
||||
|
||||
while (IS_ITERATOR_VALID(&iterator))
|
||||
{
|
||||
MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
|
||||
|
||||
if (descriptor->portID == portID && (descriptor->type & recordFilter) != 0)
|
||||
{
|
||||
recordCount++;
|
||||
|
||||
/* display entry */
|
||||
ixEthDBRecordShow(descriptor, recordFilter);
|
||||
}
|
||||
|
||||
/* move to the next record */
|
||||
BUSY_RETRY_WITH_RESULT(ixEthDBIncrementHashIterator(&dbHashtable, &iterator), local_result);
|
||||
|
||||
/* debug */
|
||||
if (local_result == IX_ETH_DB_BUSY)
|
||||
{
|
||||
printf("EthDB (API): Error, database browser failed (no access), giving up\n");
|
||||
}
|
||||
}
|
||||
|
||||
printf("\nFound %d records\n\n", recordCount);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief displays a record header
|
||||
*
|
||||
* @param recordFilter record type filter
|
||||
*
|
||||
* This function displays a record header, depending on
|
||||
* the given record type filter. It is useful when used
|
||||
* in conjunction with ixEthDBRecordShow which will display
|
||||
* record fields formatted for the header, provided the same
|
||||
* record filter is used.
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the operation completed
|
||||
* successfully or IX_ETH_DB_INVALID_ARG if the recordFilter
|
||||
* parameter is invalid or not supported
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PRIVATE
|
||||
IxEthDBStatus ixEthDBHeaderShow(IxEthDBRecordType recordFilter)
|
||||
{
|
||||
if (recordFilter == IX_ETH_DB_FILTERING_VLAN_RECORD
|
||||
|| recordFilter == (IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD))
|
||||
{
|
||||
/* display VLAN record header */
|
||||
printf(" MAC address | Age | Type | VLAN ID | CFI | QoS class \n");
|
||||
printf("___________________________________________________________________\n");
|
||||
}
|
||||
else if (recordFilter == IX_ETH_DB_FILTERING_RECORD)
|
||||
{
|
||||
/* display filtering record header */
|
||||
printf(" MAC address | Age | Type \n");
|
||||
printf("_______________________________________\n");
|
||||
}
|
||||
else if (recordFilter == IX_ETH_DB_WIFI_RECORD)
|
||||
{
|
||||
/* display WiFi record header */
|
||||
printf(" MAC address | GW MAC address \n");
|
||||
printf("_______________________________________\n");
|
||||
}
|
||||
else if (recordFilter == IX_ETH_DB_FIREWALL_RECORD)
|
||||
{
|
||||
/* display Firewall record header */
|
||||
printf(" MAC address \n");
|
||||
printf("__________________\n");
|
||||
}
|
||||
else if (recordFilter == IX_ETH_DB_ALL_RECORD_TYPES)
|
||||
{
|
||||
/* display composite record header */
|
||||
printf(" MAC address | Record | Age| Type | VLAN |CFI| QoS | GW MAC address \n");
|
||||
printf("_______________________________________________________________________________\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
return IX_ETH_DB_INVALID_ARG;
|
||||
}
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief displays database information (records and port information)
|
||||
*
|
||||
* @param portID ID of the port to display (or IX_ETH_DB_ALL_PORTS for all the ports)
|
||||
* @param recordFilter record filter (use IX_ETH_DB_NO_RECORD_TYPE to display only
|
||||
* port information)
|
||||
*
|
||||
* Note that this function is documented in the main component header
|
||||
* file, IxEthDB.h.
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the operation completed successfully or
|
||||
* an appropriate error code otherwise
|
||||
*
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBFilteringDatabaseShowRecords(IxEthDBPortId portID, IxEthDBRecordType recordFilter)
|
||||
{
|
||||
IxEthDBPortId currentPort;
|
||||
BOOL showAllPorts = (portID == IX_ETH_DB_ALL_PORTS);
|
||||
|
||||
IX_ETH_DB_CHECK_PORT_ALL(portID);
|
||||
|
||||
printf("\nEthernet learning/filtering database: listing %d port(s)\n\n", showAllPorts ? (UINT32) IX_ETH_DB_NUMBER_OF_PORTS : 1);
|
||||
|
||||
currentPort = showAllPorts ? 0 : portID;
|
||||
|
||||
while (currentPort != IX_ETH_DB_NUMBER_OF_PORTS)
|
||||
{
|
||||
/* display port info */
|
||||
ixEthDBPortInfoShow(currentPort, recordFilter);
|
||||
|
||||
/* next port */
|
||||
currentPort = showAllPorts ? currentPort + 1 : IX_ETH_DB_NUMBER_OF_PORTS;
|
||||
}
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
|
@ -1,303 +0,0 @@
|
|||
/**
|
||||
* @file IxEthDBSearch.c
|
||||
*
|
||||
* @par
|
||||
* IXP400 SW Release version 2.0
|
||||
*
|
||||
* -- Copyright Notice --
|
||||
*
|
||||
* @par
|
||||
* Copyright 2001-2005, Intel Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
* @par
|
||||
* -- End of Copyright Notice --
|
||||
*/
|
||||
|
||||
#include "IxEthDB_p.h"
|
||||
|
||||
extern HashTable dbHashtable;
|
||||
|
||||
/**
|
||||
* @brief matches two database records based on their MAC addresses
|
||||
*
|
||||
* @param untypedReference record to match against
|
||||
* @param untypedEntry record to match
|
||||
*
|
||||
* @return true if the match is successful or false otherwise
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
BOOL ixEthDBAddressRecordMatch(void *untypedReference, void *untypedEntry)
|
||||
{
|
||||
MacDescriptor *entry = (MacDescriptor *) untypedEntry;
|
||||
MacDescriptor *reference = (MacDescriptor *) untypedReference;
|
||||
|
||||
/* check accepted record types */
|
||||
if ((entry->type & reference->type) == 0) return false;
|
||||
|
||||
return (ixEthDBAddressCompare((UINT8 *) entry->macAddress, (UINT8 *) reference->macAddress) == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief matches two database records based on their MAC addresses
|
||||
* and VLAN IDs
|
||||
*
|
||||
* @param untypedReference record to match against
|
||||
* @param untypedEntry record to match
|
||||
*
|
||||
* @return true if the match is successful or false otherwise
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
BOOL ixEthDBVlanRecordMatch(void *untypedReference, void *untypedEntry)
|
||||
{
|
||||
MacDescriptor *entry = (MacDescriptor *) untypedEntry;
|
||||
MacDescriptor *reference = (MacDescriptor *) untypedReference;
|
||||
|
||||
/* check accepted record types */
|
||||
if ((entry->type & reference->type) == 0) return false;
|
||||
|
||||
return (IX_ETH_DB_GET_VLAN_ID(entry->recordData.filteringVlanData.ieee802_1qTag) ==
|
||||
IX_ETH_DB_GET_VLAN_ID(reference->recordData.filteringVlanData.ieee802_1qTag)) &&
|
||||
(ixEthDBAddressCompare(entry->macAddress, reference->macAddress) == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief matches two database records based on their MAC addresses
|
||||
* and port IDs
|
||||
*
|
||||
* @param untypedReference record to match against
|
||||
* @param untypedEntry record to match
|
||||
*
|
||||
* @return true if the match is successful or false otherwise
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
BOOL ixEthDBPortRecordMatch(void *untypedReference, void *untypedEntry)
|
||||
{
|
||||
MacDescriptor *entry = (MacDescriptor *) untypedEntry;
|
||||
MacDescriptor *reference = (MacDescriptor *) untypedReference;
|
||||
|
||||
/* check accepted record types */
|
||||
if ((entry->type & reference->type) == 0) return false;
|
||||
|
||||
return (entry->portID == reference->portID) &&
|
||||
(ixEthDBAddressCompare(entry->macAddress, reference->macAddress) == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief dummy matching function, registered for safety
|
||||
*
|
||||
* @param reference record to match against (unused)
|
||||
* @param entry record to match (unused)
|
||||
*
|
||||
* This function is registered in the matching functions
|
||||
* array on invalid types. Calling it will display an
|
||||
* error message, indicating an error in the component logic.
|
||||
*
|
||||
* @return false
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
BOOL ixEthDBNullMatch(void *reference, void *entry)
|
||||
{
|
||||
/* display an error message */
|
||||
|
||||
ixOsalLog(IX_OSAL_LOG_LVL_WARNING, IX_OSAL_LOG_DEV_STDOUT, "DB: (Search) The NullMatch function was called, wrong key type?\n", 0, 0, 0, 0, 0, 0);
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief registers hash matching methods
|
||||
*
|
||||
* @param matchFunctions table of match functions to be populated
|
||||
*
|
||||
* This function registers the available record matching functions
|
||||
* by indexing them on record types into the given function array.
|
||||
*
|
||||
* Note that it is compulsory to call this in ixEthDBInit(),
|
||||
* otherwise hashtable searching and removal will not work
|
||||
*
|
||||
* @return number of registered functions
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
UINT32 ixEthDBMatchMethodsRegister(MatchFunction *matchFunctions)
|
||||
{
|
||||
UINT32 i;
|
||||
|
||||
/* safety first */
|
||||
for ( i = 0 ; i < IX_ETH_DB_MAX_KEY_INDEX + 1 ; i++)
|
||||
{
|
||||
matchFunctions[i] = ixEthDBNullMatch;
|
||||
}
|
||||
|
||||
/* register MAC search method */
|
||||
matchFunctions[IX_ETH_DB_MAC_KEY] = ixEthDBAddressRecordMatch;
|
||||
|
||||
/* register MAC/PortID search method */
|
||||
matchFunctions[IX_ETH_DB_MAC_PORT_KEY] = ixEthDBPortRecordMatch;
|
||||
|
||||
/* register MAC/VLAN ID search method */
|
||||
matchFunctions[IX_ETH_DB_MAC_VLAN_KEY] = ixEthDBVlanRecordMatch;
|
||||
|
||||
return 3; /* three methods */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief search a record in the Ethernet datbase
|
||||
*
|
||||
* @param macAddress MAC address to perform the search on
|
||||
* @param typeFilter type of records to consider for matching
|
||||
*
|
||||
* @warning if searching is successful an implicit write lock
|
||||
* to the search result is granted, therefore unlock the
|
||||
* entry using @ref ixEthDBReleaseHashNode() as soon as possible.
|
||||
*
|
||||
* @see ixEthDBReleaseHashNode()
|
||||
*
|
||||
* @return the search result, or NULL if a record with the given
|
||||
* MAC address was not found
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
HashNode* ixEthDBSearch(IxEthDBMacAddr *macAddress, IxEthDBRecordType typeFilter)
|
||||
{
|
||||
HashNode *searchResult = NULL;
|
||||
MacDescriptor reference;
|
||||
|
||||
TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER;
|
||||
|
||||
if (macAddress == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* fill search fields */
|
||||
memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr));
|
||||
|
||||
/* set acceptable record types */
|
||||
reference.type = typeFilter;
|
||||
|
||||
BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, IX_ETH_DB_MAC_KEY, &reference, &searchResult));
|
||||
|
||||
return searchResult;
|
||||
}
|
||||
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBPeek(IxEthDBMacAddr *macAddress, IxEthDBRecordType typeFilter)
|
||||
{
|
||||
MacDescriptor reference;
|
||||
IxEthDBStatus result;
|
||||
|
||||
TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER;
|
||||
|
||||
if (macAddress == NULL)
|
||||
{
|
||||
return IX_ETH_DB_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* fill search fields */
|
||||
memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr));
|
||||
|
||||
/* set acceptable record types */
|
||||
reference.type = typeFilter;
|
||||
|
||||
result = ixEthDBPeekHashEntry(&dbHashtable, IX_ETH_DB_MAC_KEY, &reference);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief search a record in the Ethernet datbase
|
||||
*
|
||||
* @param macAddress MAC address to perform the search on
|
||||
* @param portID port ID to perform the search on
|
||||
* @param typeFilter type of records to consider for matching
|
||||
*
|
||||
* @warning if searching is successful an implicit write lock
|
||||
* to the search result is granted, therefore unlock the
|
||||
* entry using @ref ixEthDBReleaseHashNode() as soon as possible.
|
||||
*
|
||||
* @see ixEthDBReleaseHashNode()
|
||||
*
|
||||
* @return the search result, or NULL if a record with the given
|
||||
* MAC address/port ID combination was not found
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
HashNode* ixEthDBPortSearch(IxEthDBMacAddr *macAddress, IxEthDBPortId portID, IxEthDBRecordType typeFilter)
|
||||
{
|
||||
HashNode *searchResult = NULL;
|
||||
MacDescriptor reference;
|
||||
|
||||
if (macAddress == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* fill search fields */
|
||||
memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr));
|
||||
reference.portID = portID;
|
||||
|
||||
/* set acceptable record types */
|
||||
reference.type = typeFilter;
|
||||
|
||||
BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, IX_ETH_DB_MAC_PORT_KEY, &reference, &searchResult));
|
||||
|
||||
return searchResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief search a record in the Ethernet datbase
|
||||
*
|
||||
* @param macAddress MAC address to perform the search on
|
||||
* @param vlanID VLAN ID to perform the search on
|
||||
* @param typeFilter type of records to consider for matching
|
||||
*
|
||||
* @warning if searching is successful an implicit write lock
|
||||
* to the search result is granted, therefore unlock the
|
||||
* entry using @ref ixEthDBReleaseHashNode() as soon as possible.
|
||||
*
|
||||
* @see ixEthDBReleaseHashNode()
|
||||
*
|
||||
* @return the search result, or NULL if a record with the given
|
||||
* MAC address/VLAN ID combination was not found
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
HashNode* ixEthDBVlanSearch(IxEthDBMacAddr *macAddress, IxEthDBVlanId vlanID, IxEthDBRecordType typeFilter)
|
||||
{
|
||||
HashNode *searchResult = NULL;
|
||||
MacDescriptor reference;
|
||||
|
||||
if (macAddress == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* fill search fields */
|
||||
memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr));
|
||||
reference.recordData.filteringVlanData.ieee802_1qTag =
|
||||
IX_ETH_DB_SET_VLAN_ID(reference.recordData.filteringVlanData.ieee802_1qTag, vlanID);
|
||||
|
||||
/* set acceptable record types */
|
||||
reference.type = typeFilter;
|
||||
|
||||
BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, IX_ETH_DB_MAC_VLAN_KEY, &reference, &searchResult));
|
||||
|
||||
return searchResult;
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
/**
|
||||
* @file IxEthDBSpanningTree.c
|
||||
*
|
||||
* @brief Implementation of the STP API
|
||||
*
|
||||
* @par
|
||||
* IXP400 SW Release version 2.0
|
||||
*
|
||||
* -- Copyright Notice --
|
||||
*
|
||||
* @par
|
||||
* Copyright 2001-2005, Intel Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
* @par
|
||||
* -- End of Copyright Notice --
|
||||
*/
|
||||
|
||||
|
||||
#include "IxEthDB_p.h"
|
||||
|
||||
/**
|
||||
* @brief sets the STP blocking state of a port
|
||||
*
|
||||
* @param portID ID of the port
|
||||
* @param blocked true to block the port or false to unblock it
|
||||
*
|
||||
* Note that this function is documented in the main component
|
||||
* header file, IxEthDB.h.
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the operation completed successfully
|
||||
* or an appropriate error message otherwise
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBSpanningTreeBlockingStateSet(IxEthDBPortId portID, BOOL blocked)
|
||||
{
|
||||
IxNpeMhMessage message;
|
||||
IX_STATUS result;
|
||||
|
||||
IX_ETH_DB_CHECK_PORT(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_SPANNING_TREE_PROTOCOL);
|
||||
|
||||
ixEthDBPortInfo[portID].stpBlocked = blocked;
|
||||
|
||||
FILL_SETBLOCKINGSTATE_MSG(message, portID, blocked);
|
||||
|
||||
IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief retrieves the STP blocking state of a port
|
||||
*
|
||||
* @param portID ID of the port
|
||||
* @param blocked address to write the blocked status into
|
||||
*
|
||||
* Note that this function is documented in the main component
|
||||
* header file, IxEthDB.h.
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the operation completed successfully
|
||||
* or an appropriate error message otherwise
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBSpanningTreeBlockingStateGet(IxEthDBPortId portID, BOOL *blocked)
|
||||
{
|
||||
IX_ETH_DB_CHECK_PORT(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_SPANNING_TREE_PROTOCOL);
|
||||
|
||||
IX_ETH_DB_CHECK_REFERENCE(blocked);
|
||||
|
||||
*blocked = ixEthDBPortInfo[portID].stpBlocked;
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
/**
|
||||
* @file ethUtil.c
|
||||
*
|
||||
* @brief Utility functions
|
||||
*
|
||||
* @par
|
||||
* IXP400 SW Release version 2.0
|
||||
*
|
||||
* -- Copyright Notice --
|
||||
*
|
||||
* @par
|
||||
* Copyright 2001-2005, Intel Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
* @par
|
||||
* -- End of Copyright Notice --
|
||||
*/
|
||||
|
||||
|
||||
#include "IxFeatureCtrl.h"
|
||||
#include "IxEthDB_p.h"
|
||||
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBSingleEthNpeCheck(IxEthDBPortId portID)
|
||||
{
|
||||
/* If not IXP42X A0 stepping, proceed to check for existence of coprocessors */
|
||||
if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
|
||||
(ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
|
||||
|| (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
|
||||
{
|
||||
if ((portID == 0) &&
|
||||
(ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) ==
|
||||
IX_FEATURE_CTRL_COMPONENT_DISABLED))
|
||||
{
|
||||
return IX_ETH_DB_FAIL;
|
||||
}
|
||||
|
||||
if ((portID == 1) &&
|
||||
(ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) ==
|
||||
IX_FEATURE_CTRL_COMPONENT_DISABLED))
|
||||
{
|
||||
return IX_ETH_DB_FAIL;
|
||||
}
|
||||
|
||||
if ((portID == 2) &&
|
||||
(ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA_ETH) ==
|
||||
IX_FEATURE_CTRL_COMPONENT_DISABLED))
|
||||
{
|
||||
return IX_ETH_DB_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
return IX_ETH_DB_SUCCESS;
|
||||
}
|
||||
|
||||
IX_ETH_DB_PUBLIC
|
||||
BOOL ixEthDBCheckSingleBitValue(UINT32 value)
|
||||
{
|
||||
#if (CPU != SIMSPARCSOLARIS) && !defined (__wince)
|
||||
UINT32 shift;
|
||||
|
||||
/* use the count-leading-zeros XScale instruction */
|
||||
__asm__ ("clz %0, %1\n" : "=r" (shift) : "r" (value));
|
||||
|
||||
return ((value << shift) == 0x80000000UL);
|
||||
|
||||
#else
|
||||
|
||||
while (value != 0)
|
||||
{
|
||||
if (value == 1) return true;
|
||||
else if ((value & 1) == 1) return false;
|
||||
|
||||
value >>= 1;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *mac2string(const unsigned char *mac)
|
||||
{
|
||||
static char str[19];
|
||||
|
||||
if (mac == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sprintf(str, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
|
||||
return str;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,456 +0,0 @@
|
|||
/**
|
||||
* @file IxEthDBAPI.c
|
||||
*
|
||||
* @brief Implementation of the public API
|
||||
*
|
||||
* @par
|
||||
* IXP400 SW Release version 2.0
|
||||
*
|
||||
* -- Copyright Notice --
|
||||
*
|
||||
* @par
|
||||
* Copyright 2001-2005, Intel Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
* @par
|
||||
* -- End of Copyright Notice --
|
||||
*/
|
||||
|
||||
#include "IxEthDB_p.h"
|
||||
|
||||
/* forward prototypes */
|
||||
IX_ETH_DB_PUBLIC
|
||||
MacTreeNode *ixEthDBGatewaySelect(MacTreeNode *stations);
|
||||
|
||||
/**
|
||||
* @brief sets the BBSID value for the WiFi header conversion feature
|
||||
*
|
||||
* @param portID ID of the port
|
||||
* @param bbsid pointer to the 6-byte BBSID value
|
||||
*
|
||||
* Note that this function is documented in the main component
|
||||
* header file, IxEthDB.h.
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the operation completed successfully
|
||||
* or an appropriate error message otherwise
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBWiFiBBSIDSet(IxEthDBPortId portID, IxEthDBMacAddr *bbsid)
|
||||
{
|
||||
IxNpeMhMessage message;
|
||||
IX_STATUS result;
|
||||
|
||||
IX_ETH_DB_CHECK_PORT(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
|
||||
|
||||
IX_ETH_DB_CHECK_REFERENCE(bbsid);
|
||||
|
||||
memcpy(ixEthDBPortInfo[portID].bbsid, bbsid, sizeof (IxEthDBMacAddr));
|
||||
|
||||
FILL_SETBBSID_MSG(message, portID, bbsid);
|
||||
|
||||
IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief updates the Frame Control and Duration/ID WiFi header
|
||||
* conversion parameters in an NPE
|
||||
*
|
||||
* @param portID ID of the port
|
||||
*
|
||||
* This function will send a message to the NPE updating the
|
||||
* frame conversion parameters for 802.3 => 802.11 header conversion.
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the operation completed successfully
|
||||
* or IX_ETH_DB_FAIL otherwise
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PRIVATE
|
||||
IxEthDBStatus ixEthDBWiFiFrameControlDurationIDUpdate(IxEthDBPortId portID)
|
||||
{
|
||||
IxNpeMhMessage message;
|
||||
IX_STATUS result;
|
||||
|
||||
FILL_SETFRAMECONTROLDURATIONID(message, portID, ixEthDBPortInfo[portID].frameControlDurationID);
|
||||
|
||||
IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief sets the Duration/ID WiFi frame header conversion parameter
|
||||
*
|
||||
* @param portID ID of the port
|
||||
* @param durationID 16-bit value containing the new Duration/ID parameter
|
||||
*
|
||||
* Note that this function is documented in the main component
|
||||
* header file, IxEthDB.h.
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the operation completed successfully
|
||||
* or an appropriate error message otherwise
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBWiFiDurationIDSet(IxEthDBPortId portID, UINT16 durationID)
|
||||
{
|
||||
IX_ETH_DB_CHECK_PORT(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
|
||||
|
||||
ixEthDBPortInfo[portID].frameControlDurationID = (ixEthDBPortInfo[portID].frameControlDurationID & 0xFFFF0000) | durationID;
|
||||
|
||||
return ixEthDBWiFiFrameControlDurationIDUpdate(portID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief sets the Frame Control WiFi frame header conversion parameter
|
||||
*
|
||||
* @param portID ID of the port
|
||||
* @param durationID 16-bit value containing the new Frame Control parameter
|
||||
*
|
||||
* Note that this function is documented in the main component
|
||||
* header file, IxEthDB.h.
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the operation completed successfully
|
||||
* or an appropriate error message otherwise
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBWiFiFrameControlSet(IxEthDBPortId portID, UINT16 frameControl)
|
||||
{
|
||||
IX_ETH_DB_CHECK_PORT(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
|
||||
|
||||
ixEthDBPortInfo[portID].frameControlDurationID = (ixEthDBPortInfo[portID].frameControlDurationID & 0xFFFF) | (frameControl << 16);
|
||||
|
||||
return ixEthDBWiFiFrameControlDurationIDUpdate(portID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief removes a WiFi header conversion record
|
||||
*
|
||||
* @param portID ID of the port
|
||||
* @param macAddr MAC address of the record to remove
|
||||
*
|
||||
* Note that this function is documented in the main
|
||||
* component header file, IxEthDB.h.
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the operation completed
|
||||
* successfully or an appropriate error message otherwise
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBWiFiEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
|
||||
{
|
||||
MacDescriptor recordTemplate;
|
||||
|
||||
IX_ETH_DB_CHECK_PORT(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_REFERENCE(macAddr);
|
||||
|
||||
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
|
||||
|
||||
memcpy(recordTemplate.macAddress, macAddr, sizeof (IxEthDBMacAddr));
|
||||
|
||||
recordTemplate.type = IX_ETH_DB_WIFI_RECORD;
|
||||
recordTemplate.portID = portID;
|
||||
|
||||
return ixEthDBRemove(&recordTemplate, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief adds a WiFi header conversion record
|
||||
*
|
||||
* @param portID ID of the port
|
||||
* @param macAddr MAC address of the record to add
|
||||
* @param gatewayMacAddr address of the gateway (or
|
||||
* NULL if this is a station record)
|
||||
*
|
||||
* This function adds a record of type AP_TO_AP (gateway is not NULL)
|
||||
* or AP_TO_STA (gateway is NULL) in the main database as a
|
||||
* WiFi header conversion record.
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the operation completed
|
||||
* successfully or an appropriate error message otherwise
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PRIVATE
|
||||
IxEthDBStatus ixEthDBWiFiEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr, IxEthDBMacAddr *gatewayMacAddr)
|
||||
{
|
||||
MacDescriptor recordTemplate;
|
||||
|
||||
IX_ETH_DB_CHECK_PORT(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_REFERENCE(macAddr);
|
||||
|
||||
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
|
||||
|
||||
memcpy(recordTemplate.macAddress, macAddr, sizeof (IxEthDBMacAddr));
|
||||
|
||||
recordTemplate.type = IX_ETH_DB_WIFI_RECORD;
|
||||
recordTemplate.portID = portID;
|
||||
|
||||
if (gatewayMacAddr != NULL)
|
||||
{
|
||||
memcpy(recordTemplate.recordData.wifiData.gwMacAddress, gatewayMacAddr, sizeof (IxEthDBMacAddr));
|
||||
|
||||
recordTemplate.recordData.wifiData.type = IX_ETH_DB_WIFI_AP_TO_AP;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(recordTemplate.recordData.wifiData.gwMacAddress, 0, sizeof (IxEthDBMacAddr));
|
||||
|
||||
recordTemplate.recordData.wifiData.type = IX_ETH_DB_WIFI_AP_TO_STA;
|
||||
}
|
||||
|
||||
return ixEthDBAdd(&recordTemplate, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief adds a WiFi header conversion record
|
||||
*
|
||||
* @param portID ID of the port
|
||||
* @param macAddr MAC address of the record to add
|
||||
* @param gatewayMacAddr address of the gateway
|
||||
*
|
||||
* This function adds a record of type AP_TO_AP
|
||||
* in the main database as a WiFi header conversion record.
|
||||
*
|
||||
* This is simply a wrapper over @ref ixEthDBWiFiEntryAdd().
|
||||
*
|
||||
* Note that this function is documented in the main
|
||||
* component header file, IxEthDB.h.
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the operation completed
|
||||
* successfully or an appropriate error message otherwise
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBWiFiAccessPointEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr, IxEthDBMacAddr *gatewayMacAddr)
|
||||
{
|
||||
IX_ETH_DB_CHECK_REFERENCE(gatewayMacAddr);
|
||||
|
||||
return ixEthDBWiFiEntryAdd(portID, macAddr, gatewayMacAddr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief adds a WiFi header conversion record
|
||||
*
|
||||
* @param portID ID of the port
|
||||
* @param macAddr MAC address of the record to add
|
||||
*
|
||||
* This function adds a record of type AP_TO_STA
|
||||
* in the main database as a WiFi header conversion record.
|
||||
*
|
||||
* This is simply a wrapper over @ref ixEthDBWiFiEntryAdd().
|
||||
*
|
||||
* Note that this function is documented in the main
|
||||
* component header file, IxEthDB.h.
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the operation completed
|
||||
* successfully or an appropriate error message otherwise
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBWiFiStationEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
|
||||
{
|
||||
return ixEthDBWiFiEntryAdd(portID, macAddr, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief selects a set of gateways from a tree of
|
||||
* WiFi header conversion records
|
||||
*
|
||||
* @param stations binary tree containing pointers to WiFi header
|
||||
* conversion records
|
||||
*
|
||||
* This function browses through the input binary tree, identifies
|
||||
* records of type AP_TO_AP, clones these records and appends them
|
||||
* to a vine (a single right-branch binary tree) which is returned
|
||||
* as result. A maximum of MAX_GW_SIZE entries containing gateways
|
||||
* will be cloned from the original tree.
|
||||
*
|
||||
* @return vine (linear binary tree) containing record
|
||||
* clones of AP_TO_AP type, which have a gateway field
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
MacTreeNode *ixEthDBGatewaySelect(MacTreeNode *stations)
|
||||
{
|
||||
MacTreeNodeStack *stack;
|
||||
MacTreeNode *gateways, *insertionPlace;
|
||||
UINT32 gwIndex = 1; /* skip the empty root */
|
||||
|
||||
if (stations == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
stack = ixOsalCacheDmaMalloc(sizeof (MacTreeNodeStack));
|
||||
|
||||
if (stack == NULL)
|
||||
{
|
||||
ERROR_LOG("DB: (WiFi) failed to allocate the node stack for gateway tree linearization, out of memory?\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* initialize root node */
|
||||
gateways = insertionPlace = NULL;
|
||||
|
||||
/* start browsing the station tree */
|
||||
NODE_STACK_INIT(stack);
|
||||
|
||||
/* initialize stack by pushing the tree root at offset 0 */
|
||||
NODE_STACK_PUSH(stack, stations, 0);
|
||||
|
||||
while (NODE_STACK_NONEMPTY(stack))
|
||||
{
|
||||
MacTreeNode *node;
|
||||
UINT32 offset;
|
||||
|
||||
NODE_STACK_POP(stack, node, offset);
|
||||
|
||||
/* we can store maximum 31 (32 total, 1 empty root) entries in the gateway tree */
|
||||
if (offset > (MAX_GW_SIZE - 1)) break;
|
||||
|
||||
/* check if this record has a gateway address */
|
||||
if (node->descriptor != NULL && node->descriptor->recordData.wifiData.type == IX_ETH_DB_WIFI_AP_TO_AP)
|
||||
{
|
||||
/* found a record, create an insertion place */
|
||||
if (insertionPlace != NULL)
|
||||
{
|
||||
insertionPlace->right = ixEthDBAllocMacTreeNode();
|
||||
insertionPlace = insertionPlace->right;
|
||||
}
|
||||
else
|
||||
{
|
||||
gateways = ixEthDBAllocMacTreeNode();
|
||||
insertionPlace = gateways;
|
||||
}
|
||||
|
||||
if (insertionPlace == NULL)
|
||||
{
|
||||
/* no nodes left, bail out with what we have */
|
||||
ixOsalCacheDmaFree(stack);
|
||||
return gateways;
|
||||
}
|
||||
|
||||
/* clone the original record for the gateway tree */
|
||||
insertionPlace->descriptor = ixEthDBCloneMacDescriptor(node->descriptor);
|
||||
|
||||
/* insert and update the offset in the original record */
|
||||
node->descriptor->recordData.wifiData.gwAddressIndex = gwIndex++;
|
||||
}
|
||||
|
||||
/* browse the tree */
|
||||
if (node->left != NULL)
|
||||
{
|
||||
NODE_STACK_PUSH(stack, node->left, LEFT_CHILD_OFFSET(offset));
|
||||
}
|
||||
|
||||
if (node->right != NULL)
|
||||
{
|
||||
NODE_STACK_PUSH(stack, node->right, RIGHT_CHILD_OFFSET(offset));
|
||||
}
|
||||
}
|
||||
|
||||
ixOsalCacheDmaFree(stack);
|
||||
return gateways;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief downloads the WiFi header conversion table to an NPE
|
||||
*
|
||||
* @param portID ID of the port
|
||||
*
|
||||
* This function prepares the WiFi header conversion tables and
|
||||
* downloads them to the specified NPE port.
|
||||
*
|
||||
* The header conversion tables consist in the main table of
|
||||
* addresses and the secondary table of gateways. AP_TO_AP records
|
||||
* from the first table contain index fields into the second table
|
||||
* for gateway selection.
|
||||
*
|
||||
* Note that this function is documented in the main component
|
||||
* header file, IxEthDB.h.
|
||||
*
|
||||
* @return IX_ETH_DB_SUCCESS if the operation completed successfully
|
||||
* or an appropriate error message otherwise
|
||||
*/
|
||||
IX_ETH_DB_PUBLIC
|
||||
IxEthDBStatus ixEthDBWiFiConversionTableDownload(IxEthDBPortId portID)
|
||||
{
|
||||
IxEthDBPortMap query;
|
||||
MacTreeNode *stations = NULL, *gateways = NULL, *gateway = NULL;
|
||||
IxNpeMhMessage message;
|
||||
PortInfo *portInfo;
|
||||
IX_STATUS result;
|
||||
|
||||
IX_ETH_DB_CHECK_PORT(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
|
||||
|
||||
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
|
||||
|
||||
portInfo = &ixEthDBPortInfo[portID];
|
||||
|
||||
SET_DEPENDENCY_MAP(query, portID);
|
||||
|
||||
ixEthDBUpdateLock();
|
||||
|
||||
stations = ixEthDBQuery(NULL, query, IX_ETH_DB_WIFI_RECORD, MAX_ELT_SIZE);
|
||||
gateways = ixEthDBGatewaySelect(stations);
|
||||
|
||||
/* clean up gw area */
|
||||
memset((void *) portInfo->updateMethod.npeGwUpdateZone, FULL_GW_BYTE_SIZE, 0);
|
||||
|
||||
/* write all gateways */
|
||||
gateway = gateways;
|
||||
|
||||
while (gateway != NULL)
|
||||
{
|
||||
ixEthDBNPEGatewayNodeWrite((void *) (((UINT32) portInfo->updateMethod.npeGwUpdateZone)
|
||||
+ gateway->descriptor->recordData.wifiData.gwAddressIndex * ELT_ENTRY_SIZE),
|
||||
gateway);
|
||||
|
||||
gateway = gateway->right;
|
||||
}
|
||||
|
||||
/* free the gateway tree */
|
||||
if (gateways != NULL)
|
||||
{
|
||||
ixEthDBFreeMacTreeNode(gateways);
|
||||
}
|
||||
|
||||
FILL_SETAPMACTABLE_MSG(message,
|
||||
IX_OSAL_MMU_VIRT_TO_PHYS(portInfo->updateMethod.npeGwUpdateZone));
|
||||
|
||||
IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
|
||||
|
||||
if (result == IX_SUCCESS)
|
||||
{
|
||||
/* update the main tree (the stations tree) */
|
||||
portInfo->updateMethod.searchTree = stations;
|
||||
|
||||
result = ixEthDBNPEUpdateHandler(portID, IX_ETH_DB_WIFI_RECORD);
|
||||
}
|
||||
|
||||
ixEthDBUpdateUnlock();
|
||||
|
||||
return result;
|
||||
}
|
|
@ -1,473 +0,0 @@
|
|||
/**
|
||||
* @file IxEthMii.c
|
||||
*
|
||||
* @author Intel Corporation
|
||||
* @date
|
||||
*
|
||||
* @brief MII control functions
|
||||
*
|
||||
* Design Notes:
|
||||
*
|
||||
*
|
||||
* @par
|
||||
* IXP400 SW Release version 2.0
|
||||
*
|
||||
* -- Copyright Notice --
|
||||
*
|
||||
* @par
|
||||
* Copyright 2001-2005, Intel Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
* @par
|
||||
* -- End of Copyright Notice --
|
||||
*/
|
||||
|
||||
#include "IxOsal.h"
|
||||
|
||||
#include "IxEthAcc.h"
|
||||
#include "IxEthMii_p.h"
|
||||
|
||||
#ifdef __wince
|
||||
#include "IxOsPrintf.h"
|
||||
#endif
|
||||
|
||||
/* Array to store the phy IDs of the discovered phys */
|
||||
PRIVATE UINT32 ixEthMiiPhyId[IXP425_ETH_ACC_MII_MAX_ADDR];
|
||||
|
||||
/*********************************************************
|
||||
*
|
||||
* Scan for PHYs on the MII bus. This function returns
|
||||
* an array of booleans, one for each PHY address.
|
||||
* If a PHY is found at a particular address, the
|
||||
* corresponding entry in the array is set to true.
|
||||
*
|
||||
*/
|
||||
|
||||
PUBLIC IX_STATUS
|
||||
ixEthMiiPhyScan(BOOL phyPresent[], UINT32 maxPhyCount)
|
||||
{
|
||||
UINT32 i;
|
||||
UINT16 regval, regvalId1, regvalId2;
|
||||
|
||||
/*Search for PHYs on the MII*/
|
||||
/*Search for existant phys on the MDIO bus*/
|
||||
|
||||
if ((phyPresent == NULL) ||
|
||||
(maxPhyCount > IXP425_ETH_ACC_MII_MAX_ADDR))
|
||||
{
|
||||
return IX_FAIL;
|
||||
}
|
||||
|
||||
/* fill the array */
|
||||
for(i=0;
|
||||
i<IXP425_ETH_ACC_MII_MAX_ADDR;
|
||||
i++)
|
||||
{
|
||||
phyPresent[i] = false;
|
||||
}
|
||||
|
||||
/* iterate through the PHY addresses */
|
||||
for(i=0;
|
||||
maxPhyCount > 0 && i<IXP425_ETH_ACC_MII_MAX_ADDR;
|
||||
i++)
|
||||
{
|
||||
ixEthMiiPhyId[i] = IX_ETH_MII_INVALID_PHY_ID;
|
||||
if(ixEthAccMiiReadRtn(i,
|
||||
IX_ETH_MII_CTRL_REG,
|
||||
®val) == IX_ETH_ACC_SUCCESS)
|
||||
{
|
||||
if((regval & 0xffff) != 0xffff)
|
||||
{
|
||||
maxPhyCount--;
|
||||
/*Need to read the register twice here to flush PHY*/
|
||||
ixEthAccMiiReadRtn(i, IX_ETH_MII_PHY_ID1_REG, ®valId1);
|
||||
ixEthAccMiiReadRtn(i, IX_ETH_MII_PHY_ID1_REG, ®valId1);
|
||||
ixEthAccMiiReadRtn(i, IX_ETH_MII_PHY_ID2_REG, ®valId2);
|
||||
ixEthMiiPhyId[i] = (regvalId1 << IX_ETH_MII_REG_SHL) | regvalId2;
|
||||
if ((ixEthMiiPhyId[i] == IX_ETH_MII_KS8995_PHY_ID)
|
||||
|| (ixEthMiiPhyId[i] == IX_ETH_MII_LXT971_PHY_ID)
|
||||
|| (ixEthMiiPhyId[i] == IX_ETH_MII_LXT972_PHY_ID)
|
||||
|| (ixEthMiiPhyId[i] == IX_ETH_MII_LXT973_PHY_ID)
|
||||
|| (ixEthMiiPhyId[i] == IX_ETH_MII_LXT973A3_PHY_ID)
|
||||
|| (ixEthMiiPhyId[i] == IX_ETH_MII_LXT9785_PHY_ID)
|
||||
)
|
||||
{
|
||||
/* supported phy */
|
||||
phyPresent[i] = true;
|
||||
} /* end of if(ixEthMiiPhyId) */
|
||||
else
|
||||
{
|
||||
if (ixEthMiiPhyId[i] != IX_ETH_MII_INVALID_PHY_ID)
|
||||
{
|
||||
/* unsupported phy */
|
||||
ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
|
||||
IX_OSAL_LOG_DEV_STDOUT,
|
||||
"ixEthMiiPhyScan : unexpected Mii PHY ID %8.8x\n",
|
||||
ixEthMiiPhyId[i], 2, 3, 4, 5, 6);
|
||||
ixEthMiiPhyId[i] = IX_ETH_MII_UNKNOWN_PHY_ID;
|
||||
phyPresent[i] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return IX_SUCCESS;
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
*
|
||||
* Configure the PHY at the specified address
|
||||
*
|
||||
*/
|
||||
PUBLIC IX_STATUS
|
||||
ixEthMiiPhyConfig(UINT32 phyAddr,
|
||||
BOOL speed100,
|
||||
BOOL fullDuplex,
|
||||
BOOL autonegotiate)
|
||||
{
|
||||
UINT16 regval=0;
|
||||
|
||||
/* parameter check */
|
||||
if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) &&
|
||||
(ixEthMiiPhyId[phyAddr] != IX_ETH_MII_INVALID_PHY_ID))
|
||||
{
|
||||
/*
|
||||
* set the control register
|
||||
*/
|
||||
if(autonegotiate)
|
||||
{
|
||||
regval |= IX_ETH_MII_CR_AUTO_EN | IX_ETH_MII_CR_RESTART;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(speed100)
|
||||
{
|
||||
regval |= IX_ETH_MII_CR_100;
|
||||
}
|
||||
if(fullDuplex)
|
||||
{
|
||||
regval |= IX_ETH_MII_CR_FDX;
|
||||
}
|
||||
} /* end of if-else() */
|
||||
if (ixEthAccMiiWriteRtn(phyAddr,
|
||||
IX_ETH_MII_CTRL_REG,
|
||||
regval) == IX_ETH_ACC_SUCCESS)
|
||||
{
|
||||
return IX_SUCCESS;
|
||||
}
|
||||
} /* end of if(phyAddr) */
|
||||
return IX_FAIL;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
*
|
||||
* Enable the PHY Loopback at the specified address
|
||||
*/
|
||||
PUBLIC IX_STATUS
|
||||
ixEthMiiPhyLoopbackEnable (UINT32 phyAddr)
|
||||
{
|
||||
UINT16 regval ;
|
||||
|
||||
if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) &&
|
||||
(IX_ETH_MII_INVALID_PHY_ID != ixEthMiiPhyId[phyAddr]))
|
||||
{
|
||||
/* read/write the control register */
|
||||
if(ixEthAccMiiReadRtn (phyAddr,
|
||||
IX_ETH_MII_CTRL_REG,
|
||||
®val)
|
||||
== IX_ETH_ACC_SUCCESS)
|
||||
{
|
||||
if(ixEthAccMiiWriteRtn (phyAddr,
|
||||
IX_ETH_MII_CTRL_REG,
|
||||
regval | IX_ETH_MII_CR_LOOPBACK)
|
||||
== IX_ETH_ACC_SUCCESS)
|
||||
{
|
||||
return IX_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
return IX_FAIL;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
*
|
||||
* Disable the PHY Loopback at the specified address
|
||||
*/
|
||||
PUBLIC IX_STATUS
|
||||
ixEthMiiPhyLoopbackDisable (UINT32 phyAddr)
|
||||
{
|
||||
UINT16 regval ;
|
||||
|
||||
if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) &&
|
||||
(IX_ETH_MII_INVALID_PHY_ID != ixEthMiiPhyId[phyAddr]))
|
||||
{
|
||||
/* read/write the control register */
|
||||
if(ixEthAccMiiReadRtn (phyAddr,
|
||||
IX_ETH_MII_CTRL_REG,
|
||||
®val)
|
||||
== IX_ETH_ACC_SUCCESS)
|
||||
{
|
||||
if(ixEthAccMiiWriteRtn (phyAddr,
|
||||
IX_ETH_MII_CTRL_REG,
|
||||
regval & (~IX_ETH_MII_CR_LOOPBACK))
|
||||
== IX_ETH_ACC_SUCCESS)
|
||||
{
|
||||
return IX_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
return IX_FAIL;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
*
|
||||
* Reset the PHY at the specified address
|
||||
*/
|
||||
PUBLIC IX_STATUS
|
||||
ixEthMiiPhyReset(UINT32 phyAddr)
|
||||
{
|
||||
UINT32 timeout;
|
||||
UINT16 regval;
|
||||
|
||||
if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) &&
|
||||
(ixEthMiiPhyId[phyAddr] != IX_ETH_MII_INVALID_PHY_ID))
|
||||
{
|
||||
if ((ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT971_PHY_ID) ||
|
||||
(ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT972_PHY_ID) ||
|
||||
(ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT973_PHY_ID) ||
|
||||
(ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT973A3_PHY_ID) ||
|
||||
(ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT9785_PHY_ID)
|
||||
)
|
||||
{
|
||||
/* use the control register to reset the phy */
|
||||
ixEthAccMiiWriteRtn(phyAddr,
|
||||
IX_ETH_MII_CTRL_REG,
|
||||
IX_ETH_MII_CR_RESET);
|
||||
|
||||
/* poll until the reset bit is cleared */
|
||||
timeout = 0;
|
||||
do
|
||||
{
|
||||
ixOsalSleep (IX_ETH_MII_RESET_POLL_MS);
|
||||
|
||||
/* read the control register and check for timeout */
|
||||
ixEthAccMiiReadRtn(phyAddr,
|
||||
IX_ETH_MII_CTRL_REG,
|
||||
®val);
|
||||
if ((regval & IX_ETH_MII_CR_RESET) == 0)
|
||||
{
|
||||
/* timeout bit is self-cleared */
|
||||
break;
|
||||
}
|
||||
timeout += IX_ETH_MII_RESET_POLL_MS;
|
||||
}
|
||||
while (timeout < IX_ETH_MII_RESET_DELAY_MS);
|
||||
|
||||
/* check for timeout */
|
||||
if (timeout >= IX_ETH_MII_RESET_DELAY_MS)
|
||||
{
|
||||
ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG,
|
||||
IX_ETH_MII_CR_NORM_EN);
|
||||
return IX_FAIL;
|
||||
}
|
||||
|
||||
return IX_SUCCESS;
|
||||
} /* end of if(ixEthMiiPhyId) */
|
||||
else if (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_KS8995_PHY_ID)
|
||||
{
|
||||
/* reset bit is reserved, just reset the control register */
|
||||
ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG,
|
||||
IX_ETH_MII_CR_NORM_EN);
|
||||
return IX_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* unknown PHY, set the control register reset bit,
|
||||
* wait 2 s. and clear the control register.
|
||||
*/
|
||||
ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG,
|
||||
IX_ETH_MII_CR_RESET);
|
||||
|
||||
ixOsalSleep (IX_ETH_MII_RESET_DELAY_MS);
|
||||
|
||||
ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG,
|
||||
IX_ETH_MII_CR_NORM_EN);
|
||||
return IX_SUCCESS;
|
||||
} /* end of if-else(ixEthMiiPhyId) */
|
||||
} /* end of if(phyAddr) */
|
||||
return IX_FAIL;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
*
|
||||
* Link state query functions
|
||||
*/
|
||||
|
||||
PUBLIC IX_STATUS
|
||||
ixEthMiiLinkStatus(UINT32 phyAddr,
|
||||
BOOL *linkUp,
|
||||
BOOL *speed100,
|
||||
BOOL *fullDuplex,
|
||||
BOOL *autoneg)
|
||||
{
|
||||
UINT16 ctrlRegval, statRegval, regval, regval4, regval5;
|
||||
|
||||
/* check the parameters */
|
||||
if ((linkUp == NULL) ||
|
||||
(speed100 == NULL) ||
|
||||
(fullDuplex == NULL) ||
|
||||
(autoneg == NULL))
|
||||
{
|
||||
return IX_FAIL;
|
||||
}
|
||||
|
||||
*linkUp = false;
|
||||
*speed100 = false;
|
||||
*fullDuplex = false;
|
||||
*autoneg = false;
|
||||
|
||||
if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) &&
|
||||
(ixEthMiiPhyId[phyAddr] != IX_ETH_MII_INVALID_PHY_ID))
|
||||
{
|
||||
if ((ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT971_PHY_ID) ||
|
||||
(ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT972_PHY_ID) ||
|
||||
(ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT9785_PHY_ID)
|
||||
)
|
||||
{
|
||||
/* --------------------------------------------------*/
|
||||
/* Retrieve information from PHY specific register */
|
||||
/* --------------------------------------------------*/
|
||||
if (ixEthAccMiiReadRtn(phyAddr,
|
||||
IX_ETH_MII_STAT2_REG,
|
||||
®val) != IX_ETH_ACC_SUCCESS)
|
||||
{
|
||||
return IX_FAIL;
|
||||
}
|
||||
*linkUp = ((regval & IX_ETH_MII_SR2_LINK) != 0);
|
||||
*speed100 = ((regval & IX_ETH_MII_SR2_100) != 0);
|
||||
*fullDuplex = ((regval & IX_ETH_MII_SR2_FD) != 0);
|
||||
*autoneg = ((regval & IX_ETH_MII_SR2_AUTO) != 0);
|
||||
return IX_SUCCESS;
|
||||
} /* end of if(ixEthMiiPhyId) */
|
||||
else
|
||||
{
|
||||
/* ----------------------------------------------------*/
|
||||
/* Retrieve information from status and ctrl registers */
|
||||
/* ----------------------------------------------------*/
|
||||
if (ixEthAccMiiReadRtn(phyAddr,
|
||||
IX_ETH_MII_CTRL_REG,
|
||||
&ctrlRegval) != IX_ETH_ACC_SUCCESS)
|
||||
{
|
||||
return IX_FAIL;
|
||||
}
|
||||
ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_STAT_REG, &statRegval);
|
||||
|
||||
*linkUp = ((statRegval & IX_ETH_MII_SR_LINK_STATUS) != 0);
|
||||
if (*linkUp)
|
||||
{
|
||||
*autoneg = ((ctrlRegval & IX_ETH_MII_CR_AUTO_EN) != 0) &&
|
||||
((statRegval & IX_ETH_MII_SR_AUTO_SEL) != 0) &&
|
||||
((statRegval & IX_ETH_MII_SR_AUTO_NEG) != 0);
|
||||
|
||||
if (*autoneg)
|
||||
{
|
||||
/* mask the current stat values with the capabilities */
|
||||
ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_AN_ADS_REG, ®val4);
|
||||
ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_AN_PRTN_REG, ®val5);
|
||||
/* merge the flags from the 3 registers */
|
||||
regval = (statRegval & ((regval4 & regval5) << 6));
|
||||
/* initialise from status register values */
|
||||
if ((regval & IX_ETH_MII_SR_TX_FULL_DPX) != 0)
|
||||
{
|
||||
/* 100 Base X full dplx */
|
||||
*speed100 = true;
|
||||
*fullDuplex = true;
|
||||
return IX_SUCCESS;
|
||||
}
|
||||
if ((regval & IX_ETH_MII_SR_TX_HALF_DPX) != 0)
|
||||
{
|
||||
/* 100 Base X half dplx */
|
||||
*speed100 = true;
|
||||
return IX_SUCCESS;
|
||||
}
|
||||
if ((regval & IX_ETH_MII_SR_10T_FULL_DPX) != 0)
|
||||
{
|
||||
/* 10 mb full dplx */
|
||||
*fullDuplex = true;
|
||||
return IX_SUCCESS;
|
||||
}
|
||||
if ((regval & IX_ETH_MII_SR_10T_HALF_DPX) != 0)
|
||||
{
|
||||
/* 10 mb half dplx */
|
||||
return IX_SUCCESS;
|
||||
}
|
||||
} /* end of if(autoneg) */
|
||||
else
|
||||
{
|
||||
/* autonegotiate not complete, return setup parameters */
|
||||
*speed100 = ((ctrlRegval & IX_ETH_MII_CR_100) != 0);
|
||||
*fullDuplex = ((ctrlRegval & IX_ETH_MII_CR_FDX) != 0);
|
||||
}
|
||||
} /* end of if(linkUp) */
|
||||
} /* end of if-else(ixEthMiiPhyId) */
|
||||
} /* end of if(phyAddr) */
|
||||
else
|
||||
{
|
||||
return IX_FAIL;
|
||||
} /* end of if-else(phyAddr) */
|
||||
return IX_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
*
|
||||
* Link state display functions
|
||||
*/
|
||||
|
||||
PUBLIC IX_STATUS
|
||||
ixEthMiiPhyShow (UINT32 phyAddr)
|
||||
{
|
||||
BOOL linkUp, speed100, fullDuplex, autoneg;
|
||||
UINT16 cregval;
|
||||
UINT16 sregval;
|
||||
|
||||
|
||||
ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_STAT_REG, &sregval);
|
||||
ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_CTRL_REG, &cregval);
|
||||
|
||||
/* get link information */
|
||||
if (ixEthMiiLinkStatus(phyAddr,
|
||||
&linkUp,
|
||||
&speed100,
|
||||
&fullDuplex,
|
||||
&autoneg) != IX_ETH_ACC_SUCCESS)
|
||||
{
|
||||
printf("PHY Status unknown\n");
|
||||
return IX_FAIL;
|
||||
}
|
||||
|
||||
printf("PHY ID [phyAddr]: %8.8x\n",ixEthMiiPhyId[phyAddr]);
|
||||
printf( " Status reg: %4.4x\n",sregval);
|
||||
printf( " control reg: %4.4x\n",cregval);
|
||||
/* display link information */
|
||||
printf("PHY Status:\n");
|
||||
printf(" Link is %s\n",
|
||||
(linkUp ? "Up" : "Down"));
|
||||
if((sregval & IX_ETH_MII_SR_REMOTE_FAULT) != 0)
|
||||
{
|
||||
printf(" Remote fault detected\n");
|
||||
}
|
||||
printf(" Auto Negotiation %s\n",
|
||||
(autoneg ? "Completed" : "Not Completed"));
|
||||
|
||||
printf("PHY Configuration:\n");
|
||||
printf(" Speed %sMb/s\n",
|
||||
(speed100 ? "100" : "10"));
|
||||
printf(" %s Duplex\n",
|
||||
(fullDuplex ? "Full" : "Half"));
|
||||
printf(" Auto Negotiation %s\n",
|
||||
(autoneg ? "Enabled" : "Disabled"));
|
||||
return IX_SUCCESS;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue