* Update Intel IXP4xx support

- Add IXP4xx NPE ethernet MAC support
- Add support for Intel IXDPG425 board
- Add support for Prodrive PDNB3 board
- Add IRQ support
Patch by Stefan Roese, 23 May 2006

[This patch does not include cpu/ixp/npe/IxNpeMicrocode.c which still
 sufferes from licensing issues. Blame Intel.]
This commit is contained in:
Wolfgang Denk 2006-05-30 15:56:48 +02:00
parent 5770a1e488
commit ba94a1bba3
185 changed files with 74593 additions and 74 deletions

View file

@ -2,6 +2,13 @@
Changes since U-Boot 1.1.4:
======================================================================
* Update Intel IXP4xx support
- Add IXP4xx NPE ethernet MAC support
- Add support for Intel IXDPG425 board
- Add support for Prodrive PDNB3 board
- Add IRQ support
Patch by Stefan Roese, 23 May 2006
* Fix problem in PVR detection for 440GR
Patch by Stefan Roese, 18 May 2006

View file

@ -434,6 +434,11 @@ Dave Peverley <dpeverley@mpc-data.co.uk>
omap730p2 ARM926EJS
Stefan Roese <sr@denx.de>
ixdpg425 xscale
pdnb3 xscale
Robert Schwebel <r.schwebel@pengutronix.de>
csb226 xscale

View file

@ -209,7 +209,7 @@ LIST_pxa=" \
zylonite \
"
LIST_ixp="ixdp425"
LIST_ixp="ixdp425 ixdpg425 pdnb3"
LIST_arm=" \

View file

@ -1708,12 +1708,18 @@ innokom_config : unconfig
ixdp425_config : unconfig
@./mkconfig $(@:_config=) arm ixp ixdp425
ixdpg425_config : unconfig
@./mkconfig $(@:_config=) arm ixp ixdp425
lubbock_config : unconfig
@./mkconfig $(@:_config=) arm pxa lubbock
logodl_config : unconfig
@./mkconfig $(@:_config=) arm pxa logodl
pdnb3_config : unconfig
@./mkconfig $(@:_config=) arm ixp pdnb3 prodrive
pxa255_idp_config: unconfig
@./mkconfig $(@:_config=) arm pxa pxa255_idp

View file

@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk
LIB = lib$(BOARD).a
OBJS := ixdp425.o flash.o
OBJS := ixdp425.o
$(LIB): $(OBJS) $(SOBJS)
$(AR) crv $@ $^

View file

@ -1,2 +1,4 @@
#TEXT_BASE = 0x00100000
TEXT_BASE = 0x00f80000
# include NPE ethernet driver
BOARDLIBS = cpu/ixp/npe/libnpe.a

View file

@ -1,4 +1,7 @@
/*
* (C) Copyright 2006
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* (C) Copyright 2002
* Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
*
@ -25,24 +28,21 @@
* MA 02111-1307 USA
*/
#include <asm/arch/ixp425.h>
#include <common.h>
#include <command.h>
#include <malloc.h>
#include <asm/arch/ixp425.h>
DECLARE_GLOBAL_DATA_PTR;
/*
* Miscelaneous platform dependent initialisations
*/
/**********************************************************/
int board_post_init (void)
{
return (0);
}
/**********************************************************/
int board_init (void)
{
/* arch number of IXDP */
@ -51,10 +51,58 @@ int board_init (void)
/* adress of boot parameters */
gd->bd->bi_boot_params = 0x00000100;
#ifdef CONFIG_IXDPG425
/* arch number of IXDP */
gd->bd->bi_arch_number = MACH_TYPE_IXDPG425;
/*
* Get realtek RTL8305 switch and SLIC out of reset
*/
GPIO_OUTPUT_SET(CFG_GPIO_SWITCH_RESET_N);
GPIO_OUTPUT_ENABLE(CFG_GPIO_SWITCH_RESET_N);
GPIO_OUTPUT_SET(CFG_GPIO_SLIC_RESET_N);
GPIO_OUTPUT_ENABLE(CFG_GPIO_SLIC_RESET_N);
/*
* Setup GPIO's for PCI INTA & INTB
*/
GPIO_OUTPUT_DISABLE(CFG_GPIO_PCI_INTA_N);
GPIO_INT_ACT_LOW_SET(CFG_GPIO_PCI_INTA_N);
GPIO_OUTPUT_DISABLE(CFG_GPIO_PCI_INTB_N);
GPIO_INT_ACT_LOW_SET(CFG_GPIO_PCI_INTB_N);
/*
* Setup GPIO's for 33MHz clock output
*/
*IXP425_GPIO_GPCLKR = 0x01FF01FF;
GPIO_OUTPUT_ENABLE(CFG_GPIO_PCI_CLK);
GPIO_OUTPUT_ENABLE(CFG_GPIO_EXTBUS_CLK);
#endif
return 0;
}
/**********************************************************/
/*
* Check Board Identity
*/
int checkboard(void)
{
char *s = getenv("serial#");
#ifdef CONFIG_IXDPG425
puts("Board: IXDPG425 - Intel Network Gateway Reference Platform");
#else
puts("Board: IXDP425 - Intel Development Platform");
#endif
if (s != NULL) {
puts(", serial# ");
puts(s);
}
putc('\n');
return (0);
}
int dram_init (void)
{
@ -64,8 +112,7 @@ int dram_init (void)
return (0);
}
/**********************************************************/
#if (CONFIG_COMMANDS & CFG_CMD_PCI) || defined(CONFIG_PCI)
extern struct pci_controller hose;
extern void pci_ixp_init(struct pci_controller * hose);
@ -75,3 +122,4 @@ void pci_init_board(void)
pci_ixp_init(&hose);
}
#endif

View file

@ -0,0 +1,556 @@
/*
* (C) Copyright 2006
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <asm/processor.h>
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
/*
* Functions
*/
static int write_word(flash_info_t *info, ulong dest, ulong data);
void flash_print_info(flash_info_t *info)
{
int i;
int k;
int size;
int erased;
volatile unsigned long *flash;
if (info->flash_id == FLASH_UNKNOWN) {
printf ("missing or unknown FLASH type\n");
return;
}
switch (info->flash_id & FLASH_VENDMASK) {
case FLASH_MAN_AMD: printf ("AMD "); break;
case FLASH_MAN_FUJ: printf ("FUJITSU "); break;
case FLASH_MAN_SST: printf ("SST "); break;
case FLASH_MAN_EXCEL: printf ("Excel Semiconductor "); break;
default: printf ("Unknown Vendor "); break;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_AM400B: printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
break;
case FLASH_AM400T: printf ("AM29LV400T (4 Mbit, top boot sector)\n");
break;
case FLASH_AM800B: printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
break;
case FLASH_AM800T: printf ("AM29LV800T (8 Mbit, top boot sector)\n");
break;
case FLASH_AM160B: printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
break;
case FLASH_AM160T: printf ("AM29LV160T (16 Mbit, top boot sector)\n");
break;
case FLASH_AM320T: printf ("AM29LV320T (32 M, top sector)\n");
break;
case FLASH_AM320B: printf ("AM29LV320B (32 M, bottom sector)\n");
break;
case FLASH_AMDL322T: printf ("AM29DL322T (32 M, top sector)\n");
break;
case FLASH_AMDL322B: printf ("AM29DL322B (32 M, bottom sector)\n");
break;
case FLASH_AMDL323T: printf ("AM29DL323T (32 M, top sector)\n");
break;
case FLASH_AMDL323B: printf ("AM29DL323B (32 M, bottom sector)\n");
break;
case FLASH_SST020: printf ("SST39LF/VF020 (2 Mbit, uniform sector size)\n");
break;
case FLASH_SST040: printf ("SST39LF/VF040 (4 Mbit, uniform sector size)\n");
break;
default: printf ("Unknown Chip Type\n");
break;
}
printf (" Size: %ld MB in %d Sectors\n",
info->size >> 20, info->sector_count);
printf (" Sector Start Addresses:");
for (i=0; i<info->sector_count; ++i) {
#ifdef CFG_FLASH_EMPTY_INFO
/*
* Check if whole sector is erased
*/
if (i != (info->sector_count-1))
size = info->start[i+1] - info->start[i];
else
size = info->start[0] + info->size - info->start[i];
erased = 1;
flash = (volatile unsigned long *)info->start[i];
size = size >> 2; /* divide by 4 for longword access */
for (k=0; k<size; k++) {
if (*flash++ != 0xffffffff) {
erased = 0;
break;
}
}
if ((i % 5) == 0)
printf ("\n ");
/* print empty and read-only info */
printf (" %08lX%s%s",
info->start[i],
erased ? " E" : " ",
info->protect[i] ? "RO " : " ");
#else
if ((i % 5) == 0)
printf ("\n ");
printf (" %08lX%s",
info->start[i],
info->protect[i] ? " (RO)" : " ");
#endif
}
printf ("\n");
return;
}
/*
* The following code cannot be run from FLASH!
*/
static ulong flash_get_size(vu_long *addr, flash_info_t *info)
{
short i;
short n;
CFG_FLASH_WORD_SIZE value;
ulong base = (ulong)addr;
volatile CFG_FLASH_WORD_SIZE *addr2 = (CFG_FLASH_WORD_SIZE *)addr;
/* Write auto select command: read Manufacturer ID */
addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA00AA;
addr2[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x00550055;
addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00900090;
value = addr2[CFG_FLASH_READ0];
switch (value) {
case (CFG_FLASH_WORD_SIZE)AMD_MANUFACT:
info->flash_id = FLASH_MAN_AMD;
break;
case (CFG_FLASH_WORD_SIZE)FUJ_MANUFACT:
info->flash_id = FLASH_MAN_FUJ;
break;
case (CFG_FLASH_WORD_SIZE)SST_MANUFACT:
info->flash_id = FLASH_MAN_SST;
break;
case (CFG_FLASH_WORD_SIZE)EXCEL_MANUFACT:
info->flash_id = FLASH_MAN_EXCEL;
break;
default:
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
return (0); /* no or unknown flash */
}
value = addr2[CFG_FLASH_READ1]; /* device ID */
switch (value) {
case (CFG_FLASH_WORD_SIZE)AMD_ID_LV400T:
info->flash_id += FLASH_AM400T;
info->sector_count = 11;
info->size = 0x00080000;
break; /* => 0.5 MB */
case (CFG_FLASH_WORD_SIZE)AMD_ID_LV400B:
info->flash_id += FLASH_AM400B;
info->sector_count = 11;
info->size = 0x00080000;
break; /* => 0.5 MB */
case (CFG_FLASH_WORD_SIZE)AMD_ID_LV800T:
info->flash_id += FLASH_AM800T;
info->sector_count = 19;
info->size = 0x00100000;
break; /* => 1 MB */
case (CFG_FLASH_WORD_SIZE)AMD_ID_LV800B:
info->flash_id += FLASH_AM800B;
info->sector_count = 19;
info->size = 0x00100000;
break; /* => 1 MB */
case (CFG_FLASH_WORD_SIZE)AMD_ID_LV160T:
info->flash_id += FLASH_AM160T;
info->sector_count = 35;
info->size = 0x00200000;
break; /* => 2 MB */
case (CFG_FLASH_WORD_SIZE)AMD_ID_LV160B:
info->flash_id += FLASH_AM160B;
info->sector_count = 35;
info->size = 0x00200000;
break; /* => 2 MB */
case (CFG_FLASH_WORD_SIZE)AMD_ID_LV320T:
info->flash_id += FLASH_AM320T;
info->sector_count = 71;
info->size = 0x00400000; break; /* => 4 MB */
case (CFG_FLASH_WORD_SIZE)AMD_ID_LV320B:
info->flash_id += FLASH_AM320B;
info->sector_count = 71;
info->size = 0x00400000; break; /* => 4 MB */
case (CFG_FLASH_WORD_SIZE)AMD_ID_DL322T:
info->flash_id += FLASH_AMDL322T;
info->sector_count = 71;
info->size = 0x00400000; break; /* => 4 MB */
case (CFG_FLASH_WORD_SIZE)AMD_ID_DL322B:
info->flash_id += FLASH_AMDL322B;
info->sector_count = 71;
info->size = 0x00400000; break; /* => 4 MB */
case (CFG_FLASH_WORD_SIZE)AMD_ID_DL323T:
info->flash_id += FLASH_AMDL323T;
info->sector_count = 71;
info->size = 0x00400000; break; /* => 4 MB */
case (CFG_FLASH_WORD_SIZE)AMD_ID_DL323B:
info->flash_id += FLASH_AMDL323B;
info->sector_count = 71;
info->size = 0x00400000; break; /* => 4 MB */
case (CFG_FLASH_WORD_SIZE)SST_ID_xF020:
info->flash_id += FLASH_SST020;
info->sector_count = 64;
info->size = 0x00040000;
break; /* => 256 kB */
case (CFG_FLASH_WORD_SIZE)SST_ID_xF040:
info->flash_id += FLASH_SST040;
info->sector_count = 128;
info->size = 0x00080000;
break; /* => 512 kB */
default:
info->flash_id = FLASH_UNKNOWN;
return (0); /* => no or unknown flash */
}
/* set up sector start address table */
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) {
for (i = 0; i < info->sector_count; i++)
info->start[i] = base + (i * 0x00001000);
} else if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL322B) ||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL323B) ||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) ||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL324B)) {
/* set sector offsets for bottom boot block type */
for (i=0; i<8; ++i) { /* 8 x 8k boot sectors */
info->start[i] = base;
base += 8 << 10;
}
while (i < info->sector_count) { /* 64k regular sectors */
info->start[i] = base;
base += 64 << 10;
++i;
}
} else if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL322T) ||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL323T) ||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320T) ||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL324T)) {
/* set sector offsets for top boot block type */
base += info->size;
i = info->sector_count;
for (n=0; n<8; ++n) { /* 8 x 8k boot sectors */
base -= 8 << 10;
--i;
info->start[i] = base;
}
while (i > 0) { /* 64k regular sectors */
base -= 64 << 10;
--i;
info->start[i] = base;
}
} else {
if (info->flash_id & FLASH_BTYPE) {
/* set sector offsets for bottom boot block type */
info->start[0] = base + 0x00000000;
info->start[1] = base + 0x00004000;
info->start[2] = base + 0x00006000;
info->start[3] = base + 0x00008000;
for (i = 4; i < info->sector_count; i++) {
info->start[i] = base + (i * 0x00010000) - 0x00030000;
}
} else {
/* set sector offsets for top boot block type */
i = info->sector_count - 1;
info->start[i--] = base + info->size - 0x00004000;
info->start[i--] = base + info->size - 0x00006000;
info->start[i--] = base + info->size - 0x00008000;
for (; i >= 0; i--) {
info->start[i] = base + i * 0x00010000;
}
}
}
/* check for protected sectors */
for (i = 0; i < info->sector_count; i++) {
/* read sector protection at sector address, (A7 .. A0) = 0x02 */
/* D0 = 1 if protected */
addr2 = (volatile CFG_FLASH_WORD_SIZE *)(info->start[i]);
if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_AMD)
info->protect[i] = 0;
else
info->protect[i] = addr2[CFG_FLASH_READ2] & 1;
}
/*
* Prevent writes to uninitialized FLASH.
*/
if (info->flash_id != FLASH_UNKNOWN) {
addr2 = (CFG_FLASH_WORD_SIZE *)info->start[0];
*addr2 = (CFG_FLASH_WORD_SIZE)0x00F000F0; /* reset bank */
}
return (info->size);
}
int flash_erase(flash_info_t *info, int s_first, int s_last)
{
volatile CFG_FLASH_WORD_SIZE *addr = (CFG_FLASH_WORD_SIZE *)(info->start[0]);
volatile CFG_FLASH_WORD_SIZE *addr2;
int flag, prot, sect, l_sect;
ulong start, now, last;
if ((s_first < 0) || (s_first > s_last)) {
if (info->flash_id == FLASH_UNKNOWN)
printf ("- missing\n");
else
printf ("- no sectors to erase\n");
return 1;
}
if (info->flash_id == FLASH_UNKNOWN) {
printf ("Can't erase unknown flash type - aborted\n");
return 1;
}
prot = 0;
for (sect=s_first; sect<=s_last; ++sect)
if (info->protect[sect])
prot++;
if (prot)
printf ("- Warning: %d protected sectors will not be erased!\n", prot);
else
printf ("\n");
l_sect = -1;
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
/* Start erase on unprotected sectors */
for (sect = s_first; sect<=s_last; sect++) {
if (info->protect[sect] == 0) { /* not protected */
addr2 = (CFG_FLASH_WORD_SIZE *)(info->start[sect]);
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) {
addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA00AA;
addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x00550055;
addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00800080;
addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA00AA;
addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x00550055;
addr2[0] = (CFG_FLASH_WORD_SIZE)0x00300030; /* sector erase */
/* re-enable interrupts if necessary */
if (flag) {
enable_interrupts();
flag = 0;
}
/* data polling for D7 */
start = get_timer (0);
while ((addr2[0] & (CFG_FLASH_WORD_SIZE)0x00800080) !=
(CFG_FLASH_WORD_SIZE)0x00800080) {
if (get_timer(start) > CFG_FLASH_WRITE_TOUT)
return (1);
}
} else {
if (sect == s_first) {
addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA00AA;
addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x00550055;
addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00800080;
addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA00AA;
addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x00550055;
}
addr2[0] = (CFG_FLASH_WORD_SIZE)0x00300030; /* sector erase */
}
l_sect = sect;
}
}
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
/* wait at least 80us - let's wait 1 ms */
udelay (1000);
/*
* We wait for the last triggered sector
*/
if (l_sect < 0)
goto DONE;
start = get_timer (0);
last = start;
addr = (CFG_FLASH_WORD_SIZE *)(info->start[l_sect]);
while ((addr[0] & (CFG_FLASH_WORD_SIZE)0x00800080) != (CFG_FLASH_WORD_SIZE)0x00800080) {
if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
printf ("Timeout\n");
return 1;
}
/* show that we're waiting */
if ((now - last) > 1000) { /* every second */
putc ('.');
last = now;
}
}
DONE:
/* reset to read mode */
addr = (CFG_FLASH_WORD_SIZE *)info->start[0];
addr[0] = (CFG_FLASH_WORD_SIZE)0x00F000F0; /* reset bank */
printf (" done\n");
return 0;
}
/*
* Copy memory to flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
{
ulong cp, wp, data;
int i, l, rc;
wp = (addr & ~3); /* get lower word aligned address */
/*
* handle unaligned start bytes
*/
if ((l = addr - wp) != 0) {
data = 0;
for (i=0, cp=wp; i<l; ++i, ++cp) {
data = (data << 8) | (*(uchar *)cp);
}
for (; i<4 && cnt>0; ++i) {
data = (data << 8) | *src++;
--cnt;
++cp;
}
for (; cnt==0 && i<4; ++i, ++cp) {
data = (data << 8) | (*(uchar *)cp);
}
if ((rc = write_word(info, wp, data)) != 0) {
return (rc);
}
wp += 4;
}
/*
* handle word aligned part
*/
while (cnt >= 4) {
data = 0;
for (i=0; i<4; ++i)
data = (data << 8) | *src++;
if ((rc = write_word(info, wp, data)) != 0)
return (rc);
wp += 4;
cnt -= 4;
}
if (cnt == 0)
return (0);
/*
* handle unaligned tail bytes
*/
data = 0;
for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
data = (data << 8) | *src++;
--cnt;
}
for (; i<4; ++i, ++cp)
data = (data << 8) | (*(uchar *)cp);
return (write_word(info, wp, data));
}
/*
* Write a word to Flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
static int write_word(flash_info_t *info, ulong dest, ulong data)
{
volatile CFG_FLASH_WORD_SIZE *addr2 = (CFG_FLASH_WORD_SIZE *)(info->start[0]);
volatile CFG_FLASH_WORD_SIZE *dest2 = (CFG_FLASH_WORD_SIZE *)dest;
volatile CFG_FLASH_WORD_SIZE *data2 = (CFG_FLASH_WORD_SIZE *)&data;
ulong start;
int flag;
int i;
/* Check if Flash is (sufficiently) erased */
if ((*((vu_long *)dest) & data) != data)
return (2);
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
for (i=0; i<4/sizeof(CFG_FLASH_WORD_SIZE); i++) {
addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA00AA;
addr2[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x00550055;
addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00A000A0;
dest2[i] = data2[i];
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
/* data polling for D7 */
start = get_timer (0);
while ((dest2[i] & (CFG_FLASH_WORD_SIZE)0x00800080) !=
(data2[i] & (CFG_FLASH_WORD_SIZE)0x00800080)) {
if (get_timer(start) > CFG_FLASH_WRITE_TOUT)
return (1);
}
}
return (0);
}

View file

@ -0,0 +1,183 @@
/*
* (C) Copyright 2006
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* (C) Copyright 2001-2004
* Matthias Fuchs, esd gmbh germany, matthias.fuchs@esd-electronics.com
* Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <asm/processor.h>
#include <command.h>
/* ------------------------------------------------------------------------- */
#ifdef FPGA_DEBUG
#define DBG(x...) printf(x)
#else
#define DBG(x...)
#endif /* DEBUG */
#define FPGA_PRG CFG_FPGA_PRG /* FPGA program pin (cpu output)*/
#define FPGA_CLK CFG_FPGA_CLK /* FPGA clk pin (cpu output) */
#define FPGA_DATA CFG_FPGA_DATA /* FPGA data pin (cpu output) */
#define FPGA_DONE CFG_FPGA_DONE /* FPGA done pin (cpu input) */
#define FPGA_INIT CFG_FPGA_INIT /* FPGA init pin (cpu input) */
#define ERROR_FPGA_PRG_INIT_LOW -1 /* Timeout after PRG* asserted */
#define ERROR_FPGA_PRG_INIT_HIGH -2 /* Timeout after PRG* deasserted */
#define ERROR_FPGA_PRG_DONE -3 /* Timeout after programming */
#ifndef OLD_VAL
# define OLD_VAL 0
#endif
#if 0 /* test-only */
#define FPGA_WRITE_1 { \
SET_FPGA(OLD_VAL | FPGA_PRG | 0 | FPGA_DATA); /* set clock to 0 */ \
SET_FPGA(OLD_VAL | FPGA_PRG | 0 | FPGA_DATA); /* set data to 1 */ \
SET_FPGA(OLD_VAL | FPGA_PRG | FPGA_CLK | FPGA_DATA); /* set clock to 1 */ \
SET_FPGA(OLD_VAL | FPGA_PRG | FPGA_CLK | FPGA_DATA);} /* set data to 1 */
#define FPGA_WRITE_0 { \
SET_FPGA(OLD_VAL | FPGA_PRG | 0 | FPGA_DATA); /* set clock to 0 */ \
SET_FPGA(OLD_VAL | FPGA_PRG | 0 | 0 ); /* set data to 0 */ \
SET_FPGA(OLD_VAL | FPGA_PRG | FPGA_CLK | 0 ); /* set clock to 1 */ \
SET_FPGA(OLD_VAL | FPGA_PRG | FPGA_CLK | FPGA_DATA);} /* set data to 1 */
#else
#define FPGA_WRITE_1 { \
SET_FPGA(OLD_VAL | FPGA_PRG | 0 | FPGA_DATA); /* set data to 1 */ \
SET_FPGA(OLD_VAL | FPGA_PRG | FPGA_CLK | FPGA_DATA);} /* set data to 1 */
#define FPGA_WRITE_0 { \
SET_FPGA(OLD_VAL | FPGA_PRG | 0 | 0 ); /* set data to 0 */ \
SET_FPGA(OLD_VAL | FPGA_PRG | FPGA_CLK | 0 );} /* set data to 1 */
#endif
static int fpga_boot(unsigned char *fpgadata, int size)
{
int i,index,len;
int count;
int j;
/* display infos on fpgaimage */
index = 15;
for (i=0; i<4; i++) {
len = fpgadata[index];
DBG("FPGA: %s\n", &(fpgadata[index+1]));
index += len+3;
}
/* search for preamble 0xFFFFFFFF */
while (1) {
if ((fpgadata[index] == 0xff) && (fpgadata[index+1] == 0xff) &&
(fpgadata[index+2] == 0xff) && (fpgadata[index+3] == 0xff))
break; /* preamble found */
else
index++;
}
DBG("FPGA: configdata starts at position 0x%x\n",index);
DBG("FPGA: length of fpga-data %d\n", size-index);
/*
* Setup port pins for fpga programming
*/
SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA); /* set pins to high */
DBG("%s, ",(FPGA_DONE_STATE == 0) ? "NOT DONE" : "DONE" );
DBG("%s\n",(FPGA_INIT_STATE == 0) ? "NOT INIT" : "INIT" );
/*
* Init fpga by asserting and deasserting PROGRAM*
*/
SET_FPGA(0 | FPGA_CLK | FPGA_DATA); /* set prog active */
/* Wait for FPGA init line low */
count = 0;
while (FPGA_INIT_STATE) {
udelay(1000); /* wait 1ms */
/* Check for timeout - 100us max, so use 3ms */
if (count++ > 3) {
DBG("FPGA: Booting failed!\n");
return ERROR_FPGA_PRG_INIT_LOW;
}
}
DBG("%s, ",(FPGA_DONE_STATE == 0) ? "NOT DONE" : "DONE" );
DBG("%s\n",(FPGA_INIT_STATE == 0) ? "NOT INIT" : "INIT" );
/* deassert PROGRAM* */
SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA); /* set prog inactive */
/* Wait for FPGA end of init period . */
count = 0;
while (!(FPGA_INIT_STATE)) {
udelay(1000); /* wait 1ms */
/* Check for timeout */
if (count++ > 3) {
DBG("FPGA: Booting failed!\n");
return ERROR_FPGA_PRG_INIT_HIGH;
}
}
DBG("%s, ",(FPGA_DONE_STATE == 0) ? "NOT DONE" : "DONE" );
DBG("%s\n",(FPGA_INIT_STATE == 0) ? "NOT INIT" : "INIT" );
DBG("write configuration data into fpga\n");
/* write configuration-data into fpga... */
/*
* Load uncompressed image into fpga
*/
for (i=index; i<size; i++) {
for (j=0; j<8; j++) {
if ((fpgadata[i] & 0x80) == 0x80) {
FPGA_WRITE_1;
} else {
FPGA_WRITE_0;
}
fpgadata[i] <<= 1;
}
}
DBG("%s, ",(FPGA_DONE_STATE == 0) ? "NOT DONE" : "DONE" );
DBG("%s\n",(FPGA_INIT_STATE == 0) ? "NOT INIT" : "INIT" );
/*
* Check if fpga's DONE signal - correctly booted ?
*/
/* Wait for FPGA end of programming period . */
count = 0;
while (!(FPGA_DONE_STATE)) {
udelay(1000); /* wait 1ms */
/* Check for timeout */
if (count++ > 3) {
DBG("FPGA: Booting failed!\n");
return ERROR_FPGA_PRG_DONE;
}
}
DBG("FPGA: Booting successful!\n");
return 0;
}

View file

@ -0,0 +1,46 @@
#
# (C) Copyright 2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
include $(TOPDIR)/config.mk
LIB = lib$(BOARD).a
OBJS := flash.o pdnb3.o nand.o
$(LIB): $(OBJS) $(SOBJS)
$(AR) crv $@ $^
clean:
rm -f $(SOBJS) $(OBJS)
distclean: clean
rm -f $(LIB) core *.bak .depend
#########################################################################
.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
$(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
-include .depend
#########################################################################

View file

@ -0,0 +1,4 @@
TEXT_BASE = 0x01f00000
# include NPE ethernet driver
BOARDLIBS = cpu/ixp/npe/libnpe.a

View file

@ -0,0 +1,85 @@
/*
* (C) Copyright 2006
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <asm/arch/ixp425.h>
/*
* include common flash code (for esd boards)
*/
#include "../common/flash.c"
/*
* Prototypes
*/
static ulong flash_get_size (vu_long * addr, flash_info_t * info);
static inline ulong ld(ulong x)
{
ulong k = 0;
while (x >>= 1)
++k;
return k;
}
unsigned long flash_init(void)
{
unsigned long size;
int i;
/* Init: no FLASHes known */
for (i=0; i<CFG_MAX_FLASH_BANKS; i++)
flash_info[i].flash_id = FLASH_UNKNOWN;
size = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]);
if (flash_info[0].flash_id == FLASH_UNKNOWN)
printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
size, size<<20);
/* Reconfigure CS0 to actual FLASH size */
*IXP425_EXP_CS0 = (*IXP425_EXP_CS0 & ~0x00003C00) | ((ld(size) - 9) << 10);
/* Monitor protection ON by default */
flash_protect(FLAG_PROTECT_SET,
CFG_MONITOR_BASE, CFG_MONITOR_BASE + monitor_flash_len - 1,
&flash_info[CFG_MAX_FLASH_BANKS - 1]);
/* Environment protection ON by default */
flash_protect(FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR + CFG_ENV_SECT_SIZE - 1,
&flash_info[CFG_MAX_FLASH_BANKS - 1]);
/* Redundant environment protection ON by default */
flash_protect(FLAG_PROTECT_SET,
CFG_ENV_ADDR_REDUND,
CFG_ENV_ADDR_REDUND + CFG_ENV_SIZE_REDUND - 1,
&flash_info[CFG_MAX_FLASH_BANKS - 1]);
flash_info[0].size = size;
return size;
}

171
board/prodrive/pdnb3/nand.c Normal file
View file

@ -0,0 +1,171 @@
/*
* (C) Copyright 2006
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
#include <nand.h>
struct pdnb3_ndfc_regs {
uchar cmd;
uchar wait;
uchar addr;
uchar term;
uchar data;
};
static u8 hwctl;
static struct pdnb3_ndfc_regs *pdnb3_ndfc;
#define readb(addr) *(volatile u_char *)(addr)
#define readl(addr) *(volatile u_long *)(addr)
#define writeb(d,addr) *(volatile u_char *)(addr) = (d)
/*
* The PDNB3 has a NAND Flash Controller (NDFC) that handles all accesses to
* the NAND devices. The NDFC has command, address and data registers that
* when accessed will set up the NAND flash pins appropriately. We'll use the
* hwcontrol function to save the configuration in a global variable.
* We can then use this information in the read and write functions to
* determine which NDFC register to access.
*
* There is one NAND devices on the board, a Hynix HY27US08561A (32 MByte).
*/
static void pdnb3_nand_hwcontrol(struct mtd_info *mtd, int cmd)
{
switch (cmd) {
case NAND_CTL_SETCLE:
hwctl |= 0x1;
break;
case NAND_CTL_CLRCLE:
hwctl &= ~0x1;
break;
case NAND_CTL_SETALE:
hwctl |= 0x2;
break;
case NAND_CTL_CLRALE:
hwctl &= ~0x2;
break;
case NAND_CTL_SETNCE:
break;
case NAND_CTL_CLRNCE:
writeb(0x00, &(pdnb3_ndfc->term));
break;
}
}
static void pdnb3_nand_write_byte(struct mtd_info *mtd, u_char byte)
{
if (hwctl & 0x1)
writeb(byte, &(pdnb3_ndfc->cmd));
else if (hwctl & 0x2)
writeb(byte, &(pdnb3_ndfc->addr));
else
writeb(byte, &(pdnb3_ndfc->data));
}
static u_char pdnb3_nand_read_byte(struct mtd_info *mtd)
{
return readb(&(pdnb3_ndfc->data));
}
static void pdnb3_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
{
int i;
for (i = 0; i < len; i++) {
if (hwctl & 0x1)
writeb(buf[i], &(pdnb3_ndfc->cmd));
else if (hwctl & 0x2)
writeb(buf[i], &(pdnb3_ndfc->addr));
else
writeb(buf[i], &(pdnb3_ndfc->data));
}
}
static void pdnb3_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
{
int i;
if (len % 4) {
for (i = 0; i < len; i++)
buf[i] = readb(&(pdnb3_ndfc->data));
} else {
ulong *ptr = (ulong *)buf;
int count = len >> 2;
for (i = 0; i < count; i++)
*ptr++ = readl(&(pdnb3_ndfc->data));
}
}
static int pdnb3_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
{
int i;
for (i = 0; i < len; i++)
if (buf[i] != readb(&(pdnb3_ndfc->data)))
return i;
return 0;
}
static int pdnb3_nand_dev_ready(struct mtd_info *mtd)
{
volatile u_char val;
/*
* Blocking read to wait for NAND to be ready
*/
val = readb(&(pdnb3_ndfc->wait));
/*
* Return always true
*/
return 1;
}
void board_nand_init(struct nand_chip *nand)
{
pdnb3_ndfc = (struct pdnb3_ndfc_regs *)CFG_NAND_BASE;
nand->eccmode = NAND_ECC_SOFT;
/* Set address of NAND IO lines (Using Linear Data Access Region) */
nand->IO_ADDR_R = (void __iomem *) ((ulong) pdnb3_ndfc + 0x4);
nand->IO_ADDR_W = (void __iomem *) ((ulong) pdnb3_ndfc + 0x4);
/* Reference hardware control function */
nand->hwcontrol = pdnb3_nand_hwcontrol;
/* Set command delay time */
nand->hwcontrol = pdnb3_nand_hwcontrol;
nand->write_byte = pdnb3_nand_write_byte;
nand->read_byte = pdnb3_nand_read_byte;
nand->write_buf = pdnb3_nand_write_buf;
nand->read_buf = pdnb3_nand_read_buf;
nand->verify_buf = pdnb3_nand_verify_buf;
nand->dev_ready = pdnb3_nand_dev_ready;
}
#endif

View file

@ -0,0 +1,249 @@
/*
* (C) Copyright 2006
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <command.h>
#include <malloc.h>
#include <asm/arch/ixp425.h>
DECLARE_GLOBAL_DATA_PTR;
/* Prototypes */
int gunzip(void *, int, unsigned char *, unsigned long *);
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
/* predefine these here for FPGA programming (before including fpga.c) */
#define SET_FPGA(data) *IXP425_GPIO_GPOUTR = (data)
#define FPGA_DONE_STATE (*IXP425_GPIO_GPINR & CFG_FPGA_DONE)
#define FPGA_INIT_STATE (*IXP425_GPIO_GPINR & CFG_FPGA_INIT)
#define OLD_VAL old_val
static unsigned long old_val = 0;
/*
* include common fpga code (for prodrive boards)
*/
#include "../common/fpga.c"
/*
* Miscelaneous platform dependent initialisations
*/
int board_post_init(void)
{
return (0);
}
int board_init(void)
{
/* arch number of PDNB3 */
gd->bd->bi_arch_number = MACH_TYPE_PDNB3;
/* adress of boot parameters */
gd->bd->bi_boot_params = 0x00000100;
GPIO_OUTPUT_SET(CFG_GPIO_FPGA_RESET);
GPIO_OUTPUT_ENABLE(CFG_GPIO_FPGA_RESET);
GPIO_OUTPUT_SET(CFG_GPIO_SYS_RUNNING);
GPIO_OUTPUT_ENABLE(CFG_GPIO_SYS_RUNNING);
/*
* Setup GPIO's for FPGA programming
*/
GPIO_OUTPUT_CLEAR(CFG_GPIO_PRG);
GPIO_OUTPUT_CLEAR(CFG_GPIO_CLK);
GPIO_OUTPUT_CLEAR(CFG_GPIO_DATA);
GPIO_OUTPUT_ENABLE(CFG_GPIO_PRG);
GPIO_OUTPUT_ENABLE(CFG_GPIO_CLK);
GPIO_OUTPUT_ENABLE(CFG_GPIO_DATA);
GPIO_OUTPUT_DISABLE(CFG_GPIO_INIT);
GPIO_OUTPUT_DISABLE(CFG_GPIO_DONE);
/*
* Setup GPIO's for interrupts
*/
GPIO_OUTPUT_DISABLE(CFG_GPIO_PCI_INTA);
GPIO_INT_ACT_LOW_SET(CFG_GPIO_PCI_INTA);
GPIO_OUTPUT_DISABLE(CFG_GPIO_PCI_INTB);
GPIO_INT_ACT_LOW_SET(CFG_GPIO_PCI_INTB);
GPIO_OUTPUT_DISABLE(CFG_GPIO_RESTORE_INT);
GPIO_INT_ACT_LOW_SET(CFG_GPIO_RESTORE_INT);
GPIO_OUTPUT_DISABLE(CFG_GPIO_RESTART_INT);
GPIO_INT_ACT_LOW_SET(CFG_GPIO_RESTART_INT);
/*
* Setup GPIO's for 33MHz clock output
*/
*IXP425_GPIO_GPCLKR = 0x01FF0000;
GPIO_OUTPUT_ENABLE(CFG_GPIO_CLK_33M);
/*
* Setup other chip select's
*/
*IXP425_EXP_CS1 = CFG_EXP_CS1;
return 0;
}
/*
* Check Board Identity
*/
int checkboard(void)
{
char *s = getenv("serial#");
puts("Board: PDNB3");
if (s != NULL) {
puts(", serial# ");
puts(s);
}
putc('\n');
return (0);
}
int dram_init(void)
{
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
return (0);
}
int do_fpga_boot(unsigned char *fpgadata)
{
unsigned char *dst;
int status;
int index;
int i;
ulong len = CFG_MALLOC_LEN;
/*
* Setup GPIO's for FPGA programming
*/
GPIO_OUTPUT_CLEAR(CFG_GPIO_PRG);
GPIO_OUTPUT_CLEAR(CFG_GPIO_CLK);
GPIO_OUTPUT_CLEAR(CFG_GPIO_DATA);
/*
* Save value so no readback is required upon programming
*/
old_val = *IXP425_GPIO_GPOUTR;
/*
* First try to decompress fpga image (gzip compressed?)
*/
dst = malloc(CFG_FPGA_MAX_SIZE);
if (gunzip(dst, CFG_FPGA_MAX_SIZE, (uchar *)fpgadata, &len) != 0) {
printf("Error: Image has to be gzipp'ed!\n");
return -1;
}
status = fpga_boot(dst, len);
if (status != 0) {
printf("\nFPGA: Booting failed ");
switch (status) {
case ERROR_FPGA_PRG_INIT_LOW:
printf("(Timeout: INIT not low after asserting PROGRAM*)\n ");
break;
case ERROR_FPGA_PRG_INIT_HIGH:
printf("(Timeout: INIT not high after deasserting PROGRAM*)\n ");
break;
case ERROR_FPGA_PRG_DONE:
printf("(Timeout: DONE not high after programming FPGA)\n ");
break;
}
/* display infos on fpgaimage */
index = 15;
for (i=0; i<4; i++) {
len = dst[index];
printf("FPGA: %s\n", &(dst[index+1]));
index += len+3;
}
putc ('\n');
/* delayed reboot */
for (i=5; i>0; i--) {
printf("Rebooting in %2d seconds \r",i);
for (index=0;index<1000;index++)
udelay(1000);
}
putc('\n');
do_reset(NULL, 0, 0, NULL);
}
puts("FPGA: ");
/* display infos on fpgaimage */
index = 15;
for (i=0; i<4; i++) {
len = dst[index];
printf("%s ", &(dst[index+1]));
index += len+3;
}
putc('\n');
free(dst);
/*
* Reset FPGA
*/
GPIO_OUTPUT_CLEAR(CFG_GPIO_FPGA_RESET);
udelay(10);
GPIO_OUTPUT_SET(CFG_GPIO_FPGA_RESET);
return (0);
}
int do_fpga(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
ulong addr;
if (argc < 2) {
printf ("Usage:\n%s\n", cmdtp->usage);
return 1;
}
addr = simple_strtoul(argv[1], NULL, 16);
return do_fpga_boot((unsigned char *)addr);
}
U_BOOT_CMD(
fpga, 2, 0, do_fpga,
"fpga - boot FPGA\n",
"address size\n - boot FPGA with gzipped image at <address>\n"
);
#if (CONFIG_COMMANDS & CFG_CMD_PCI) || defined(CONFIG_PCI)
extern struct pci_controller hose;
extern void pci_ixp_init(struct pci_controller * hose);
void pci_init_board(void)
{
extern void pci_ixp_init (struct pci_controller *hose);
pci_ixp_init(&hose);
}
#endif

View file

@ -0,0 +1,56 @@
/*
* (C) Copyright 2006
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
OUTPUT_FORMAT("elf32-bigarm", "elf32-bigarm", "elf32-bigarm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
cpu/ixp/start.o (.text)
*(.text)
}
. = ALIGN(4);
.rodata : { *(.rodata) }
. = ALIGN(4);
.data : { *(.data) }
. = ALIGN(4);
.got : { *(.got) }
. = .;
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
. = ALIGN(4);
__bss_start = .;
.bss : { *(.bss) }
_end = .;
}

View file

@ -33,6 +33,9 @@
#include <asm/io.h>
#include <asm/arch/hardware.h>
#endif
#ifdef CONFIG_IXP425 /* only valid for IXP425 */
#include <asm/arch/ixp425.h>
#endif
#include <i2c.h>
#if defined(CONFIG_SOFT_I2C)

View file

@ -27,7 +27,7 @@ BIG_ENDIAN = y
PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 \
-msoft-float -mbig-endian
PLATFORM_CPPFLAGS += -mbig-endian -march=armv4 -mtune=strongarm1100
PLATFORM_CPPFLAGS += -mbig-endian -march=armv5te -mtune=strongarm1100
# =========================================================================
#
# Supply options according to compiler version

View file

@ -34,10 +34,47 @@
#include <command.h>
#include <asm/arch/ixp425.h>
ulong loops_per_jiffy;
#ifdef CONFIG_USE_IRQ
DECLARE_GLOBAL_DATA_PTR;
#endif
#if defined(CONFIG_DISPLAY_CPUINFO)
int print_cpuinfo (void)
{
unsigned long id;
int speed = 0;
asm ("mrc p15, 0, %0, c0, c0, 0":"=r" (id));
puts("CPU: Intel IXP425 at ");
switch ((id & 0x000003f0) >> 4) {
case 0x1c:
loops_per_jiffy = 887467;
speed = 533;
break;
case 0x1d:
loops_per_jiffy = 666016;
speed = 400;
break;
case 0x1f:
loops_per_jiffy = 442901;
speed = 266;
break;
}
if (speed)
printf("%d MHz\n", speed);
else
puts("unknown revision\n");
return 0;
}
#endif /* CONFIG_DISPLAY_CPUINFO */
int cpu_init (void)
{
/*
@ -48,7 +85,9 @@ int cpu_init (void)
FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ;
#endif
#if (CONFIG_COMMANDS & CFG_CMD_PCI) || defined (CONFIG_PCI)
pci_init();
#endif
return 0;
}
@ -154,3 +193,25 @@ void pci_init(void)
return;
}
*/
#ifdef CONFIG_BOOTCOUNT_LIMIT
void bootcount_store (ulong a)
{
volatile ulong *save_addr = (volatile ulong *)(CFG_BOOTCOUNT_ADDR);
save_addr[0] = a;
save_addr[1] = BOOTCOUNT_MAGIC;
}
ulong bootcount_load (void)
{
volatile ulong *save_addr = (volatile ulong *)(CFG_BOOTCOUNT_ADDR);
if (save_addr[1] != BOOTCOUNT_MAGIC)
return 0;
else
return save_addr[0];
}
#endif /* CONFIG_BOOTCOUNT_LIMIT */

View file

@ -1,5 +1,7 @@
/* vi: set ts=8 sw=8 noet: */
/*
* (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>
@ -31,22 +33,85 @@
#include <asm/arch/ixp425.h>
#ifdef CONFIG_USE_IRQ
/* enable IRQ/FIQ interrupts */
void enable_interrupts (void)
{
#error: interrupts not implemented yet
}
/*
* When interrupts are enabled, use timer 2 for time/delay generation...
*/
#define FREQ 66666666
#define CLOCK_TICK_RATE (((FREQ / CFG_HZ & ~IXP425_OST_RELOAD_MASK) + 1) * CFG_HZ)
#define LATCH ((CLOCK_TICK_RATE + CFG_HZ/2) / CFG_HZ) /* For divider */
struct _irq_handler {
void *m_data;
void (*m_func)( void *data);
};
static struct _irq_handler IRQ_HANDLER[N_IRQS];
static volatile ulong timestamp;
/* enable IRQ/FIQ interrupts */
void enable_interrupts(void)
{
unsigned long temp;
__asm__ __volatile__("mrs %0, cpsr\n"
"bic %0, %0, #0x80\n"
"msr cpsr_c, %0"
: "=r" (temp)
:
: "memory");
}
/*
* disable IRQ/FIQ interrupts
* returns true if interrupts had been enabled before we disabled them
*/
int disable_interrupts (void)
int disable_interrupts(void)
{
#error: interrupts not implemented yet
unsigned long old,temp;
__asm__ __volatile__("mrs %0, cpsr\n"
"orr %1, %0, #0x80\n"
"msr cpsr_c, %1"
: "=r" (old), "=r" (temp)
:
: "memory");
return (old & 0x80) == 0;
}
#else
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);
}
static void timer_isr(void *data)
{
unsigned int *pTime = (unsigned int *)data;
(*pTime)++;
/*
* Reset IRQ source
*/
*IXP425_OSST = IXP425_OSST_TIMER_2_PEND;
}
ulong get_timer (ulong base)
{
return timestamp - base;
}
void reset_timer (void)
{
timestamp = 0;
}
#else /* #ifdef CONFIG_USE_IRQ */
void enable_interrupts (void)
{
return;
@ -55,8 +120,7 @@ int disable_interrupts (void)
{
return 0;
}
#endif
#endif /* #ifdef CONFIG_USE_IRQ */
void bad_mode (void)
{
@ -140,19 +204,46 @@ void do_fiq (struct pt_regs *pt_regs)
{
printf ("fast interrupt request\n");
show_regs (pt_regs);
bad_mode ();
printf("IRQ=%08lx FIQ=%08lx\n", *IXP425_ICIH, *IXP425_ICFH);
}
void do_irq (struct pt_regs *pt_regs)
{
#ifdef CONFIG_USE_IRQ
int irq = next_irq();
IRQ_HANDLER[irq].m_func(IRQ_HANDLER[irq].m_data);
#else
printf ("interrupt request\n");
show_regs (pt_regs);
bad_mode ();
#endif
}
int interrupt_init (void)
{
/* nothing happens here - we don't setup any IRQs */
#ifdef CONFIG_USE_IRQ
int i;
/* install default interrupt handlers */
for (i = 0; i < N_IRQS; i++) {
IRQ_HANDLER[i].m_data = (void *)i;
IRQ_HANDLER[i].m_func = default_isr;
}
/* install interrupt handler for timer */
IRQ_HANDLER[IXP425_TIMER_2_IRQ].m_data = (void *)&timestamp;
IRQ_HANDLER[IXP425_TIMER_2_IRQ].m_func = timer_isr;
/* setup the Timer counter value */
*IXP425_OSRT2 = (LATCH & ~IXP425_OST_RELOAD_MASK) | IXP425_OST_ENABLE;
/* configure interrupts for IRQ mode */
*IXP425_ICLR = 0x00000000;
/* enable timer irq */
*IXP425_ICMR = (1 << IXP425_TIMER_2_IRQ);
#endif
return (0);
}

261
cpu/ixp/npe/IxEthAcc.c Normal file
View file

@ -0,0 +1,261 @@
/**
* @file IxEthAcc.c
*
* @author Intel Corporation
* @date 20-Feb-2001
*
* @brief This file contains the implementation of the IXP425 Ethernet Access Component
*
* Design Notes:
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#include "IxEthAcc.h"
#ifdef CONFIG_IXP425_COMPONENT_ETHDB
#include "IxEthDB.h"
#endif
#include "IxFeatureCtrl.h"
#include "IxEthAcc_p.h"
#include "IxEthAccMac_p.h"
#include "IxEthAccMii_p.h"
/**
* @addtogroup IxEthAcc
*@{
*/
/**
* @brief System-wide information data strucure.
*
* @ingroup IxEthAccPri
*
*/
IxEthAccInfo ixEthAccDataInfo;
extern PUBLIC IxEthAccMacState ixEthAccMacState[];
extern PUBLIC IxOsalMutex ixEthAccControlInterfaceMutex;
/**
* @brief System-wide information
*
* @ingroup IxEthAccPri
*
*/
BOOL ixEthAccServiceInit = FALSE;
/* global filtering bit mask */
PUBLIC UINT32 ixEthAccNewSrcMask;
/**
* @brief Per port information data strucure.
*
* @ingroup IxEthAccPri
*
*/
IxEthAccPortDataInfo ixEthAccPortData[IX_ETH_ACC_NUMBER_OF_PORTS];
PUBLIC IxEthAccStatus ixEthAccInit()
{
#ifdef CONFIG_IXP425_COMPONENT_ETHDB
/*
* Initialize Control plane
*/
if (ixEthDBInit() != IX_ETH_ACC_SUCCESS)
{
IX_ETH_ACC_WARNING_LOG("ixEthAccInit: EthDB init failed\n", 0, 0, 0, 0, 0, 0);
return IX_ETH_ACC_FAIL;
}
#endif
if (IX_FEATURE_CTRL_SWCONFIG_ENABLED == ixFeatureCtrlSwConfigurationCheck (IX_FEATURECTRL_ETH_LEARNING))
{
ixEthAccNewSrcMask = (~0); /* want all the bits */
}
else
{
ixEthAccNewSrcMask = (~IX_ETHACC_NE_NEWSRCMASK); /* want all but the NewSrc bit */
}
/*
* Initialize Data plane
*/
if ( ixEthAccInitDataPlane() != IX_ETH_ACC_SUCCESS )
{
IX_ETH_ACC_WARNING_LOG("ixEthAccInit: data plane init failed\n", 0, 0, 0, 0, 0, 0);
return IX_ETH_ACC_FAIL;
}
if ( ixEthAccQMgrQueuesConfig() != IX_ETH_ACC_SUCCESS )
{
IX_ETH_ACC_WARNING_LOG("ixEthAccInit: queue config failed\n", 0, 0, 0, 0, 0, 0);
return IX_ETH_ACC_FAIL;
}
/*
* Initialize MII
*/
if ( ixEthAccMiiInit() != IX_ETH_ACC_SUCCESS )
{
IX_ETH_ACC_WARNING_LOG("ixEthAccInit: Mii init failed\n", 0, 0, 0, 0, 0, 0);
return IX_ETH_ACC_FAIL;
}
/*
* Initialize MAC I/O memory
*/
if (ixEthAccMacMemInit() != IX_ETH_ACC_SUCCESS)
{
IX_ETH_ACC_WARNING_LOG("ixEthAccInit: Mac init failed\n", 0, 0, 0, 0, 0, 0);
return IX_ETH_ACC_FAIL;
}
/*
* Initialize control plane interface lock
*/
if (ixOsalMutexInit(&ixEthAccControlInterfaceMutex) != IX_SUCCESS)
{
IX_ETH_ACC_WARNING_LOG("ixEthAccInit: Control plane interface lock initialization failed\n", 0, 0, 0, 0, 0, 0);
return IX_ETH_ACC_FAIL;
}
/* initialiasation is complete */
ixEthAccServiceInit = TRUE;
return IX_ETH_ACC_SUCCESS;
}
PUBLIC void ixEthAccUnload(void)
{
IxEthAccPortId portId;
if ( IX_ETH_ACC_IS_SERVICE_INITIALIZED() )
{
/* check none of the port is still active */
for (portId = 0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++)
{
if ( IX_ETH_IS_PORT_INITIALIZED(portId) )
{
if (ixEthAccMacState[portId].portDisableState == ACTIVE)
{
IX_ETH_ACC_WARNING_LOG("ixEthAccUnload: port %u still active, bail out\n", portId, 0, 0, 0, 0, 0);
return;
}
}
}
/* unmap the memory areas */
ixEthAccMiiUnload();
ixEthAccMacUnload();
/* set all ports as uninitialized */
for (portId = 0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++)
{
ixEthAccPortData[portId].portInitialized = FALSE;
}
/* uninitialize the service */
ixEthAccServiceInit = FALSE;
}
}
PUBLIC IxEthAccStatus ixEthAccPortInit( IxEthAccPortId portId)
{
IxEthAccStatus ret=IX_ETH_ACC_SUCCESS;
if ( ! IX_ETH_ACC_IS_SERVICE_INITIALIZED() )
{
return(IX_ETH_ACC_FAIL);
}
/*
* Check for valid port
*/
if ( ! IX_ETH_ACC_IS_PORT_VALID(portId) )
{
return (IX_ETH_ACC_INVALID_PORT);
}
if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
{
IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot initialize Eth port.\n",(INT32) portId,0,0,0,0,0);
return IX_ETH_ACC_SUCCESS ;
}
if ( IX_ETH_IS_PORT_INITIALIZED(portId) )
{
/* Already initialized */
return(IX_ETH_ACC_FAIL);
}
if(ixEthAccMacInit(portId)!=IX_ETH_ACC_SUCCESS)
{
return IX_ETH_ACC_FAIL;
}
/*
* Set the port init flag.
*/
ixEthAccPortData[portId].portInitialized = TRUE;
#ifdef CONFIG_IXP425_COMPONENT_ETHDB
/* init learning/filtering database structures for this port */
ixEthDBPortInit(portId);
#endif
return(ret);
}

1049
cpu/ixp/npe/IxEthAccCommon.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,533 @@
/**
* @file IxEthAccControlInterface.c
*
* @author Intel Corporation
* @date
*
* @brief IX_ETH_ACC_PUBLIC wrappers for control plane functions
*
* Design Notes:
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#include "IxOsal.h"
#include "IxEthAcc.h"
#include "IxEthAcc_p.h"
PUBLIC IxOsalMutex ixEthAccControlInterfaceMutex;
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortEnable(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
printf("EthAcc: (Mac) cannot enable port %d, service not initialized\n", portId);
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortEnablePriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortDisable(IxEthAccPortId portId)
{
IxEthAccStatus result;
/* check the context is iinitialized */
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortDisablePriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortEnabledQuery(IxEthAccPortId portId, BOOL *enabled)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortEnabledQueryPriv(portId, enabled);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortPromiscuousModeClear(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortPromiscuousModeClearPriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortPromiscuousModeSet(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortPromiscuousModeSetPriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortUnicastMacAddressSet(IxEthAccPortId portId, IxEthAccMacAddr *macAddr)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortUnicastMacAddressSetPriv(portId, macAddr);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortUnicastMacAddressGet(IxEthAccPortId portId, IxEthAccMacAddr *macAddr)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortUnicastMacAddressGetPriv(portId, macAddr);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortMulticastAddressJoin(IxEthAccPortId portId, IxEthAccMacAddr *macAddr)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortMulticastAddressJoinPriv(portId, macAddr);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortMulticastAddressJoinAll(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortMulticastAddressJoinAllPriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortMulticastAddressLeave(IxEthAccPortId portId, IxEthAccMacAddr *macAddr)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortMulticastAddressLeavePriv(portId, macAddr);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortMulticastAddressLeaveAll(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortMulticastAddressLeaveAllPriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortUnicastAddressShow(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortUnicastAddressShowPriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC void
ixEthAccPortMulticastAddressShow(IxEthAccPortId portId)
{
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return;
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
ixEthAccPortMulticastAddressShowPriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortDuplexModeSet(IxEthAccPortId portId, IxEthAccDuplexMode mode)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortDuplexModeSetPriv(portId, mode);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortDuplexModeGet(IxEthAccPortId portId, IxEthAccDuplexMode *mode)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortDuplexModeGetPriv(portId, mode);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortTxFrameAppendPaddingEnable(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortTxFrameAppendPaddingEnablePriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortTxFrameAppendPaddingDisable(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortTxFrameAppendPaddingDisablePriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortTxFrameAppendFCSEnable(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortTxFrameAppendFCSEnablePriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortTxFrameAppendFCSDisable(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortTxFrameAppendFCSDisablePriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortRxFrameAppendFCSEnable(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortRxFrameAppendFCSEnablePriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortRxFrameAppendFCSDisable(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortRxFrameAppendFCSDisablePriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccTxSchedulingDisciplineSet(IxEthAccPortId portId, IxEthAccSchedulerDiscipline sched)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccTxSchedulingDisciplineSetPriv(portId, sched);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccRxSchedulingDisciplineSet(IxEthAccSchedulerDiscipline sched)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccRxSchedulingDisciplineSetPriv(sched);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortNpeLoopbackEnable(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccNpeLoopbackEnablePriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortTxEnable(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortTxEnablePriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortRxEnable(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortRxEnablePriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortNpeLoopbackDisable(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccNpeLoopbackDisablePriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortTxDisable(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortTxDisablePriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortRxDisable(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortRxDisablePriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortMacReset(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortMacResetPriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}

File diff suppressed because it is too large Load diff

2641
cpu/ixp/npe/IxEthAccMac.c Normal file

File diff suppressed because it is too large Load diff

410
cpu/ixp/npe/IxEthAccMii.c Normal file
View file

@ -0,0 +1,410 @@
/**
* @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
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#include "IxOsal.h"
#include "IxEthAcc.h"
#include "IxEthAcc_p.h"
#include "IxEthAccMac_p.h"
#include "IxEthAccMii_p.h"
PRIVATE UINT32 miiBaseAddressVirt;
PRIVATE IxOsalMutex miiAccessLock;
PUBLIC UINT32 ixEthAccMiiRetryCount = IX_ETH_ACC_MII_TIMEOUT_10TH_SECS;
PUBLIC UINT32 ixEthAccMiiAccessTimeout = IX_ETH_ACC_MII_10TH_SEC_IN_MILLIS;
/* -----------------------------------
* private function prototypes
*/
PRIVATE void
ixEthAccMdioCmdWrite(UINT32 mdioCommand);
PRIVATE void
ixEthAccMdioCmdRead(UINT32 *data);
PRIVATE void
ixEthAccMdioStatusRead(UINT32 *data);
PRIVATE void
ixEthAccMdioCmdWrite(UINT32 mdioCommand)
{
REG_WRITE(miiBaseAddressVirt,
IX_ETH_ACC_MAC_MDIO_CMD_1,
mdioCommand & 0xff);
REG_WRITE(miiBaseAddressVirt,
IX_ETH_ACC_MAC_MDIO_CMD_2,
(mdioCommand >> 8) & 0xff);
REG_WRITE(miiBaseAddressVirt,
IX_ETH_ACC_MAC_MDIO_CMD_3,
(mdioCommand >> 16) & 0xff);
REG_WRITE(miiBaseAddressVirt,
IX_ETH_ACC_MAC_MDIO_CMD_4,
(mdioCommand >> 24) & 0xff);
}
PRIVATE void
ixEthAccMdioCmdRead(UINT32 *data)
{
UINT32 regval;
REG_READ(miiBaseAddressVirt,
IX_ETH_ACC_MAC_MDIO_CMD_1,
regval);
*data = regval & 0xff;
REG_READ(miiBaseAddressVirt,
IX_ETH_ACC_MAC_MDIO_CMD_2,
regval);
*data |= (regval & 0xff) << 8;
REG_READ(miiBaseAddressVirt,
IX_ETH_ACC_MAC_MDIO_CMD_3,
regval);
*data |= (regval & 0xff) << 16;
REG_READ(miiBaseAddressVirt,
IX_ETH_ACC_MAC_MDIO_CMD_4,
regval);
*data |= (regval & 0xff) << 24;
}
PRIVATE void
ixEthAccMdioStatusRead(UINT32 *data)
{
UINT32 regval;
REG_READ(miiBaseAddressVirt,
IX_ETH_ACC_MAC_MDIO_STS_1,
regval);
*data = regval & 0xff;
REG_READ(miiBaseAddressVirt,
IX_ETH_ACC_MAC_MDIO_STS_2,
regval);
*data |= (regval & 0xff) << 8;
REG_READ(miiBaseAddressVirt,
IX_ETH_ACC_MAC_MDIO_STS_3,
regval);
*data |= (regval & 0xff) << 16;
REG_READ(miiBaseAddressVirt,
IX_ETH_ACC_MAC_MDIO_STS_4,
regval);
*data |= (regval & 0xff) << 24;
}
/********************************************************************
* ixEthAccMiiInit
*/
IxEthAccStatus
ixEthAccMiiInit()
{
if(ixOsalMutexInit(&miiAccessLock)!= IX_SUCCESS)
{
return IX_ETH_ACC_FAIL;
}
miiBaseAddressVirt = (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_0_BASE, IX_OSAL_IXP400_ETHA_MAP_SIZE);
if (miiBaseAddressVirt == 0)
{
ixOsalLog(IX_OSAL_LOG_LVL_FATAL,
IX_OSAL_LOG_DEV_STDOUT,
"EthAcc: Could not map MII I/O mapped memory\n",
0, 0, 0, 0, 0, 0);
return IX_ETH_ACC_FAIL;
}
return IX_ETH_ACC_SUCCESS;
}
void
ixEthAccMiiUnload(void)
{
IX_OSAL_MEM_UNMAP(miiBaseAddressVirt);
miiBaseAddressVirt = 0;
}
PUBLIC IxEthAccStatus
ixEthAccMiiAccessTimeoutSet(UINT32 timeout, UINT32 retryCount)
{
if (retryCount < 1) return IX_ETH_ACC_FAIL;
ixEthAccMiiRetryCount = retryCount;
ixEthAccMiiAccessTimeout = timeout;
return IX_ETH_ACC_SUCCESS;
}
/*********************************************************************
* ixEthAccMiiReadRtn - read a 16 bit value from a PHY
*/
IxEthAccStatus
ixEthAccMiiReadRtn (UINT8 phyAddr,
UINT8 phyReg,
UINT16 *value)
{
UINT32 mdioCommand;
UINT32 regval;
UINT32 miiTimeout;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
if ((phyAddr >= IXP425_ETH_ACC_MII_MAX_ADDR)
|| (phyReg >= IXP425_ETH_ACC_MII_MAX_REG))
{
return (IX_ETH_ACC_FAIL);
}
if (value == NULL)
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER);
mdioCommand = phyReg << IX_ETH_ACC_MII_REG_SHL
| phyAddr << IX_ETH_ACC_MII_ADDR_SHL;
mdioCommand |= IX_ETH_ACC_MII_GO;
ixEthAccMdioCmdWrite(mdioCommand);
miiTimeout = ixEthAccMiiRetryCount;
while(miiTimeout)
{
ixEthAccMdioCmdRead(&regval);
if((regval & IX_ETH_ACC_MII_GO) == 0x0)
{
break;
}
/* Sleep for a while */
ixOsalSleep(ixEthAccMiiAccessTimeout);
miiTimeout--;
}
if(miiTimeout == 0)
{
ixOsalMutexUnlock(&miiAccessLock);
*value = 0xffff;
return IX_ETH_ACC_FAIL;
}
ixEthAccMdioStatusRead(&regval);
if(regval & IX_ETH_ACC_MII_READ_FAIL)
{
ixOsalMutexUnlock(&miiAccessLock);
*value = 0xffff;
return IX_ETH_ACC_FAIL;
}
*value = regval & 0xffff;
ixOsalMutexUnlock(&miiAccessLock);
return IX_ETH_ACC_SUCCESS;
}
/*********************************************************************
* ixEthAccMiiWriteRtn - write a 16 bit value to a PHY
*/
IxEthAccStatus
ixEthAccMiiWriteRtn (UINT8 phyAddr,
UINT8 phyReg,
UINT16 value)
{
UINT32 mdioCommand;
UINT32 regval;
UINT16 readVal;
UINT32 miiTimeout;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
if ((phyAddr >= IXP425_ETH_ACC_MII_MAX_ADDR)
|| (phyReg >= IXP425_ETH_ACC_MII_MAX_REG))
{
return (IX_ETH_ACC_FAIL);
}
/* ensure that a PHY is present at this address */
if(ixEthAccMiiReadRtn(phyAddr,
IX_ETH_ACC_MII_CTRL_REG,
&readVal) != IX_ETH_ACC_SUCCESS)
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER);
mdioCommand = phyReg << IX_ETH_ACC_MII_REG_SHL
| phyAddr << IX_ETH_ACC_MII_ADDR_SHL ;
mdioCommand |= IX_ETH_ACC_MII_GO | IX_ETH_ACC_MII_WRITE | value;
ixEthAccMdioCmdWrite(mdioCommand);
miiTimeout = ixEthAccMiiRetryCount;
while(miiTimeout)
{
ixEthAccMdioCmdRead(&regval);
/*The "GO" bit is reset to 0 when the write completes*/
if((regval & IX_ETH_ACC_MII_GO) == 0x0)
{
break;
}
/* Sleep for a while */
ixOsalSleep(ixEthAccMiiAccessTimeout);
miiTimeout--;
}
ixOsalMutexUnlock(&miiAccessLock);
if(miiTimeout == 0)
{
return IX_ETH_ACC_FAIL;
}
return IX_ETH_ACC_SUCCESS;
}
/*****************************************************************
*
* Phy query functions
*
*/
IxEthAccStatus
ixEthAccMiiStatsShow (UINT32 phyAddr)
{
UINT16 regval;
printf("Regisers on PHY at address 0x%x\n", phyAddr);
ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_CTRL_REG, &regval);
printf(" Control Register : 0x%4.4x\n", regval);
ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_STAT_REG, &regval);
printf(" Status Register : 0x%4.4x\n", regval);
ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_PHY_ID1_REG, &regval);
printf(" PHY ID1 Register : 0x%4.4x\n", regval);
ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_PHY_ID2_REG, &regval);
printf(" PHY ID2 Register : 0x%4.4x\n", regval);
ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_ADS_REG, &regval);
printf(" Auto Neg ADS Register : 0x%4.4x\n", regval);
ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_PRTN_REG, &regval);
printf(" Auto Neg Partner Ability Register : 0x%4.4x\n", regval);
ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_EXP_REG, &regval);
printf(" Auto Neg Expansion Register : 0x%4.4x\n", regval);
ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_NEXT_REG, &regval);
printf(" Auto Neg Next Register : 0x%4.4x\n", regval);
return IX_ETH_ACC_SUCCESS;
}
/*****************************************************************
*
* Interface query functions
*
*/
IxEthAccStatus
ixEthAccMdioShow (void)
{
UINT32 regval;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER);
ixEthAccMdioCmdRead(&regval);
ixOsalMutexUnlock(&miiAccessLock);
printf("MDIO command register\n");
printf(" Go bit : 0x%x\n", (regval & BIT(31)) >> 31);
printf(" MDIO Write : 0x%x\n", (regval & BIT(26)) >> 26);
printf(" PHY address : 0x%x\n", (regval >> 21) & 0x1f);
printf(" Reg address : 0x%x\n", (regval >> 16) & 0x1f);
ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER);
ixEthAccMdioStatusRead(&regval);
ixOsalMutexUnlock(&miiAccessLock);
printf("MDIO status register\n");
printf(" Read OK : 0x%x\n", (regval & BIT(31)) >> 31);
printf(" Read Data : 0x%x\n", (regval >> 16) & 0xff);
return IX_ETH_ACC_SUCCESS;
}

448
cpu/ixp/npe/IxEthDBAPI.c Normal file
View file

@ -0,0 +1,448 @@
/**
* @file IxEthDBAPI.c
*
* @brief Implementation of the public API
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#include "IxEthDB_p.h"
#include "IxFeatureCtrl.h"
extern HashTable dbHashtable;
extern IxEthDBPortMap overflowUpdatePortList;
extern BOOL ixEthDBPortUpdateRequired[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1];
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFilteringStaticEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
{
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_REFERENCE(macAddr);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
return ixEthDBTriggerAddPortUpdate(macAddr, portID, TRUE);
}
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFilteringDynamicEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
{
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_REFERENCE(macAddr);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
return ixEthDBTriggerAddPortUpdate(macAddr, portID, FALSE);
}
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFilteringEntryDelete(IxEthDBMacAddr *macAddr)
{
HashNode *searchResult;
IX_ETH_DB_CHECK_REFERENCE(macAddr);
searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
if (searchResult == NULL)
{
return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
}
ixEthDBReleaseHashNode(searchResult);
/* build a remove event and place it on the event queue */
return ixEthDBTriggerRemovePortUpdate(macAddr, ((MacDescriptor *) searchResult->data)->portID);
}
IX_ETH_DB_PUBLIC
void ixEthDBDatabaseMaintenance()
{
HashIterator iterator;
UINT32 portIndex;
BOOL agingRequired = FALSE;
/* ports who will have deleted records and therefore will need updating */
IxEthDBPortMap triggerPorts;
if (IX_FEATURE_CTRL_SWCONFIG_ENABLED !=
ixFeatureCtrlSwConfigurationCheck (IX_FEATURECTRL_ETH_LEARNING))
{
return;
}
SET_EMPTY_DEPENDENCY_MAP(triggerPorts);
/* check if there's at least a port that needs aging */
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
{
if (ixEthDBPortInfo[portIndex].agingEnabled && ixEthDBPortInfo[portIndex].enabled)
{
agingRequired = TRUE;
}
}
if (agingRequired)
{
/* ask each NPE port to write back the database for aging inspection */
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
{
if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE
&& ixEthDBPortInfo[portIndex].agingEnabled
&& ixEthDBPortInfo[portIndex].enabled)
{
IxNpeMhMessage message;
IX_STATUS result;
/* send EDB_GetMACAddressDatabase message */
FILL_GETMACADDRESSDATABASE(message,
0 /* unused */,
IX_OSAL_MMU_VIRT_TO_PHYS(ixEthDBPortInfo[portIndex].updateMethod.npeUpdateZone));
IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portIndex), message, result);
if (result == IX_SUCCESS)
{
/* analyze NPE copy */
ixEthDBNPESyncScan(portIndex, ixEthDBPortInfo[portIndex].updateMethod.npeUpdateZone, FULL_ELT_BYTE_SIZE);
IX_ETH_DB_SUPPORT_TRACE("DB: (API) Finished scanning NPE tree on port %d\n", portIndex);
}
else
{
ixEthDBPortInfo[portIndex].agingEnabled = FALSE;
ixEthDBPortInfo[portIndex].updateMethod.updateEnabled = FALSE;
ixEthDBPortInfo[portIndex].updateMethod.userControlled = TRUE;
ixOsalLog(IX_OSAL_LOG_LVL_FATAL,
IX_OSAL_LOG_DEV_STDOUT,
"EthDB: (Maintenance) warning, disabling aging and updates for port %d (assumed dead)\n",
portIndex, 0, 0, 0, 0, 0);
ixEthDBDatabaseClear(portIndex, IX_ETH_DB_ALL_RECORD_TYPES);
}
}
}
/* browse database and age entries */
BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
while (IS_ITERATOR_VALID(&iterator))
{
MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
UINT32 *age = NULL;
BOOL staticEntry = TRUE;
if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
{
age = &descriptor->recordData.filteringData.age;
staticEntry = descriptor->recordData.filteringData.staticEntry;
}
else if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD)
{
age = &descriptor->recordData.filteringVlanData.age;
staticEntry = descriptor->recordData.filteringVlanData.staticEntry;
}
else
{
staticEntry = TRUE;
}
if (ixEthDBPortInfo[descriptor->portID].agingEnabled && (staticEntry == FALSE))
{
/* manually increment the age if the port has no such capability */
if ((ixEthDBPortDefinitions[descriptor->portID].capabilities & IX_ETH_ENTRY_AGING) == 0)
{
*age += (IX_ETH_DB_MAINTENANCE_TIME / 60);
}
/* age entry if it exceeded the maximum time to live */
if (*age >= (IX_ETH_DB_LEARNING_ENTRY_AGE_TIME / 60))
{
/* add port to the set of update trigger ports */
JOIN_PORT_TO_MAP(triggerPorts, descriptor->portID);
/* delete entry */
BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator));
}
else
{
/* move to the next record */
BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
}
}
else
{
/* move to the next record */
BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
}
}
/* update ports which lost records */
ixEthDBUpdatePortLearningTrees(triggerPorts);
}
}
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBDatabaseClear(IxEthDBPortId portID, IxEthDBRecordType recordType)
{
IxEthDBPortMap triggerPorts;
HashIterator iterator;
if (portID >= IX_ETH_DB_NUMBER_OF_PORTS && portID != IX_ETH_DB_ALL_PORTS)
{
return IX_ETH_DB_INVALID_PORT;
}
/* check if the user passes some extra bits */
if ((recordType | IX_ETH_DB_ALL_RECORD_TYPES) != IX_ETH_DB_ALL_RECORD_TYPES)
{
return IX_ETH_DB_INVALID_ARG;
}
SET_EMPTY_DEPENDENCY_MAP(triggerPorts);
/* browse database and age entries */
BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
while (IS_ITERATOR_VALID(&iterator))
{
MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
if (((descriptor->portID == portID) || (portID == IX_ETH_DB_ALL_PORTS))
&& ((descriptor->type & recordType) != 0))
{
/* add to trigger if automatic updates are required */
if (ixEthDBPortUpdateRequired[descriptor->type])
{
/* add port to the set of update trigger ports */
JOIN_PORT_TO_MAP(triggerPorts, descriptor->portID);
}
/* delete entry */
BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator));
}
else
{
/* move to the next record */
BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
}
}
/* update ports which lost records */
ixEthDBUpdatePortLearningTrees(triggerPorts);
return IX_ETH_DB_SUCCESS;
}
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFilteringPortSearch(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
{
HashNode *searchResult;
IxEthDBStatus result = IX_ETH_DB_NO_SUCH_ADDR;
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_REFERENCE(macAddr);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
if (searchResult == NULL)
{
return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
}
if (((MacDescriptor *) (searchResult->data))->portID == portID)
{
result = IX_ETH_DB_SUCCESS; /* address and port match */
}
ixEthDBReleaseHashNode(searchResult);
return result;
}
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFilteringDatabaseSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr)
{
HashNode *searchResult;
IX_ETH_DB_CHECK_REFERENCE(portID);
IX_ETH_DB_CHECK_REFERENCE(macAddr);
searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
if (searchResult == NULL)
{
return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
}
/* return the port ID */
*portID = ((MacDescriptor *) searchResult->data)->portID;
ixEthDBReleaseHashNode(searchResult);
return IX_ETH_DB_SUCCESS;
}
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBPortAgingDisable(IxEthDBPortId portID)
{
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
ixEthDBPortInfo[portID].agingEnabled = FALSE;
return IX_ETH_DB_SUCCESS;
}
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBPortAgingEnable(IxEthDBPortId portID)
{
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
ixEthDBPortInfo[portID].agingEnabled = TRUE;
return IX_ETH_DB_SUCCESS;
}
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFilteringPortUpdatingSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr)
{
HashNode *searchResult;
MacDescriptor *descriptor;
IX_ETH_DB_CHECK_REFERENCE(portID);
IX_ETH_DB_CHECK_REFERENCE(macAddr);
searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
if (searchResult == NULL)
{
return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
}
descriptor = (MacDescriptor *) searchResult->data;
/* return the port ID */
*portID = descriptor->portID;
/* reset entry age */
if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
{
descriptor->recordData.filteringData.age = 0;
}
else
{
descriptor->recordData.filteringVlanData.age = 0;
}
ixEthDBReleaseHashNode(searchResult);
return IX_ETH_DB_SUCCESS;
}
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBPortDependencyMapSet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap)
{
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_REFERENCE(dependencyPortMap);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING);
/* force bit at offset 255 to 0 (reserved) */
dependencyPortMap[31] &= 0xFE;
COPY_DEPENDENCY_MAP(ixEthDBPortInfo[portID].dependencyPortMap, dependencyPortMap);
return IX_ETH_DB_SUCCESS;
}
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBPortDependencyMapGet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap)
{
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_REFERENCE(dependencyPortMap);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING);
COPY_DEPENDENCY_MAP(dependencyPortMap, ixEthDBPortInfo[portID].dependencyPortMap);
return IX_ETH_DB_SUCCESS;
}
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBPortUpdateEnableSet(IxEthDBPortId portID, BOOL enableUpdate)
{
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING);
ixEthDBPortInfo[portID].updateMethod.updateEnabled = enableUpdate;
ixEthDBPortInfo[portID].updateMethod.userControlled = TRUE;
return IX_ETH_DB_SUCCESS;
}

View file

@ -0,0 +1,678 @@
/**
* @file IxEthDBAPISupport.c
*
* @brief Public API support functions
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#include <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;
IxOsalMutex *ackPortAddressLock;
IX_STATUS result;
/* use this macro instead CHECK_PORT
as the port doesn't need to be enabled */
IX_ETH_DB_CHECK_PORT_EXISTS(portID);
IX_ETH_DB_CHECK_REFERENCE(macAddr);
if (!ixEthDBPortInfo[portID].initialized)
{
return IX_ETH_DB_PORT_UNINITIALIZED;
}
ackPortAddressLock = &ixEthDBPortInfo[portID].npeAckLock;
/* Operation stops here when Ethernet Learning is not enabled */
if(IX_FEATURE_CTRL_SWCONFIG_DISABLED ==
ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING))
{
return IX_ETH_DB_SUCCESS;
}
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
/* exit if the port is not an Ethernet NPE */
if (ixEthDBPortDefinitions[portID].type != IX_ETH_NPE)
{
return IX_ETH_DB_INVALID_PORT;
}
/* populate message */
FILL_SETPORTADDRESS_MSG(message, portID, macAddr->macAddress);
IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Sending SetPortAddress on port %d...\n", portID);
/* send a SetPortAddress message */
IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
if (result == IX_SUCCESS)
{
ixEthDBPortInfo[portID].macAddressUploaded = TRUE;
}
return result;
}

463
cpu/ixp/npe/IxEthDBCore.c Normal file
View file

@ -0,0 +1,463 @@
/**
* @file IxEthDBDBCore.c
*
* @brief Database support functions
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#include "IxEthDB_p.h"
/* list of database hashtables */
IX_ETH_DB_PUBLIC HashTable dbHashtable;
IX_ETH_DB_PUBLIC MatchFunction matchFunctions[IX_ETH_DB_MAX_KEY_INDEX + 1];
IX_ETH_DB_PUBLIC BOOL ixEthDBPortUpdateRequired[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1];
IX_ETH_DB_PUBLIC UINT32 ixEthDBKeyType[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1];
/* private initialization flag */
IX_ETH_DB_PRIVATE BOOL ethDBInitializationComplete = FALSE;
/**
* @brief initializes EthDB
*
* This function must be called to initialize the component.
*
* It does the following things:
* - checks the port definition structure
* - scans the capabilities of the NPE images and sets the
* capabilities of the ports accordingly
* - initializes the memory pools internally used in EthDB
* for storing database records and handling data
* - registers automatic update handlers for add and remove
* operations
* - registers hashing match functions, depending on key sets
* - initializes the main database hashtable
* - allocates contiguous memory zones to be used for NPE
* updates
* - registers the serialize methods used to convert data
* into NPE-readable format
* - starts the event processor
*
* Note that this function is documented in the public
* component header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS or an appropriate error if the
* component failed to initialize correctly
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBInit(void)
{
IxEthDBStatus result;
if (ethDBInitializationComplete)
{
/* redundant */
return IX_ETH_DB_SUCCESS;
}
/* trap an invalid port definition structure */
IX_ETH_DB_PORTS_ASSERTION;
/* memory management */
ixEthDBInitMemoryPools();
/* register hashing search methods */
ixEthDBMatchMethodsRegister(matchFunctions);
/* register type-based automatic port updates */
ixEthDBUpdateTypeRegister(ixEthDBPortUpdateRequired);
/* register record to key type mappings */
ixEthDBKeyTypeRegister(ixEthDBKeyType);
/* hash table */
ixEthDBInitHash(&dbHashtable, NUM_BUCKETS, ixEthDBEntryXORHash, matchFunctions, (FreeFunction) ixEthDBFreeMacDescriptor);
/* NPE update zones */
ixEthDBNPEUpdateAreasInit();
/* register record serialization methods */
ixEthDBRecordSerializeMethodsRegister();
/* start the event processor */
result = ixEthDBEventProcessorInit();
/* scan NPE features */
if (result == IX_ETH_DB_SUCCESS)
{
ixEthDBFeatureCapabilityScan();
}
ethDBInitializationComplete = TRUE;
return result;
}
/**
* @brief prepares EthDB for unloading
*
* This function must be called before removing the
* EthDB component from memory (e.g. doing rmmod in
* Linux) if the component is to be re-initialized again
* without rebooting the platform.
*
* All the EthDB ports must be disabled before this
* function is to be called. Failure to disable all
* the ports will return the IX_ETH_DB_BUSY error.
*
* This function will destroy mutexes, deallocate
* memory and stop the event processor.
*
* Note that this function is fully documented in the
* main component header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if de-initialization
* completed successfully or an appropriate error
* message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBUnload(void)
{
IxEthDBPortId portIndex;
if (!ethDBInitializationComplete)
{
/* redundant */
return IX_ETH_DB_SUCCESS;
}
/* check if any ports are enabled */
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
{
if (ixEthDBPortInfo[portIndex].enabled)
{
return IX_ETH_DB_BUSY;
}
}
/* free port resources */
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
{
if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE)
{
ixOsalMutexDestroy(&ixEthDBPortInfo[portIndex].npeAckLock);
}
ixEthDBPortInfo[portIndex].initialized = FALSE;
}
/* shutdown event processor */
ixEthDBStopLearningFunction();
/* deallocate NPE update zones */
ixEthDBNPEUpdateAreasUnload();
ethDBInitializationComplete = FALSE;
return IX_ETH_DB_SUCCESS;
}
/**
* @brief adds a new entry to the Ethernet database
*
* @param newRecordTemplate address of the record template to use
* @param updateTrigger port map containing the update triggers
* resulting from this update operation
*
* Creates a new database entry, populates it with the data
* copied from the given template and adds the record to the
* database hash table.
* It also checks whether the new record type is registered to trigger
* automatic updates; if it is, the update trigger will contain the
* port on which the record insertion was performed, as well as the
* old port in case the addition was a record migration (from one port
* to the other). The caller can use the updateTrigger to trigger
* automatic updates on the ports changed as a result of this addition.
*
* @retval IX_ETH_DB_SUCCESS addition successful
* @retval IX_ETH_DB_NOMEM insertion failed, no memory left in the mac descriptor memory pool
* @retval IX_ETH_DB_BUSY database busy, cannot insert due to locking
*
* @internal
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBAdd(MacDescriptor *newRecordTemplate, IxEthDBPortMap updateTrigger)
{
IxEthDBStatus result;
MacDescriptor *newDescriptor;
IxEthDBPortId originalPortID;
HashNode *node = NULL;
BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, ixEthDBKeyType[newRecordTemplate->type], newRecordTemplate, &node));
TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER;
if (node == NULL)
{
/* not found, create a new one */
newDescriptor = ixEthDBAllocMacDescriptor();
if (newDescriptor == NULL)
{
return IX_ETH_DB_NOMEM; /* no memory */
}
/* old port does not exist, avoid unnecessary updates */
originalPortID = newRecordTemplate->portID;
}
else
{
/* a node with the same key exists, will update node */
newDescriptor = (MacDescriptor *) node->data;
/* save original port id */
originalPortID = newDescriptor->portID;
}
/* copy/update fields into new record */
memcpy(newDescriptor->macAddress, newRecordTemplate->macAddress, sizeof (IxEthDBMacAddr));
memcpy(&newDescriptor->recordData, &newRecordTemplate->recordData, sizeof (IxEthDBRecordData));
newDescriptor->type = newRecordTemplate->type;
newDescriptor->portID = newRecordTemplate->portID;
newDescriptor->user = newRecordTemplate->user;
if (node == NULL)
{
/* new record, insert into hashtable */
BUSY_RETRY_WITH_RESULT(ixEthDBAddHashEntry(&dbHashtable, newDescriptor), result);
if (result != IX_ETH_DB_SUCCESS)
{
ixEthDBFreeMacDescriptor(newDescriptor);
return result; /* insertion failed */
}
}
if (node != NULL)
{
/* release access */
ixEthDBReleaseHashNode(node);
}
/* trigger add/remove update if required by type */
if (updateTrigger != NULL &&
ixEthDBPortUpdateRequired[newRecordTemplate->type])
{
/* add new port to update list */
JOIN_PORT_TO_MAP(updateTrigger, newRecordTemplate->portID);
/* check if record has moved, we'll need to update the old port as well */
if (originalPortID != newDescriptor->portID)
{
JOIN_PORT_TO_MAP(updateTrigger, originalPortID);
}
}
return IX_ETH_DB_SUCCESS;
}
/**
* @brief remove a record from the Ethernet database
*
* @param templateRecord template record used to determine
* what record is to be removed
* @param updateTrigger port map containing the update triggers
* resulting from this update operation
*
* This function will examine the template record it receives
* and attempts to delete a record of the same type and containing
* the same keys as the template record. If deletion is successful
* and the record type is registered for automatic port updates the
* port will also be set in the updateTrigger port map, so that the
* client can perform an update of the port.
*
* @retval IX_ETH_DB_SUCCESS removal was successful
* @retval IX_ETH_DB_NO_SUCH_ADDR the record with the given MAC address was not found
* @retval IX_ETH_DB_BUSY database busy, cannot remove due to locking
*
* @internal
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBRemove(MacDescriptor *templateRecord, IxEthDBPortMap updateTrigger)
{
IxEthDBStatus result;
TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER;
BUSY_RETRY_WITH_RESULT(ixEthDBRemoveHashEntry(&dbHashtable, ixEthDBKeyType[templateRecord->type], templateRecord), result);
if (result != IX_ETH_DB_SUCCESS)
{
return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
}
/* trigger add/remove update if required by type */
if (updateTrigger != NULL
&&ixEthDBPortUpdateRequired[templateRecord->type])
{
/* add new port to update list */
JOIN_PORT_TO_MAP(updateTrigger, templateRecord->portID);
}
return IX_ETH_DB_SUCCESS;
}
/**
* @brief register record key types
*
* This function registers the appropriate key types,
* depending on record types.
*
* All filtering records use the MAC address as the key.
* WiFi and Firewall records use a compound key consisting
* in both the MAC address and the port ID.
*
* @return the number of registered record types
*/
IX_ETH_DB_PUBLIC
UINT32 ixEthDBKeyTypeRegister(UINT32 *keyType)
{
/* safety */
memset(keyType, 0, sizeof (keyType));
/* register all known record types */
keyType[IX_ETH_DB_FILTERING_RECORD] = IX_ETH_DB_MAC_KEY;
keyType[IX_ETH_DB_FILTERING_VLAN_RECORD] = IX_ETH_DB_MAC_KEY;
keyType[IX_ETH_DB_ALL_FILTERING_RECORDS] = IX_ETH_DB_MAC_KEY;
keyType[IX_ETH_DB_WIFI_RECORD] = IX_ETH_DB_MAC_PORT_KEY;
keyType[IX_ETH_DB_FIREWALL_RECORD] = IX_ETH_DB_MAC_PORT_KEY;
return 5;
}
/**
* @brief Sets a user-defined field into a database record
*
* Note that this function is fully documented in the main component
* header file.
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBUserFieldSet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void *field)
{
HashNode *result = NULL;
if (macAddr == NULL)
{
return IX_ETH_DB_INVALID_ARG;
}
if (recordType == IX_ETH_DB_FILTERING_RECORD)
{
result = ixEthDBSearch(macAddr, recordType);
}
else if (recordType == IX_ETH_DB_FILTERING_VLAN_RECORD)
{
result = ixEthDBVlanSearch(macAddr, vlanID, recordType);
}
else if (recordType == IX_ETH_DB_WIFI_RECORD || recordType == IX_ETH_DB_FIREWALL_RECORD)
{
IX_ETH_DB_CHECK_PORT_EXISTS(portID);
result = ixEthDBPortSearch(macAddr, portID, recordType);
}
else
{
return IX_ETH_DB_INVALID_ARG;
}
if (result == NULL)
{
return IX_ETH_DB_NO_SUCH_ADDR;
}
((MacDescriptor *) result->data)->user = field;
ixEthDBReleaseHashNode(result);
return IX_ETH_DB_SUCCESS;
}
/**
* @brief Retrieves a user-defined field from a database record
*
* Note that this function is fully documented in the main component
* header file.
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBUserFieldGet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void **field)
{
HashNode *result = NULL;
if (macAddr == NULL || field == NULL)
{
return IX_ETH_DB_INVALID_ARG;
}
if (recordType == IX_ETH_DB_FILTERING_RECORD)
{
result = ixEthDBSearch(macAddr, recordType);
}
else if (recordType == IX_ETH_DB_FILTERING_VLAN_RECORD)
{
result = ixEthDBVlanSearch(macAddr, vlanID, recordType);
}
else if (recordType == IX_ETH_DB_WIFI_RECORD || recordType == IX_ETH_DB_FIREWALL_RECORD)
{
IX_ETH_DB_CHECK_PORT_EXISTS(portID);
result = ixEthDBPortSearch(macAddr, portID, recordType);
}
else
{
return IX_ETH_DB_INVALID_ARG;
}
if (result == NULL)
{
return IX_ETH_DB_NO_SUCH_ADDR;
}
*field = ((MacDescriptor *) result->data)->user;
ixEthDBReleaseHashNode(result);
return IX_ETH_DB_SUCCESS;
}

520
cpu/ixp/npe/IxEthDBEvents.c Normal file
View file

@ -0,0 +1,520 @@
/**
* @file IxEthDBEvents.c
*
* @brief Implementation of the event processor component
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#include <IxNpeMh.h>
#include <IxFeatureCtrl.h>
#include "IxEthDB_p.h"
/* forward prototype declarations */
IX_ETH_DB_PUBLIC void ixEthDBEventProcessorLoop(void *);
IX_ETH_DB_PUBLIC void ixEthDBNPEEventCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg);
IX_ETH_DB_PRIVATE void ixEthDBProcessEvent(PortEvent *local_event, IxEthDBPortMap triggerPorts);
IX_ETH_DB_PRIVATE IxEthDBStatus ixEthDBTriggerPortUpdate(UINT32 eventType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, BOOL staticEntry);
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBStartLearningFunction(void);
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBStopLearningFunction(void);
/* data */
IX_ETH_DB_PRIVATE IxOsalSemaphore eventQueueSemaphore;
IX_ETH_DB_PRIVATE PortEventQueue eventQueue;
IX_ETH_DB_PRIVATE IxOsalMutex eventQueueLock;
IX_ETH_DB_PRIVATE IxOsalMutex portUpdateLock;
IX_ETH_DB_PRIVATE BOOL ixEthDBLearningShutdown = FALSE;
IX_ETH_DB_PRIVATE BOOL ixEthDBEventProcessorRunning = FALSE;
/* imported data */
extern HashTable dbHashtable;
/**
* @brief initializes the event processor
*
* Initializes the event processor queue and processing thread.
* Called from ixEthDBInit() DB-subcomponent master init function.
*
* @warning do not call directly
*
* @retval IX_ETH_DB_SUCCESS initialization was successful
* @retval IX_ETH_DB_FAIL initialization failed (OSAL or mutex init failure)
*
* @internal
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBEventProcessorInit(void)
{
if (ixOsalMutexInit(&portUpdateLock) != IX_SUCCESS)
{
return IX_ETH_DB_FAIL;
}
if (ixOsalMutexInit(&eventQueueLock) != IX_SUCCESS)
{
return IX_ETH_DB_FAIL;
}
if (IX_FEATURE_CTRL_SWCONFIG_ENABLED ==
ixFeatureCtrlSwConfigurationCheck (IX_FEATURECTRL_ETH_LEARNING))
{
/* start processor loop thread */
if (ixEthDBStartLearningFunction() != IX_ETH_DB_SUCCESS)
{
return IX_ETH_DB_FAIL;
}
}
return IX_ETH_DB_SUCCESS;
}
/**
* @brief initializes the event queue and the event processor
*
* This function is called by the component initialization
* function, ixEthDBInit().
*
* @warning do not call directly
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully or IX_ETH_DB_FAIL otherwise
*
* @internal
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBStartLearningFunction(void)
{
IxOsalThread eventProcessorThread;
IxOsalThreadAttr threadAttr;
threadAttr.name = "EthDB event thread";
threadAttr.stackSize = 32 * 1024; /* 32kbytes */
threadAttr.priority = 128;
/* reset event queue */
ixOsalMutexLock(&eventQueueLock, IX_OSAL_WAIT_FOREVER);
RESET_QUEUE(&eventQueue);
ixOsalMutexUnlock(&eventQueueLock);
/* init event queue semaphore */
if (ixOsalSemaphoreInit(&eventQueueSemaphore, 0) != IX_SUCCESS)
{
return IX_ETH_DB_FAIL;
}
ixEthDBLearningShutdown = FALSE;
/* create processor loop thread */
if (ixOsalThreadCreate(&eventProcessorThread, &threadAttr, ixEthDBEventProcessorLoop, NULL) != IX_SUCCESS)
{
return IX_ETH_DB_FAIL;
}
/* start event processor */
ixOsalThreadStart(&eventProcessorThread);
return IX_ETH_DB_SUCCESS;
}
/**
* @brief stops the event processor
*
* Stops the event processor and frees the event queue semaphore
* Called by the component de-initialization function, ixEthDBUnload()
*
* @warning do not call directly
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully or IX_ETH_DB_FAIL otherwise;
*
* @internal
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBStopLearningFunction(void)
{
ixEthDBLearningShutdown = TRUE;
/* wake up event processing loop to actually process the shutdown event */
ixOsalSemaphorePost(&eventQueueSemaphore);
if (ixOsalSemaphoreDestroy(&eventQueueSemaphore) != IX_SUCCESS)
{
return IX_ETH_DB_FAIL;
}
return IX_ETH_DB_SUCCESS;
}
/**
* @brief default NPE event processing callback
*
* @param npeID ID of the NPE that generated the event
* @param msg NPE message (encapsulated event)
*
* Creates an event object on the Ethernet event processor queue
* and signals the new event by incrementing the event queue semaphore.
* Events are processed by @ref ixEthDBEventProcessorLoop() which runs
* at user level.
*
* @see ixEthDBEventProcessorLoop()
*
* @warning do not call directly
*
* @internal
*/
IX_ETH_DB_PUBLIC
void ixEthDBNPEEventCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg)
{
PortEvent *local_event;
IX_ETH_DB_IRQ_EVENTS_TRACE("DB: (Events) new event received by processor callback from port %d, id 0x%X\n", IX_ETH_DB_NPE_TO_PORT_ID(npeID), NPE_MSG_ID(msg), 0, 0, 0, 0);
if (CAN_ENQUEUE(&eventQueue))
{
TEST_FIXTURE_LOCK_EVENT_QUEUE;
local_event = QUEUE_HEAD(&eventQueue);
/* create event structure on queue */
local_event->eventType = NPE_MSG_ID(msg);
local_event->portID = IX_ETH_DB_NPE_TO_PORT_ID(npeID);
/* update queue */
PUSH_UPDATE_QUEUE(&eventQueue);
TEST_FIXTURE_UNLOCK_EVENT_QUEUE;
IX_ETH_DB_IRQ_EVENTS_TRACE("DB: (Events) Waking up main processor loop...\n", 0, 0, 0, 0, 0, 0);
/* increment event queue semaphore */
ixOsalSemaphorePost(&eventQueueSemaphore);
}
else
{
IX_ETH_DB_IRQ_EVENTS_TRACE("DB: (Events) Warning: could not enqueue event (overflow)\n", 0, 0, 0, 0, 0, 0);
}
}
/**
* @brief Ethernet event processor loop
*
* Extracts at most EVENT_PROCESSING_LIMIT batches of events and
* sends them for processing to @ref ixEthDBProcessEvent().
* Triggers port updates which normally follow learning events.
*
* @warning do not call directly, executes in separate thread
*
* @internal
*/
IX_ETH_DB_PUBLIC
void ixEthDBEventProcessorLoop(void *unused1)
{
IxEthDBPortMap triggerPorts;
IxEthDBPortId portIndex;
ixEthDBEventProcessorRunning = TRUE;
IX_ETH_DB_EVENTS_TRACE("DB: (Events) Event processor loop was started\n");
while (!ixEthDBLearningShutdown)
{
BOOL keepProcessing = TRUE;
UINT32 processedEvents = 0;
IX_ETH_DB_EVENTS_VERBOSE_TRACE("DB: (Events) Waiting for new learning event...\n");
ixOsalSemaphoreWait(&eventQueueSemaphore, IX_OSAL_WAIT_FOREVER);
IX_ETH_DB_EVENTS_VERBOSE_TRACE("DB: (Events) Received new event\n");
if (!ixEthDBLearningShutdown)
{
/* port update handling */
SET_EMPTY_DEPENDENCY_MAP(triggerPorts);
while (keepProcessing)
{
PortEvent local_event;
UINT32 intLockKey;
/* lock queue */
ixOsalMutexLock(&eventQueueLock, IX_OSAL_WAIT_FOREVER);
/* lock NPE interrupts */
intLockKey = ixOsalIrqLock();
/* extract event */
local_event = *(QUEUE_TAIL(&eventQueue));
SHIFT_UPDATE_QUEUE(&eventQueue);
ixOsalIrqUnlock(intLockKey);
ixOsalMutexUnlock(&eventQueueLock);
IX_ETH_DB_EVENTS_TRACE("DB: (Events) Processing event with ID 0x%X\n", local_event.eventType);
ixEthDBProcessEvent(&local_event, triggerPorts);
processedEvents++;
if (processedEvents > EVENT_PROCESSING_LIMIT /* maximum burst reached? */
|| ixOsalSemaphoreTryWait(&eventQueueSemaphore) != IX_SUCCESS) /* or empty queue? */
{
keepProcessing = FALSE;
}
}
ixEthDBUpdatePortLearningTrees(triggerPorts);
}
}
/* turn off automatic updates */
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
{
ixEthDBPortInfo[portIndex].updateMethod.updateEnabled = FALSE;
}
ixEthDBEventProcessorRunning = FALSE;
}
/**
* @brief event processor routine
*
* @param event event to be processed
* @param triggerPorts port map accumulating ports to be updated
*
* Processes learning events by synchronizing the database with
* newly learnt data. Called only by @ref ixEthDBEventProcessorLoop().
*
* @warning do not call directly
*
* @internal
*/
IX_ETH_DB_PRIVATE
void ixEthDBProcessEvent(PortEvent *local_event, IxEthDBPortMap triggerPorts)
{
MacDescriptor recordTemplate;
switch (local_event->eventType)
{
case IX_ETH_DB_ADD_FILTERING_RECORD:
/* add record */
memset(&recordTemplate, 0, sizeof (recordTemplate));
memcpy(recordTemplate.macAddress, local_event->macAddr.macAddress, sizeof (IxEthDBMacAddr));
recordTemplate.type = IX_ETH_DB_FILTERING_RECORD;
recordTemplate.portID = local_event->portID;
recordTemplate.recordData.filteringData.staticEntry = local_event->staticEntry;
ixEthDBAdd(&recordTemplate, triggerPorts);
IX_ETH_DB_EVENTS_TRACE("DB: (Events) Added record on port %d\n", local_event->portID);
break;
case IX_ETH_DB_REMOVE_FILTERING_RECORD:
/* remove record */
memset(&recordTemplate, 0, sizeof (recordTemplate));
memcpy(recordTemplate.macAddress, local_event->macAddr.macAddress, sizeof (IxEthDBMacAddr));
recordTemplate.type = IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD;
ixEthDBRemove(&recordTemplate, triggerPorts);
IX_ETH_DB_EVENTS_TRACE("DB: (Events) Removed record on port %d\n", local_event->portID);
break;
default:
/* can't handle/not interested in this event type */
ERROR_LOG("DB: (Events) Event processor received an unknown event type (0x%X)\n", local_event->eventType);
return;
}
}
/**
* @brief asynchronously adds a filtering record
* by posting an ADD_FILTERING_RECORD event to the event queue
*
* @param macAddr MAC address of the new record
* @param portID port ID of the new record
* @param staticEntry TRUE if record is static, FALSE if dynamic
*
* @return IX_ETH_DB_SUCCESS if the event creation was
* successfull or IX_ETH_DB_BUSY if the event queue is full
*
* @internal
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBTriggerAddPortUpdate(IxEthDBMacAddr *macAddr, IxEthDBPortId portID, BOOL staticEntry)
{
MacDescriptor reference;
TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER;
/* fill search fields */
memcpy(reference.macAddress, macAddr, sizeof (IxEthDBMacAddr));
reference.portID = portID;
/* set acceptable record types */
reference.type = IX_ETH_DB_ALL_FILTERING_RECORDS;
if (ixEthDBPeekHashEntry(&dbHashtable, IX_ETH_DB_MAC_PORT_KEY, &reference) == IX_ETH_DB_SUCCESS)
{
/* already have an identical record */
return IX_ETH_DB_SUCCESS;
}
else
{
return ixEthDBTriggerPortUpdate(IX_ETH_DB_ADD_FILTERING_RECORD, macAddr, portID, staticEntry);
}
}
/**
* @brief asynchronously removes a filtering record
* by posting a REMOVE_FILTERING_RECORD event to the event queue
*
* @param macAddr MAC address of the record to remove
* @param portID port ID of the record to remove
*
* @return IX_ETH_DB_SUCCESS if the event creation was
* successfull or IX_ETH_DB_BUSY if the event queue is full
*
* @internal
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBTriggerRemovePortUpdate(IxEthDBMacAddr *macAddr, IxEthDBPortId portID)
{
if (ixEthDBPeek(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS) != IX_ETH_DB_NO_SUCH_ADDR)
{
return ixEthDBTriggerPortUpdate(IX_ETH_DB_REMOVE_FILTERING_RECORD, macAddr, portID, FALSE);
}
else
{
return IX_ETH_DB_NO_SUCH_ADDR;
}
}
/**
* @brief adds an ADD or REMOVE event to the main event queue
*
* @param eventType event type - IX_ETH_DB_ADD_FILTERING_RECORD
* to add and IX_ETH_DB_REMOVE_FILTERING_RECORD to remove a
* record.
*
* @return IX_ETH_DB_SUCCESS if the event was successfully
* sent or IX_ETH_DB_BUSY if the event queue is full
*
* @internal
*/
IX_ETH_DB_PRIVATE
IxEthDBStatus ixEthDBTriggerPortUpdate(UINT32 eventType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, BOOL staticEntry)
{
UINT32 intLockKey;
/* lock interrupts to protect queue */
intLockKey = ixOsalIrqLock();
if (CAN_ENQUEUE(&eventQueue))
{
PortEvent *queueEvent = QUEUE_HEAD(&eventQueue);
/* update fields on the queue */
memcpy(queueEvent->macAddr.macAddress, macAddr->macAddress, sizeof (IxEthDBMacAddr));
queueEvent->eventType = eventType;
queueEvent->portID = portID;
queueEvent->staticEntry = staticEntry;
PUSH_UPDATE_QUEUE(&eventQueue);
/* imcrement event queue semaphore */
ixOsalSemaphorePost(&eventQueueSemaphore);
/* unlock interrupts */
ixOsalIrqUnlock(intLockKey);
return IX_ETH_DB_SUCCESS;
}
else /* event queue full */
{
/* unlock interrupts */
ixOsalIrqUnlock(intLockKey);
return IX_ETH_DB_BUSY;
}
}
/**
* @brief Locks learning tree updates and port disable
*
*
* This function locks portUpdateLock single mutex. It is primarily used
* to avoid executing 'port disable' during ELT maintenance.
*
* @internal
*/
IX_ETH_DB_PUBLIC
void ixEthDBUpdateLock(void)
{
ixOsalMutexLock(&portUpdateLock, IX_OSAL_WAIT_FOREVER);
}
/**
* @brief Unlocks learning tree updates and port disable
*
*
* This function unlocks a portUpdateLock mutex. It is primarily used
* to avoid executing 'port disable' during ELT maintenance.
*
* @internal
*/
IX_ETH_DB_PUBLIC
void ixEthDBUpdateUnlock(void)
{
ixOsalMutexUnlock(&portUpdateLock);
}

View file

@ -0,0 +1,662 @@
/**
* @file IxEthDBFeatures.c
*
* @brief Implementation of the EthDB feature control API
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#include "IxNpeDl.h"
#include "IxEthDBQoS.h"
#include "IxEthDB_p.h"
/**
* @brief scans the capabilities of the loaded NPE images
*
* This function MUST be called by the ixEthDBInit() function.
* No EthDB features (including learning and filtering) are enabled
* before this function is called.
*
* @return none
*
* @internal
*/
IX_ETH_DB_PUBLIC
void ixEthDBFeatureCapabilityScan(void)
{
IxNpeDlImageId imageId, npeAImageId;
IxEthDBPortId portIndex;
PortInfo *portInfo;
IxEthDBPriorityTable defaultPriorityTable;
IX_STATUS result;
UINT32 queueIndex;
UINT32 queueStructureIndex;
UINT32 trafficClassDefinitionIndex;
/* read version of NPE A - required to set the AQM queues for B and C */
npeAImageId.functionalityId = 0;
ixNpeDlLoadedImageGet(IX_NPEDL_NPEID_NPEA, &npeAImageId);
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
{
IxNpeMhMessage msg;
portInfo = &ixEthDBPortInfo[portIndex];
/* check and bypass if NPE B or C is fused out */
if (ixEthDBSingleEthNpeCheck(portIndex) != IX_ETH_DB_SUCCESS) continue;
/* all ports are capable of LEARNING by default */
portInfo->featureCapability |= IX_ETH_DB_LEARNING;
portInfo->featureStatus |= IX_ETH_DB_LEARNING;
if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE)
{
if (ixNpeDlLoadedImageGet(IX_ETH_DB_PORT_ID_TO_NPE(portIndex), &imageId) != IX_SUCCESS)
{
WARNING_LOG("DB: (FeatureScan) NpeDl did not provide the image ID for NPE port %d\n", portIndex);
}
else
{
/* initialize and empty NPE response mutex */
ixOsalMutexInit(&portInfo->npeAckLock);
ixOsalMutexLock(&portInfo->npeAckLock, IX_OSAL_WAIT_FOREVER);
/* check NPE response to GetStatus */
msg.data[0] = IX_ETHNPE_NPE_GETSTATUS << 24;
msg.data[1] = 0;
IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portIndex), msg, result);
if (result != IX_SUCCESS)
{
WARNING_LOG("DB: (FeatureScan) warning, could not send message to the NPE\n");
continue;
}
if (imageId.functionalityId == 0x00
|| imageId.functionalityId == 0x03
|| imageId.functionalityId == 0x04
|| imageId.functionalityId == 0x80)
{
portInfo->featureCapability |= IX_ETH_DB_FILTERING;
portInfo->featureCapability |= IX_ETH_DB_FIREWALL;
portInfo->featureCapability |= IX_ETH_DB_SPANNING_TREE_PROTOCOL;
}
else if (imageId.functionalityId == 0x01
|| imageId.functionalityId == 0x81)
{
portInfo->featureCapability |= IX_ETH_DB_FILTERING;
portInfo->featureCapability |= IX_ETH_DB_FIREWALL;
portInfo->featureCapability |= IX_ETH_DB_SPANNING_TREE_PROTOCOL;
portInfo->featureCapability |= IX_ETH_DB_VLAN_QOS;
}
else if (imageId.functionalityId == 0x02
|| imageId.functionalityId == 0x82)
{
portInfo->featureCapability |= IX_ETH_DB_WIFI_HEADER_CONVERSION;
portInfo->featureCapability |= IX_ETH_DB_FIREWALL;
portInfo->featureCapability |= IX_ETH_DB_SPANNING_TREE_PROTOCOL;
portInfo->featureCapability |= IX_ETH_DB_VLAN_QOS;
}
/* reset AQM queues */
memset(portInfo->ixEthDBTrafficClassAQMAssignments, 0, sizeof (portInfo->ixEthDBTrafficClassAQMAssignments));
/* ensure there's at least one traffic class record in the definition table, otherwise we have no default case, hence no queues */
IX_ENSURE(sizeof (ixEthDBTrafficClassDefinitions) != 0, "DB: no traffic class definitions found, check IxEthDBQoS.h");
/* find the traffic class definition index compatible with the current NPE A functionality ID */
for (trafficClassDefinitionIndex = 0 ;
trafficClassDefinitionIndex < sizeof (ixEthDBTrafficClassDefinitions) / sizeof (ixEthDBTrafficClassDefinitions[0]);
trafficClassDefinitionIndex++)
{
if (ixEthDBTrafficClassDefinitions[trafficClassDefinitionIndex][IX_ETH_DB_NPE_A_FUNCTIONALITY_ID_INDEX] == npeAImageId.functionalityId)
{
/* found it */
break;
}
}
/* select the default case if we went over the array boundary */
if (trafficClassDefinitionIndex == sizeof (ixEthDBTrafficClassDefinitions) / sizeof (ixEthDBTrafficClassDefinitions[0]))
{
trafficClassDefinitionIndex = 0; /* the first record is the default case */
}
/* select queue assignment structure based on the traffic class configuration index */
queueStructureIndex = ixEthDBTrafficClassDefinitions[trafficClassDefinitionIndex][IX_ETH_DB_QUEUE_ASSIGNMENT_INDEX];
/* only traffic class 0 is active at initialization time */
portInfo->ixEthDBTrafficClassCount = 1;
/* enable port, VLAN and Firewall feature bits to initialize QoS/VLAN/Firewall configuration */
portInfo->featureStatus |= IX_ETH_DB_VLAN_QOS;
portInfo->featureStatus |= IX_ETH_DB_FIREWALL;
portInfo->enabled = TRUE;
#define CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */
#ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */
/* set VLAN initial configuration (permissive) */
if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0) /* QoS-enabled image */
{
/* QoS capable */
portInfo->ixEthDBTrafficClassAvailable = ixEthDBTrafficClassDefinitions[trafficClassDefinitionIndex][IX_ETH_DB_TRAFFIC_CLASS_COUNT_INDEX];
/* set AQM queues */
for (queueIndex = 0 ; queueIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; queueIndex++)
{
portInfo->ixEthDBTrafficClassAQMAssignments[queueIndex] = ixEthDBQueueAssignments[queueStructureIndex][queueIndex];
}
/* set default PVID (0) and default traffic class 0 */
ixEthDBPortVlanTagSet(portIndex, 0);
/* enable reception of all frames */
ixEthDBAcceptableFrameTypeSet(portIndex, IX_ETH_DB_ACCEPT_ALL_FRAMES);
/* clear full VLAN membership */
ixEthDBPortVlanMembershipRangeRemove(portIndex, 0, IX_ETH_DB_802_1Q_MAX_VLAN_ID);
/* clear TTI table - no VLAN tagged frames will be transmitted */
ixEthDBEgressVlanRangeTaggingEnabledSet(portIndex, 0, 4094, FALSE);
/* set membership on 0, otherwise no Tx or Rx is working */
ixEthDBPortVlanMembershipAdd(portIndex, 0);
}
else /* QoS not available in this image */
#endif /* test-only */
{
/* initialize traffic class availability (only class 0 is available) */
portInfo->ixEthDBTrafficClassAvailable = 1;
/* point all AQM queues to traffic class 0 */
for (queueIndex = 0 ; queueIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; queueIndex++)
{
portInfo->ixEthDBTrafficClassAQMAssignments[queueIndex] =
ixEthDBQueueAssignments[queueStructureIndex][0];
}
}
#ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */
/* download priority mapping table and Rx queue configuration */
memset (defaultPriorityTable, 0, sizeof (defaultPriorityTable));
ixEthDBPriorityMappingTableSet(portIndex, defaultPriorityTable);
#endif
/* by default we turn off invalid source MAC address filtering */
ixEthDBFirewallInvalidAddressFilterEnable(portIndex, FALSE);
/* disable port, VLAN, Firewall feature bits */
portInfo->featureStatus &= ~IX_ETH_DB_VLAN_QOS;
portInfo->featureStatus &= ~IX_ETH_DB_FIREWALL;
portInfo->enabled = FALSE;
/* enable filtering by default if present */
if ((portInfo->featureCapability & IX_ETH_DB_FILTERING) != 0)
{
portInfo->featureStatus |= IX_ETH_DB_FILTERING;
}
}
}
}
}
/**
* @brief returns the capability of a port
*
* @param portID ID of the port
* @param featureSet location to store the port capability in
*
* This function will save the capability set of the given port
* into the given location. Capabilities are bit-ORed, each representing
* a bit of the feature set.
*
* Note that this function is documented in the main component
* public header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed successfully
* or IX_ETH_DB_INVALID_PORT if the given port is invalid
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFeatureCapabilityGet(IxEthDBPortId portID, IxEthDBFeature *featureSet)
{
IX_ETH_DB_CHECK_PORT_INITIALIZED(portID);
IX_ETH_DB_CHECK_REFERENCE(featureSet);
*featureSet = ixEthDBPortInfo[portID].featureCapability;
return IX_ETH_DB_SUCCESS;
}
/**
* @brief enables or disables a port capability
*
* @param portID ID of the port
* @param feature feature to enable or disable
* @param enabled TRUE to enable the selected feature or FALSE to disable it
*
* Note that this function is documented in the main component
* header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFeatureEnable(IxEthDBPortId portID, IxEthDBFeature feature, BOOL enable)
{
PortInfo *portInfo;
IxEthDBPriorityTable defaultPriorityTable;
IxEthDBVlanSet vlanSet;
IxEthDBStatus status = IX_ETH_DB_SUCCESS;
BOOL portEnabled;
IX_ETH_DB_CHECK_PORT_INITIALIZED(portID);
portInfo = &ixEthDBPortInfo[portID];
portEnabled = portInfo->enabled;
/* check that only one feature is selected */
if (!ixEthDBCheckSingleBitValue(feature))
{
return IX_ETH_DB_FEATURE_UNAVAILABLE;
}
/* port capable of this feature? */
if ((portInfo->featureCapability & feature) == 0)
{
return IX_ETH_DB_FEATURE_UNAVAILABLE;
}
/* mutual exclusion between learning and WiFi header conversion */
if (enable && ((feature | portInfo->featureStatus) & (IX_ETH_DB_FILTERING | IX_ETH_DB_WIFI_HEADER_CONVERSION))
== (IX_ETH_DB_FILTERING | IX_ETH_DB_WIFI_HEADER_CONVERSION))
{
return IX_ETH_DB_NO_PERMISSION;
}
/* learning must be enabled before filtering */
if (enable && (feature == IX_ETH_DB_FILTERING) && ((portInfo->featureStatus & IX_ETH_DB_LEARNING) == 0))
{
return IX_ETH_DB_NO_PERMISSION;
}
/* filtering must be disabled before learning */
if (!enable && (feature == IX_ETH_DB_LEARNING) && ((portInfo->featureStatus & IX_ETH_DB_FILTERING) != 0))
{
return IX_ETH_DB_NO_PERMISSION;
}
/* redundant enabling or disabling */
if ((!enable && ((portInfo->featureStatus & feature) == 0))
|| (enable && ((portInfo->featureStatus & feature) != 0)))
{
/* do nothing */
return IX_ETH_DB_SUCCESS;
}
/* force port enabled */
portInfo->enabled = TRUE;
if (enable)
{
/* turn on enable bit */
portInfo->featureStatus |= feature;
#ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */
/* if this is VLAN/QoS set the default priority table */
if (feature == IX_ETH_DB_VLAN_QOS)
{
/* turn on VLAN/QoS (most permissive mode):
- set default 802.1Q priority mapping table, in accordance to the
availability of traffic classes
- set the acceptable frame filter to accept all
- set the Ingress tagging mode to pass-through
- set full VLAN membership list
- set full TTI table
- set the default 802.1Q tag to 0 (VLAN ID 0, Pri 0, CFI 0)
- enable TPID port extraction
*/
portInfo->ixEthDBTrafficClassCount = portInfo->ixEthDBTrafficClassAvailable;
/* set default 802.1Q priority mapping table - note that C indexing starts from 0, so we substract 1 here */
memcpy (defaultPriorityTable,
(const void *) ixEthIEEE802_1QUserPriorityToTrafficClassMapping[portInfo->ixEthDBTrafficClassCount - 1],
sizeof (defaultPriorityTable));
/* update priority mapping and AQM queue assignments */
status = ixEthDBPriorityMappingTableSet(portID, defaultPriorityTable);
if (status == IX_ETH_DB_SUCCESS)
{
status = ixEthDBAcceptableFrameTypeSet(portID, IX_ETH_DB_ACCEPT_ALL_FRAMES);
}
if (status == IX_ETH_DB_SUCCESS)
{
status = ixEthDBIngressVlanTaggingEnabledSet(portID, IX_ETH_DB_PASS_THROUGH);
}
/* set membership and TTI tables */
memset (vlanSet, 0xFF, sizeof (vlanSet));
if (status == IX_ETH_DB_SUCCESS)
{
/* use the internal function to bypass PVID check */
status = ixEthDBPortVlanTableSet(portID, portInfo->vlanMembership, vlanSet);
}
if (status == IX_ETH_DB_SUCCESS)
{
/* use the internal function to bypass PVID check */
status = ixEthDBPortVlanTableSet(portID, portInfo->transmitTaggingInfo, vlanSet);
}
/* reset the PVID */
if (status == IX_ETH_DB_SUCCESS)
{
status = ixEthDBPortVlanTagSet(portID, 0);
}
/* enable TPID port extraction */
if (status == IX_ETH_DB_SUCCESS)
{
status = ixEthDBVlanPortExtractionEnable(portID, TRUE);
}
}
else if (feature == IX_ETH_DB_FIREWALL)
#endif
{
/* firewall starts in black-list mode unless otherwise configured before *
* note that invalid source MAC address filtering is disabled by default */
if (portInfo->firewallMode != IX_ETH_DB_FIREWALL_BLACK_LIST
&& portInfo->firewallMode != IX_ETH_DB_FIREWALL_WHITE_LIST)
{
status = ixEthDBFirewallModeSet(portID, IX_ETH_DB_FIREWALL_BLACK_LIST);
if (status == IX_ETH_DB_SUCCESS)
{
status = ixEthDBFirewallInvalidAddressFilterEnable(portID, FALSE);
}
}
}
if (status != IX_ETH_DB_SUCCESS)
{
/* checks failed, disable */
portInfo->featureStatus &= ~feature;
}
}
else
{
/* turn off features */
if (feature == IX_ETH_DB_FIREWALL)
{
/* turning off the firewall is equivalent to:
- set to black-list mode
- clear all the entries and download the new table
- turn off the invalid source address checking
*/
status = ixEthDBDatabaseClear(portID, IX_ETH_DB_FIREWALL_RECORD);
if (status == IX_ETH_DB_SUCCESS)
{
status = ixEthDBFirewallModeSet(portID, IX_ETH_DB_FIREWALL_BLACK_LIST);
}
if (status == IX_ETH_DB_SUCCESS)
{
status = ixEthDBFirewallInvalidAddressFilterEnable(portID, FALSE);
}
if (status == IX_ETH_DB_SUCCESS)
{
status = ixEthDBFirewallTableDownload(portID);
}
}
else if (feature == IX_ETH_DB_WIFI_HEADER_CONVERSION)
{
/* turn off header conversion */
status = ixEthDBDatabaseClear(portID, IX_ETH_DB_WIFI_RECORD);
if (status == IX_ETH_DB_SUCCESS)
{
status = ixEthDBWiFiConversionTableDownload(portID);
}
}
#ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */
else if (feature == IX_ETH_DB_VLAN_QOS)
{
/* turn off VLAN/QoS:
- set a priority mapping table with one traffic class
- set the acceptable frame filter to accept all
- set the Ingress tagging mode to pass-through
- clear the VLAN membership list
- clear the TTI table
- set the default 802.1Q tag to 0 (VLAN ID 0, Pri 0, CFI 0)
- disable TPID port extraction
*/
/* initialize all => traffic class 0 priority mapping table */
memset (defaultPriorityTable, 0, sizeof (defaultPriorityTable));
portInfo->ixEthDBTrafficClassCount = 1;
status = ixEthDBPriorityMappingTableSet(portID, defaultPriorityTable);
if (status == IX_ETH_DB_SUCCESS)
{
status = ixEthDBAcceptableFrameTypeSet(portID, IX_ETH_DB_ACCEPT_ALL_FRAMES);
}
if (status == IX_ETH_DB_SUCCESS)
{
status = ixEthDBIngressVlanTaggingEnabledSet(portID, IX_ETH_DB_PASS_THROUGH);
}
/* clear membership and TTI tables */
memset (vlanSet, 0, sizeof (vlanSet));
if (status == IX_ETH_DB_SUCCESS)
{
/* use the internal function to bypass PVID check */
status = ixEthDBPortVlanTableSet(portID, portInfo->vlanMembership, vlanSet);
}
if (status == IX_ETH_DB_SUCCESS)
{
/* use the internal function to bypass PVID check */
status = ixEthDBPortVlanTableSet(portID, portInfo->transmitTaggingInfo, vlanSet);
}
/* reset the PVID */
if (status == IX_ETH_DB_SUCCESS)
{
status = ixEthDBPortVlanTagSet(portID, 0);
}
/* disable TPID port extraction */
if (status == IX_ETH_DB_SUCCESS)
{
status = ixEthDBVlanPortExtractionEnable(portID, FALSE);
}
}
#endif
if (status == IX_ETH_DB_SUCCESS)
{
/* checks passed, disable */
portInfo->featureStatus &= ~feature;
}
}
/* restore port enabled state */
portInfo->enabled = portEnabled;
return status;
}
/**
* @brief returns the status of a feature
*
* @param portID port ID
* @param present location to store a boolean value indicating
* if the feature is present (TRUE) or not (FALSE)
* @param enabled location to store a booleam value indicating
* if the feature is present (TRUE) or not (FALSE)
*
* Note that this function is documented in the main component
* header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFeatureStatusGet(IxEthDBPortId portID, IxEthDBFeature feature, BOOL *present, BOOL *enabled)
{
PortInfo *portInfo;
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_REFERENCE(present);
IX_ETH_DB_CHECK_REFERENCE(enabled);
portInfo = &ixEthDBPortInfo[portID];
*present = (portInfo->featureCapability & feature) != 0;
*enabled = (portInfo->featureStatus & feature) != 0;
return IX_ETH_DB_SUCCESS;
}
/**
* @brief returns the value of an EthDB property
*
* @param portID ID of the port
* @param feature feature owning the property
* @param property ID of the property
* @param type location to store the property type into
* @param value location to store the property value into
*
* Note that this function is documented in the main component
* header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFeaturePropertyGet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, IxEthDBPropertyType *type, void *value)
{
IX_ETH_DB_CHECK_PORT_EXISTS(portID);
IX_ETH_DB_CHECK_REFERENCE(type);
IX_ETH_DB_CHECK_REFERENCE(value);
if (feature == IX_ETH_DB_VLAN_QOS)
{
if (property == IX_ETH_DB_QOS_TRAFFIC_CLASS_COUNT_PROPERTY)
{
* (UINT32 *) value = ixEthDBPortInfo[portID].ixEthDBTrafficClassCount;
*type = IX_ETH_DB_INTEGER_PROPERTY;
return IX_ETH_DB_SUCCESS;
}
else if (property >= IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY
&& property <= IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY)
{
UINT32 classDelta = property - IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY;
if (classDelta >= ixEthDBPortInfo[portID].ixEthDBTrafficClassCount)
{
return IX_ETH_DB_FAIL;
}
* (UINT32 *) value = ixEthDBPortInfo[portID].ixEthDBTrafficClassAQMAssignments[classDelta];
*type = IX_ETH_DB_INTEGER_PROPERTY;
return IX_ETH_DB_SUCCESS;
}
}
return IX_ETH_DB_INVALID_ARG;
}
/**
* @brief sets the value of an EthDB property
*
* @param portID ID of the port
* @param feature feature owning the property
* @param property ID of the property
* @param value location containing the property value
*
* This function implements a private property intended
* only for EthAcc usage. Upon setting the IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE
* property (the value is ignored), the availability of traffic classes is
* frozen to whatever traffic class structure is currently in use.
* This means that if VLAN_QOS has been enabled before EthAcc
* initialization then all the defined traffic classes will be available;
* otherwise only one traffic class (0) will be available.
*
* Note that this function is documented in the main component
* header file, IxEthDB.h as not accepting any parameters. The
* current implementation is only intended for the private use of EthAcc.
*
* Also note that once this function is called the effect is irreversible,
* unless EthDB is complete unloaded and re-initialized.
*
* @return IX_ETH_DB_INVALID_ARG (no read-write properties are
* supported in this release)
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFeaturePropertySet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, void *value)
{
IX_ETH_DB_CHECK_PORT_EXISTS(portID);
if ((feature == IX_ETH_DB_VLAN_QOS) && (property == IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE))
{
ixEthDBPortInfo[portID].ixEthDBTrafficClassAvailable = ixEthDBPortInfo[portID].ixEthDBTrafficClassCount;
return IX_ETH_DB_SUCCESS;
}
return IX_ETH_DB_INVALID_ARG;
}

View file

@ -0,0 +1,266 @@
/**
* @file IxEthDBFirewall.c
*
* @brief Implementation of the firewall API
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#include "IxEthDB_p.h"
/**
* @brief updates the NPE firewall operating mode and
* firewall address table
*
* @param portID ID of the port
* @param epDelta initial entry point for binary searches (NPE optimization)
* @param address address of the firewall MAC address table
*
* This function will send a message to the NPE configuring the
* firewall mode (white list or black list), invalid source
* address filtering and downloading a new MAC address database
* to be used for firewall matching.
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully or IX_ETH_DB_FAIL otherwise
*
* @internal
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFirewallUpdate(IxEthDBPortId portID, void *address, UINT32 epDelta)
{
IxNpeMhMessage message;
IX_STATUS result;
UINT32 mode = 0;
PortInfo *portInfo = &ixEthDBPortInfo[portID];
mode = (portInfo->srcAddressFilterEnabled != FALSE) << 1 | (portInfo->firewallMode == IX_ETH_DB_FIREWALL_WHITE_LIST);
FILL_SETFIREWALLMODE_MSG(message,
IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID),
epDelta,
mode,
IX_OSAL_MMU_VIRT_TO_PHYS(address));
IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
return result;
}
/**
* @brief configures the firewall white list/black list
* access mode
*
* @param portID ID of the port
* @param mode firewall filtering mode (IX_ETH_DB_FIREWALL_WHITE_LIST
* or IX_ETH_DB_FIREWALL_BLACK_LIST)
*
* Note that this function is documented in the main component
* header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFirewallModeSet(IxEthDBPortId portID, IxEthDBFirewallMode mode)
{
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL);
if (mode != IX_ETH_DB_FIREWALL_WHITE_LIST
&& mode != IX_ETH_DB_FIREWALL_BLACK_LIST)
{
return IX_ETH_DB_INVALID_ARG;
}
ixEthDBPortInfo[portID].firewallMode = mode;
return ixEthDBFirewallTableDownload(portID);
}
/**
* @brief enables or disables the invalid source MAC address filter
*
* @param portID ID of the port
* @param enable TRUE to enable invalid source MAC address filtering
* or FALSE to disable it
*
* The invalid source MAC address filter will discard, when enabled,
* frames whose source MAC address is a multicast or the broadcast MAC
* address.
*
* Note that this function is documented in the main component
* header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFirewallInvalidAddressFilterEnable(IxEthDBPortId portID, BOOL enable)
{
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL);
ixEthDBPortInfo[portID].srcAddressFilterEnabled = enable;
return ixEthDBFirewallTableDownload(portID);
}
/**
* @brief adds a firewall record
*
* @param portID ID of the port
* @param macAddr MAC address of the new record
*
* This function will add a new firewall record
* on the specified port, using the specified
* MAC address. If the record already exists this
* function will silently return IX_ETH_DB_SUCCESS,
* although no duplicate records are added.
*
* Note that this function is documented in the main
* component header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFirewallEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
{
MacDescriptor recordTemplate;
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_REFERENCE(macAddr);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL);
memcpy(recordTemplate.macAddress, macAddr, sizeof (IxEthDBMacAddr));
recordTemplate.type = IX_ETH_DB_FIREWALL_RECORD;
recordTemplate.portID = portID;
return ixEthDBAdd(&recordTemplate, NULL);
}
/**
* @brief removes a firewall record
*
* @param portID ID of the port
* @param macAddr MAC address of the record to remove
*
* This function will attempt to remove a firewall
* record from the given port, using the specified
* MAC address.
*
* Note that this function is documented in the main
* component header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully of an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFirewallEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
{
MacDescriptor recordTemplate;
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_REFERENCE(macAddr);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL);
memcpy(recordTemplate.macAddress, macAddr, sizeof (IxEthDBMacAddr));
recordTemplate.type = IX_ETH_DB_FIREWALL_RECORD;
recordTemplate.portID = portID;
return ixEthDBRemove(&recordTemplate, NULL);
}
/**
* @brief downloads the firewall address table to an NPE
*
* @param portID ID of the port
*
* This function will download the firewall address table to
* an NPE port.
*
* Note that this function is documented in the main
* component header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully or IX_ETH_DB_FAIL otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFirewallTableDownload(IxEthDBPortId portID)
{
IxEthDBPortMap query;
IxEthDBStatus result;
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL);
SET_DEPENDENCY_MAP(query, portID);
ixEthDBUpdateLock();
ixEthDBPortInfo[portID].updateMethod.searchTree = ixEthDBQuery(NULL, query, IX_ETH_DB_FIREWALL_RECORD, MAX_FW_SIZE);
result = ixEthDBNPEUpdateHandler(portID, IX_ETH_DB_FIREWALL_RECORD);
ixEthDBUpdateUnlock();
return result;
}

View file

@ -0,0 +1,642 @@
/**
* @file ethHash.c
*
* @brief Hashtable implementation
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#include "IxEthDB_p.h"
#include "IxEthDBLocks_p.h"
/**
* @addtogroup EthDB
*
* @{
*/
/**
* @brief initializes a hash table object
*
* @param hashTable uninitialized hash table structure
* @param numBuckets number of buckets to use
* @param entryHashFunction hash function used
* to hash entire hash node data block (for adding)
* @param matchFunctions array of match functions, indexed on type,
* used to differentiate records with the same hash value
* @param freeFunction function used to free node data blocks
*
* Initializes the given hash table object.
*
* @internal
*/
void ixEthDBInitHash(HashTable *hashTable,
UINT32 numBuckets,
HashFunction entryHashFunction,
MatchFunction *matchFunctions,
FreeFunction freeFunction)
{
UINT32 bucketIndex;
UINT32 hashSize = numBuckets * sizeof(HashNode *);
/* entry hashing, matching and freeing methods */
hashTable->entryHashFunction = entryHashFunction;
hashTable->matchFunctions = matchFunctions;
hashTable->freeFunction = freeFunction;
/* buckets */
hashTable->numBuckets = numBuckets;
/* set to 0 all buckets */
memset(hashTable->hashBuckets, 0, hashSize);
/* init bucket locks - note that initially all mutexes are unlocked after MutexInit()*/
for (bucketIndex = 0 ; bucketIndex < numBuckets ; bucketIndex++)
{
ixOsalFastMutexInit(&hashTable->bucketLocks[bucketIndex]);
}
}
/**
* @brief adds an entry to the hash table
*
* @param hashTable hash table to add the entry to
* @param entry entry to add
*
* The entry will be hashed using the entry hashing function and added to the
* hash table, unless a locking blockage occurs, in which case the caller
* should retry.
*
* @retval IX_ETH_DB_SUCCESS if adding <i>entry</i> has succeeded
* @retval IX_ETH_DB_NOMEM if there's no memory left in the hash node pool
* @retval IX_ETH_DB_BUSY if there's a locking failure on the insertion path
*
* @internal
*/
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBAddHashEntry(HashTable *hashTable, void *entry)
{
UINT32 hashValue = hashTable->entryHashFunction(entry);
UINT32 bucketIndex = hashValue % hashTable->numBuckets;
HashNode *bucket = hashTable->hashBuckets[bucketIndex];
HashNode *newNode;
LockStack locks;
INIT_STACK(&locks);
/* lock bucket */
PUSH_LOCK(&locks, &hashTable->bucketLocks[bucketIndex]);
/* lock insertion element (first in chain), if any */
if (bucket != NULL)
{
PUSH_LOCK(&locks, &bucket->lock);
}
/* get new node */
newNode = ixEthDBAllocHashNode();
if (newNode == NULL)
{
/* unlock everything */
UNROLL_STACK(&locks);
return IX_ETH_DB_NOMEM;
}
/* init lock - note that mutexes are unlocked after MutexInit */
ixOsalFastMutexInit(&newNode->lock);
/* populate new link */
newNode->data = entry;
/* add to bucket */
newNode->next = bucket;
hashTable->hashBuckets[bucketIndex] = newNode;
/* unlock bucket and insertion point */
UNROLL_STACK(&locks);
return IX_ETH_DB_SUCCESS;
}
/**
* @brief removes an entry from the hashtable
*
* @param hashTable hash table to remove entry from
* @param keyType type of record key used for matching
* @param reference reference key used to identify the entry
*
* The reference key will be hashed using the key hashing function,
* the entry is searched using the hashed value and then examined
* against the reference entry using the match function. A positive
* match will trigger the deletion of the entry.
* Locking failures are reported and the caller should retry.
*
* @retval IX_ETH_DB_SUCCESS if the removal was successful
* @retval IX_ETH_DB_NO_SUCH_ADDR if the entry was not found
* @retval IX_ETH_DB_BUSY if a locking failure occured during the process
*
* @internal
*/
IxEthDBStatus ixEthDBRemoveHashEntry(HashTable *hashTable, int keyType, void *reference)
{
UINT32 hashValue = hashTable->entryHashFunction(reference);
UINT32 bucketIndex = hashValue % hashTable->numBuckets;
HashNode *node = hashTable->hashBuckets[bucketIndex];
HashNode *previousNode = NULL;
LockStack locks;
INIT_STACK(&locks);
while (node != NULL)
{
/* try to lock node */
PUSH_LOCK(&locks, &node->lock);
if (hashTable->matchFunctions[keyType](reference, node->data))
{
/* found entry */
if (node->next != NULL)
{
PUSH_LOCK(&locks, &node->next->lock);
}
if (previousNode == NULL)
{
/* node is head of chain */
PUSH_LOCK(&locks, &hashTable->bucketLocks[bucketIndex]);
hashTable->hashBuckets[bucketIndex] = node->next;
POP_LOCK(&locks);
}
else
{
/* relink */
previousNode->next = node->next;
}
UNROLL_STACK(&locks);
/* free node */
hashTable->freeFunction(node->data);
ixEthDBFreeHashNode(node);
return IX_ETH_DB_SUCCESS;
}
else
{
if (previousNode != NULL)
{
/* unlock previous node */
SHIFT_STACK(&locks);
}
/* advance to next element in chain */
previousNode = node;
node = node->next;
}
}
UNROLL_STACK(&locks);
/* not found */
return IX_ETH_DB_NO_SUCH_ADDR;
}
/**
* @brief retrieves an entry from the hash table
*
* @param hashTable hash table to perform the search into
* @param reference search key (a MAC address)
* @param keyType type of record key used for matching
* @param searchResult pointer where a reference to the located hash node
* is placed
*
* Searches the entry with the same key as <i>reference</i> and places the
* pointer to the resulting node in <i>searchResult</i>.
* An implicit write access lock is granted after a search, which gives the
* caller the opportunity to modify the entry.
* Access should be released as soon as possible using @ref ixEthDBReleaseHashNode().
*
* @see ixEthDBReleaseHashNode()
*
* @retval IX_ETH_DB_SUCCESS if the search was completed successfully
* @retval IX_ETH_DB_NO_SUCH_ADDRESS if no entry with the given key was found
* @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case
* the caller should retry
*
* @warning unless the return value is <b>IX_ETH_DB_SUCCESS</b> the searchResult
* location is NOT modified and therefore using a NULL comparison test when the
* value was not properly initialized would be an error
*
* @internal
*/
IxEthDBStatus ixEthDBSearchHashEntry(HashTable *hashTable, int keyType, void *reference, HashNode **searchResult)
{
UINT32 hashValue;
HashNode *node;
hashValue = hashTable->entryHashFunction(reference);
node = hashTable->hashBuckets[hashValue % hashTable->numBuckets];
while (node != NULL)
{
TRY_LOCK(&node->lock);
if (hashTable->matchFunctions[keyType](reference, node->data))
{
*searchResult = node;
return IX_ETH_DB_SUCCESS;
}
else
{
UNLOCK(&node->lock);
node = node->next;
}
}
/* not found */
return IX_ETH_DB_NO_SUCH_ADDR;
}
/**
* @brief reports the existence of an entry in the hash table
*
* @param hashTable hash table to perform the search into
* @param reference search key (a MAC address)
* @param keyType type of record key used for matching
*
* Searches the entry with the same key as <i>reference</i>.
* No implicit write access lock is granted after a search, hence the
* caller cannot access or modify the entry. The result is only temporary.
*
* @see ixEthDBReleaseHashNode()
*
* @retval IX_ETH_DB_SUCCESS if the search was completed successfully
* @retval IX_ETH_DB_NO_SUCH_ADDRESS if no entry with the given key was found
* @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case
* the caller should retry
*
* @internal
*/
IxEthDBStatus ixEthDBPeekHashEntry(HashTable *hashTable, int keyType, void *reference)
{
UINT32 hashValue;
HashNode *node;
hashValue = hashTable->entryHashFunction(reference);
node = hashTable->hashBuckets[hashValue % hashTable->numBuckets];
while (node != NULL)
{
TRY_LOCK(&node->lock);
if (hashTable->matchFunctions[keyType](reference, node->data))
{
UNLOCK(&node->lock);
return IX_ETH_DB_SUCCESS;
}
else
{
UNLOCK(&node->lock);
node = node->next;
}
}
/* not found */
return IX_ETH_DB_NO_SUCH_ADDR;
}
/**
* @brief releases the write access lock
*
* @pre the node should have been obtained via @ref ixEthDBSearchHashEntry()
*
* @see ixEthDBSearchHashEntry()
*
* @internal
*/
void ixEthDBReleaseHashNode(HashNode *node)
{
UNLOCK(&node->lock);
}
/**
* @brief initializes a hash iterator
*
* @param hashTable hash table to be iterated
* @param iterator iterator object
*
* If the initialization is successful the iterator will point to the
* first hash table record (if any).
* Testing if the iterator has not passed the end of the table should be
* done using the IS_ITERATOR_VALID(iteratorPtr) macro.
* An implicit write access lock is granted on the entry pointed by the iterator.
* The access is automatically revoked when the iterator is incremented.
* If the caller decides to terminate the iteration before the end of the table is
* passed then the manual access release method, @ref ixEthDBReleaseHashIterator,
* must be called.
*
* @see ixEthDBReleaseHashIterator()
*
* @retval IX_ETH_DB_SUCCESS if initialization was successful and the iterator points
* to the first valid table node
* @retval IX_ETH_DB_FAIL if the table is empty
* @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case the caller
* should retry
*
* @warning do not use ixEthDBReleaseHashNode() on entries pointed by the iterator, as this
* might place the database in a permanent invalid lock state
*
* @internal
*/
IxEthDBStatus ixEthDBInitHashIterator(HashTable *hashTable, HashIterator *iterator)
{
iterator->bucketIndex = 0;
iterator->node = NULL;
iterator->previousNode = NULL;
return ixEthDBIncrementHashIterator(hashTable, iterator);
}
/**
* @brief releases the write access locks of the iterator nodes
*
* @warning use of this function is required only when the caller terminates an iteration
* before reaching the end of the table
*
* @see ixEthDBInitHashIterator()
* @see ixEthDBIncrementHashIterator()
*
* @param iterator iterator whose node(s) should be unlocked
*
* @internal
*/
void ixEthDBReleaseHashIterator(HashIterator *iterator)
{
if (iterator->previousNode != NULL)
{
UNLOCK(&iterator->previousNode->lock);
}
if (iterator->node != NULL)
{
UNLOCK(&iterator->node->lock);
}
}
/**
* @brief incremenents an iterator so that it points to the next valid entry of the table
* (if any)
*
* @param hashTable hash table to iterate
* @param iterator iterator object
*
* @pre the iterator object must be initialized using @ref ixEthDBInitHashIterator()
*
* If the increment operation is successful the iterator will point to the
* next hash table record (if any).
* Testing if the iterator has not passed the end of the table should be
* done using the IS_ITERATOR_VALID(iteratorPtr) macro.
* An implicit write access lock is granted on the entry pointed by the iterator.
* The access is automatically revoked when the iterator is re-incremented.
* If the caller decides to terminate the iteration before the end of the table is
* passed then the manual access release method, @ref ixEthDBReleaseHashIterator,
* must be called.
* Is is guaranteed that no other thread can remove or change the iterated entry until
* the iterator is incremented successfully.
*
* @see ixEthDBReleaseHashIterator()
*
* @retval IX_ETH_DB_SUCCESS if the operation was successful and the iterator points
* to the next valid table node
* @retval IX_ETH_DB_FAIL if the iterator has passed the end of the table
* @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case the caller
* should retry
*
* @warning do not use ixEthDBReleaseHashNode() on entries pointed by the iterator, as this
* might place the database in a permanent invalid lock state
*
* @internal
*/
IxEthDBStatus ixEthDBIncrementHashIterator(HashTable *hashTable, HashIterator *iterator)
{
/* unless iterator is just initialized... */
if (iterator->node != NULL)
{
/* try next in chain */
if (iterator->node->next != NULL)
{
TRY_LOCK(&iterator->node->next->lock);
if (iterator->previousNode != NULL)
{
UNLOCK(&iterator->previousNode->lock);
}
iterator->previousNode = iterator->node;
iterator->node = iterator->node->next;
return IX_ETH_DB_SUCCESS;
}
else
{
/* last in chain, prepare for next bucket */
iterator->bucketIndex++;
}
}
/* try next used bucket */
for (; iterator->bucketIndex < hashTable->numBuckets ; iterator->bucketIndex++)
{
HashNode **nodePtr = &(hashTable->hashBuckets[iterator->bucketIndex]);
HashNode *node = *nodePtr;
#if (CPU!=SIMSPARCSOLARIS) && !defined (__wince)
if (((iterator->bucketIndex & IX_ETHDB_BUCKET_INDEX_MASK) == 0) &&
(iterator->bucketIndex < (hashTable->numBuckets - IX_ETHDB_BUCKETPTR_AHEAD)))
{
/* preload next cache line (2 cache line ahead) */
nodePtr += IX_ETHDB_BUCKETPTR_AHEAD;
__asm__ ("pld [%0];\n": : "r" (nodePtr));
}
#endif
if (node != NULL)
{
TRY_LOCK(&node->lock);
/* unlock last one or two nodes in the previous chain */
if (iterator->node != NULL)
{
UNLOCK(&iterator->node->lock);
if (iterator->previousNode != NULL)
{
UNLOCK(&iterator->previousNode->lock);
}
}
/* redirect iterator */
iterator->previousNode = NULL;
iterator->node = node;
return IX_ETH_DB_SUCCESS;
}
}
/* could not advance iterator */
if (iterator->node != NULL)
{
UNLOCK(&iterator->node->lock);
if (iterator->previousNode != NULL)
{
UNLOCK(&iterator->previousNode->lock);
}
iterator->node = NULL;
}
return IX_ETH_DB_END;
}
/**
* @brief removes an entry pointed by an iterator
*
* @param hashTable iterated hash table
* @param iterator iterator object
*
* Removes the entry currently pointed by the iterator and repositions the iterator
* on the next valid entry (if any). Handles locking issues automatically and
* implicitely grants write access lock to the new pointed entry.
* Failures due to concurrent threads having write access locks in the same region
* preserve the state of the database and the iterator object, leaving the caller
* free to retry without loss of access. It is guaranteed that only the thread owning
* the iterator can remove the object pointed by the iterator.
*
* @retval IX_ETH_DB_SUCCESS if removal has succeeded
* @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case the caller
* should retry
*
* @internal
*/
IxEthDBStatus ixEthDBRemoveEntryAtHashIterator(HashTable *hashTable, HashIterator *iterator)
{
HashIterator nextIteratorPos;
LockStack locks;
INIT_STACK(&locks);
/* set initial bucket index for next position */
nextIteratorPos.bucketIndex = iterator->bucketIndex;
/* compute iterator position before removing anything and lock ahead */
if (iterator->node->next != NULL)
{
PUSH_LOCK(&locks, &iterator->node->next->lock);
/* reposition on the next node in the chain */
nextIteratorPos.node = iterator->node->next;
nextIteratorPos.previousNode = iterator->previousNode;
}
else
{
/* try next chain - don't know yet if we'll find anything */
nextIteratorPos.node = NULL;
/* if we find something it's a chain head */
nextIteratorPos.previousNode = NULL;
/* browse up in the buckets to find a non-null chain */
while (++nextIteratorPos.bucketIndex < hashTable->numBuckets)
{
nextIteratorPos.node = hashTable->hashBuckets[nextIteratorPos.bucketIndex];
if (nextIteratorPos.node != NULL)
{
/* found a non-empty chain, try to lock head */
PUSH_LOCK(&locks, &nextIteratorPos.node->lock);
break;
}
}
}
/* restore links over the to-be-deleted item */
if (iterator->previousNode == NULL)
{
/* first in chain, lock bucket */
PUSH_LOCK(&locks, &hashTable->bucketLocks[iterator->bucketIndex]);
hashTable->hashBuckets[iterator->bucketIndex] = iterator->node->next;
POP_LOCK(&locks);
}
else
{
/* relink */
iterator->previousNode->next = iterator->node->next;
/* unlock last remaining node in current chain when moving between chains */
if (iterator->node->next == NULL)
{
UNLOCK(&iterator->previousNode->lock);
}
}
/* delete entry */
hashTable->freeFunction(iterator->node->data);
ixEthDBFreeHashNode(iterator->node);
/* reposition iterator */
*iterator = nextIteratorPos;
return IX_ETH_DB_SUCCESS;
}
/**
* @}
*/

View file

@ -0,0 +1,149 @@
/**
* @file IxEthDBLearning.c
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#include "IxEthDB_p.h"
/**
* @brief hashes the mac address in a mac descriptor with a XOR function
*
* @param entry pointer to a mac descriptor to be hashed
*
* This function only extracts the mac address and employs ixEthDBKeyXORHash()
* to do the actual hashing.
* Used only to add a whole entry to a hash table, as opposed to searching which
* takes only a key and uses the key hashing directly.
*
* @see ixEthDBKeyXORHash()
*
* @return the hash value
*
* @internal
*/
UINT32 ixEthDBEntryXORHash(void *entry)
{
MacDescriptor *descriptor = (MacDescriptor *) entry;
return ixEthDBKeyXORHash(descriptor->macAddress);
}
/**
* @brief hashes a mac address
*
* @param key pointer to a 6 byte structure (typically an IxEthDBMacAddr pointer)
* to be hashed
*
* Given a 6 bytes MAC address, the hash used is:
*
* hash(MAC[0:5]) = MAC[0:1] ^ MAC[2:3] ^ MAC[4:5]
*
* Used by the hash table to search and remove entries based
* solely on their keys (mac addresses).
*
* @return the hash value
*
* @internal
*/
UINT32 ixEthDBKeyXORHash(void *key)
{
UINT32 hashValue;
UINT8 *value = (UINT8 *) key;
hashValue = (value[5] << 8) | value[4];
hashValue ^= (value[3] << 8) | value[2];
hashValue ^= (value[1] << 8) | value[0];
return hashValue;
}
/**
* @brief mac descriptor match function
*
* @param reference mac address (typically an IxEthDBMacAddr pointer) structure
* @param entry pointer to a mac descriptor whose key (mac address) is to be
* matched against the reference key
*
* Used by the hash table to retrieve entries. Hashing entries can produce
* collisions, i.e. descriptors with different mac addresses and the same
* hash value, where this function is used to differentiate entries.
*
* @retval TRUE if the entry matches the reference key (equal addresses)
* @retval FALSE if the entry does not match the reference key
*
* @internal
*/
BOOL ixEthDBAddressMatch(void *reference, void *entry)
{
return (ixEthDBAddressCompare(reference, ((MacDescriptor *) entry)->macAddress) == 0);
}
/**
* @brief compares two mac addresses
*
* @param mac1 first mac address to compare
* @param mac2 second mac address to compare
*
* This comparison works in a similar way to strcmp, producing similar results.
* Used to insert values keyed on mac addresses into binary search trees.
*
* @retval -1 if mac1 < mac2
* @retval 0 if ma1 == mac2
* @retval 1 if mac1 > mac2
*/
UINT32 ixEthDBAddressCompare(UINT8 *mac1, UINT8 *mac2)
{
UINT32 local_index;
for (local_index = 0 ; local_index < IX_IEEE803_MAC_ADDRESS_SIZE ; local_index++)
{
if (mac1[local_index] > mac2[local_index])
{
return 1;
}
else if (mac1[local_index] < mac2[local_index])
{
return -1;
}
}
return 0;
}

649
cpu/ixp/npe/IxEthDBMem.c Normal file
View file

@ -0,0 +1,649 @@
/**
* @file IxEthDBDBMem.c
*
* @brief Memory handling routines for the MAC address database
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#include "IxEthDB_p.h"
IX_ETH_DB_PRIVATE HashNode *nodePool = NULL;
IX_ETH_DB_PRIVATE MacDescriptor *macPool = NULL;
IX_ETH_DB_PRIVATE MacTreeNode *treePool = NULL;
IX_ETH_DB_PRIVATE HashNode nodePoolArea[NODE_POOL_SIZE];
IX_ETH_DB_PRIVATE MacDescriptor macPoolArea[MAC_POOL_SIZE];
IX_ETH_DB_PRIVATE MacTreeNode treePoolArea[TREE_POOL_SIZE];
IX_ETH_DB_PRIVATE IxOsalMutex nodePoolLock;
IX_ETH_DB_PRIVATE IxOsalMutex macPoolLock;
IX_ETH_DB_PRIVATE IxOsalMutex treePoolLock;
#define LOCK_NODE_POOL { ixOsalMutexLock(&nodePoolLock, IX_OSAL_WAIT_FOREVER); }
#define UNLOCK_NODE_POOL { ixOsalMutexUnlock(&nodePoolLock); }
#define LOCK_MAC_POOL { ixOsalMutexLock(&macPoolLock, IX_OSAL_WAIT_FOREVER); }
#define UNLOCK_MAC_POOL { ixOsalMutexUnlock(&macPoolLock); }
#define LOCK_TREE_POOL { ixOsalMutexLock(&treePoolLock, IX_OSAL_WAIT_FOREVER); }
#define UNLOCK_TREE_POOL { ixOsalMutexUnlock(&treePoolLock); }
/* private function prototypes */
IX_ETH_DB_PRIVATE MacDescriptor* ixEthDBPoolAllocMacDescriptor(void);
IX_ETH_DB_PRIVATE void ixEthDBPoolFreeMacDescriptor(MacDescriptor *macDescriptor);
/**
* @addtogroup EthMemoryManagement
*
* @{
*/
/**
* @brief initializes the memory pools used by the ethernet database component
*
* Initializes the hash table node, mac descriptor and mac tree node pools.
* Called at initialization time by @ref ixEthDBInit().
*
* @internal
*/
IX_ETH_DB_PUBLIC
void ixEthDBInitMemoryPools(void)
{
int local_index;
/* HashNode pool */
ixOsalMutexInit(&nodePoolLock);
for (local_index = 0 ; local_index < NODE_POOL_SIZE ; local_index++)
{
HashNode *freeNode = &nodePoolArea[local_index];
freeNode->nextFree = nodePool;
nodePool = freeNode;
}
/* MacDescriptor pool */
ixOsalMutexInit(&macPoolLock);
for (local_index = 0 ; local_index < MAC_POOL_SIZE ; local_index++)
{
MacDescriptor *freeDescriptor = &macPoolArea[local_index];
freeDescriptor->nextFree = macPool;
macPool = freeDescriptor;
}
/* MacTreeNode pool */
ixOsalMutexInit(&treePoolLock);
for (local_index = 0 ; local_index < TREE_POOL_SIZE ; local_index++)
{
MacTreeNode *freeNode = &treePoolArea[local_index];
freeNode->nextFree = treePool;
treePool = freeNode;
}
}
/**
* @brief allocates a hash node from the pool
*
* Allocates a hash node and resets its value.
*
* @return the allocated hash node or NULL if the pool is empty
*
* @internal
*/
IX_ETH_DB_PUBLIC
HashNode* ixEthDBAllocHashNode(void)
{
HashNode *allocatedNode = NULL;
if (nodePool != NULL)
{
LOCK_NODE_POOL;
allocatedNode = nodePool;
nodePool = nodePool->nextFree;
UNLOCK_NODE_POOL;
memset(allocatedNode, 0, sizeof(HashNode));
}
return allocatedNode;
}
/**
* @brief frees a hash node into the pool
*
* @param hashNode node to be freed
*
* @internal
*/
IX_ETH_DB_PUBLIC
void ixEthDBFreeHashNode(HashNode *hashNode)
{
if (hashNode != NULL)
{
LOCK_NODE_POOL;
hashNode->nextFree = nodePool;
nodePool = hashNode;
UNLOCK_NODE_POOL;
}
}
/**
* @brief allocates a mac descriptor from the pool
*
* Allocates a mac descriptor and resets its value.
* This function is not used directly, instead @ref ixEthDBAllocMacDescriptor()
* is used, which keeps track of the pointer reference count.
*
* @see ixEthDBAllocMacDescriptor()
*
* @warning this function is not used directly by any other function
* apart from ixEthDBAllocMacDescriptor()
*
* @return the allocated mac descriptor or NULL if the pool is empty
*
* @internal
*/
IX_ETH_DB_PRIVATE
MacDescriptor* ixEthDBPoolAllocMacDescriptor(void)
{
MacDescriptor *allocatedDescriptor = NULL;
if (macPool != NULL)
{
LOCK_MAC_POOL;
allocatedDescriptor = macPool;
macPool = macPool->nextFree;
UNLOCK_MAC_POOL;
memset(allocatedDescriptor, 0, sizeof(MacDescriptor));
}
return allocatedDescriptor;
}
/**
* @brief allocates and initializes a mac descriptor smart pointer
*
* Uses @ref ixEthDBPoolAllocMacDescriptor() to allocate a mac descriptor
* from the pool and initializes its reference count.
*
* @see ixEthDBPoolAllocMacDescriptor()
*
* @return the allocated mac descriptor or NULL if the pool is empty
*
* @internal
*/
IX_ETH_DB_PUBLIC
MacDescriptor* ixEthDBAllocMacDescriptor(void)
{
MacDescriptor *allocatedDescriptor = ixEthDBPoolAllocMacDescriptor();
if (allocatedDescriptor != NULL)
{
LOCK_MAC_POOL;
allocatedDescriptor->refCount++;
UNLOCK_MAC_POOL;
}
return allocatedDescriptor;
}
/**
* @brief frees a mac descriptor back into the pool
*
* @param macDescriptor mac descriptor to be freed
*
* @warning this function is not to be called by anyone but
* ixEthDBFreeMacDescriptor()
*
* @see ixEthDBFreeMacDescriptor()
*
* @internal
*/
IX_ETH_DB_PRIVATE
void ixEthDBPoolFreeMacDescriptor(MacDescriptor *macDescriptor)
{
LOCK_MAC_POOL;
macDescriptor->nextFree = macPool;
macPool = macDescriptor;
UNLOCK_MAC_POOL;
}
/**
* @brief frees or reduces the usage count of a mac descriptor smart pointer
*
* If the reference count reaches 0 (structure is no longer used anywhere)
* then the descriptor is freed back into the pool using ixEthDBPoolFreeMacDescriptor().
*
* @see ixEthDBPoolFreeMacDescriptor()
*
* @internal
*/
IX_ETH_DB_PUBLIC
void ixEthDBFreeMacDescriptor(MacDescriptor *macDescriptor)
{
if (macDescriptor != NULL)
{
LOCK_MAC_POOL;
if (macDescriptor->refCount > 0)
{
macDescriptor->refCount--;
if (macDescriptor->refCount == 0)
{
UNLOCK_MAC_POOL;
ixEthDBPoolFreeMacDescriptor(macDescriptor);
}
else
{
UNLOCK_MAC_POOL;
}
}
else
{
UNLOCK_MAC_POOL;
}
}
}
/**
* @brief clones a mac descriptor smart pointer
*
* @param macDescriptor mac descriptor to clone
*
* Increments the usage count of the smart pointer
*
* @returns the cloned smart pointer
*
* @internal
*/
IX_ETH_DB_PUBLIC
MacDescriptor* ixEthDBCloneMacDescriptor(MacDescriptor *macDescriptor)
{
LOCK_MAC_POOL;
if (macDescriptor->refCount == 0)
{
UNLOCK_MAC_POOL;
return NULL;
}
macDescriptor->refCount++;
UNLOCK_MAC_POOL;
return macDescriptor;
}
/**
* @brief allocates a mac tree node from the pool
*
* Allocates and initializes a mac tree node from the pool.
*
* @return the allocated mac tree node or NULL if the pool is empty
*
* @internal
*/
IX_ETH_DB_PUBLIC
MacTreeNode* ixEthDBAllocMacTreeNode(void)
{
MacTreeNode *allocatedNode = NULL;
if (treePool != NULL)
{
LOCK_TREE_POOL;
allocatedNode = treePool;
treePool = treePool->nextFree;
UNLOCK_TREE_POOL;
memset(allocatedNode, 0, sizeof(MacTreeNode));
}
return allocatedNode;
}
/**
* @brief frees a mac tree node back into the pool
*
* @param macNode mac tree node to be freed
*
* @warning not to be used except from ixEthDBFreeMacTreeNode().
*
* @see ixEthDBFreeMacTreeNode()
*
* @internal
*/
void ixEthDBPoolFreeMacTreeNode(MacTreeNode *macNode)
{
if (macNode != NULL)
{
LOCK_TREE_POOL;
macNode->nextFree = treePool;
treePool = macNode;
UNLOCK_TREE_POOL;
}
}
/**
* @brief frees or reduces the usage count of a mac tree node smart pointer
*
* @param macNode mac tree node to free
*
* Reduces the usage count of the given mac node. If the usage count
* reaches 0 the node is freed back into the pool using ixEthDBPoolFreeMacTreeNode()
*
* @internal
*/
IX_ETH_DB_PUBLIC
void ixEthDBFreeMacTreeNode(MacTreeNode *macNode)
{
if (macNode->descriptor != NULL)
{
ixEthDBFreeMacDescriptor(macNode->descriptor);
}
if (macNode->left != NULL)
{
ixEthDBFreeMacTreeNode(macNode->left);
}
if (macNode->right != NULL)
{
ixEthDBFreeMacTreeNode(macNode->right);
}
ixEthDBPoolFreeMacTreeNode(macNode);
}
/**
* @brief clones a mac tree node
*
* @param macNode mac tree node to be cloned
*
* Increments the usage count of the node, <i>its associated descriptor
* and <b>recursively</b> of all its child nodes</i>.
*
* @warning this function is recursive and clones whole trees/subtrees, use only for
* root nodes
*
* @internal
*/
IX_ETH_DB_PUBLIC
MacTreeNode* ixEthDBCloneMacTreeNode(MacTreeNode *macNode)
{
if (macNode != NULL)
{
MacTreeNode *clonedMacNode = ixEthDBAllocMacTreeNode();
if (clonedMacNode != NULL)
{
if (macNode->right != NULL)
{
clonedMacNode->right = ixEthDBCloneMacTreeNode(macNode->right);
}
if (macNode->left != NULL)
{
clonedMacNode->left = ixEthDBCloneMacTreeNode(macNode->left);
}
if (macNode->descriptor != NULL)
{
clonedMacNode->descriptor = ixEthDBCloneMacDescriptor(macNode->descriptor);
}
}
return clonedMacNode;
}
else
{
return NULL;
}
}
#ifndef NDEBUG
/* Debug statistical functions for memory usage */
extern HashTable dbHashtable;
int ixEthDBNumHashElements(void);
int ixEthDBNumHashElements(void)
{
UINT32 bucketIndex;
int numElements = 0;
HashTable *hashTable = &dbHashtable;
for (bucketIndex = 0 ; bucketIndex < hashTable->numBuckets ; bucketIndex++)
{
if (hashTable->hashBuckets[bucketIndex] != NULL)
{
HashNode *node = hashTable->hashBuckets[bucketIndex];
while (node != NULL)
{
numElements++;
node = node->next;
}
}
}
return numElements;
}
UINT32 ixEthDBSearchTreeUsageGet(MacTreeNode *tree)
{
if (tree == NULL)
{
return 0;
}
else
{
return 1 /* this node */ + ixEthDBSearchTreeUsageGet(tree->left) + ixEthDBSearchTreeUsageGet(tree->right);
}
}
int ixEthDBShowMemoryStatus(void)
{
MacDescriptor *mac;
MacTreeNode *tree;
HashNode *node;
int macCounter = 0;
int treeCounter = 0;
int nodeCounter = 0;
int totalTreeUsage = 0;
int totalDescriptorUsage = 0;
int totalCloneDescriptorUsage = 0;
int totalNodeUsage = 0;
UINT32 portIndex;
LOCK_NODE_POOL;
LOCK_MAC_POOL;
LOCK_TREE_POOL;
mac = macPool;
tree = treePool;
node = nodePool;
while (mac != NULL)
{
macCounter++;
mac = mac->nextFree;
if (macCounter > MAC_POOL_SIZE)
{
break;
}
}
while (tree != NULL)
{
treeCounter++;
tree = tree->nextFree;
if (treeCounter > TREE_POOL_SIZE)
{
break;
}
}
while (node != NULL)
{
nodeCounter++;
node = node->nextFree;
if (nodeCounter > NODE_POOL_SIZE)
{
break;
}
}
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
{
int treeUsage = ixEthDBSearchTreeUsageGet(ixEthDBPortInfo[portIndex].updateMethod.searchTree);
totalTreeUsage += treeUsage;
totalCloneDescriptorUsage += treeUsage; /* each tree node contains a descriptor */
}
totalNodeUsage = ixEthDBNumHashElements();
totalDescriptorUsage += totalNodeUsage; /* each hash table entry contains a descriptor */
UNLOCK_NODE_POOL;
UNLOCK_MAC_POOL;
UNLOCK_TREE_POOL;
printf("Ethernet database memory usage stats:\n\n");
if (macCounter <= MAC_POOL_SIZE)
{
printf("\tMAC descriptor pool : %d free out of %d entries (%d%%)\n", macCounter, MAC_POOL_SIZE, macCounter * 100 / MAC_POOL_SIZE);
}
else
{
printf("\tMAC descriptor pool : invalid state (ring within the pool), normally %d entries\n", MAC_POOL_SIZE);
}
if (treeCounter <= TREE_POOL_SIZE)
{
printf("\tTree node pool : %d free out of %d entries (%d%%)\n", treeCounter, TREE_POOL_SIZE, treeCounter * 100 / TREE_POOL_SIZE);
}
else
{
printf("\tTREE descriptor pool : invalid state (ring within the pool), normally %d entries\n", TREE_POOL_SIZE);
}
if (nodeCounter <= NODE_POOL_SIZE)
{
printf("\tHash node pool : %d free out of %d entries (%d%%)\n", nodeCounter, NODE_POOL_SIZE, nodeCounter * 100 / NODE_POOL_SIZE);
}
else
{
printf("\tNODE descriptor pool : invalid state (ring within the pool), normally %d entries\n", NODE_POOL_SIZE);
}
printf("\n");
printf("\tMAC descriptor usage : %d entries, %d cloned\n", totalDescriptorUsage, totalCloneDescriptorUsage);
printf("\tTree node usage : %d entries\n", totalTreeUsage);
printf("\tHash node usage : %d entries\n", totalNodeUsage);
printf("\n");
/* search for duplicate nodes in the mac pool */
{
MacDescriptor *reference = macPool;
while (reference != NULL)
{
MacDescriptor *comparison = reference->nextFree;
while (comparison != NULL)
{
if (reference == comparison)
{
printf("Warning: reached a duplicate (%p), invalid MAC pool state\n", reference);
return 1;
}
comparison = comparison->nextFree;
}
reference = reference->nextFree;
}
}
printf("No duplicates found in the MAC pool (sanity check ok)\n");
return 0;
}
#endif /* NDEBUG */
/**
* @} EthMemoryManagement
*/

View file

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

View file

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

View file

@ -0,0 +1,652 @@
/**
* @file IxEthDBAPI.c
*
* @brief Implementation of the public API
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#include "IxEthDB_p.h"
extern HashTable dbHashtable;
IX_ETH_DB_PRIVATE void ixEthDBPortInfoShow(IxEthDBPortId portID, IxEthDBRecordType recordFilter);
IX_ETH_DB_PRIVATE IxEthDBStatus ixEthDBHeaderShow(IxEthDBRecordType recordFilter);
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBDependencyPortMapShow(IxEthDBPortId portID, IxEthDBPortMap map);
/**
* @brief displays a port dependency map
*
* @param portID ID of the port
* @param map port map to display
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBDependencyPortMapShow(IxEthDBPortId portID, IxEthDBPortMap map)
{
UINT32 portIndex;
BOOL mapSelf = TRUE, mapNone = TRUE, firstPort = TRUE;
/* dependency port maps */
printf("Dependency port map: ");
/* browse the port map */
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
{
if (IS_PORT_INCLUDED(portIndex, map))
{
mapNone = FALSE;
if (portIndex != portID)
{
mapSelf = FALSE;
}
printf("%s%d", firstPort ? "{" : ", ", portIndex);
firstPort = FALSE;
}
}
if (mapNone)
{
mapSelf = FALSE;
}
printf("%s (%s)\n", firstPort ? "" : "}", mapSelf ? "self" : mapNone ? "none" : "group");
return IX_ETH_DB_SUCCESS;
}
/**
* @brief displays all the filtering records belonging to a port
*
* @param portID ID of the port to display
*
* Note that this function is documented in the main component
* header file, IxEthDB.h.
*
* @warning deprecated, use @ref ixEthDBFilteringDatabaseShowRecords()
* instead. Calling this function is equivalent to calling
* ixEthDBFilteringDatabaseShowRecords(portID, IX_ETH_DB_FILTERING_RECORD)
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFilteringDatabaseShow(IxEthDBPortId portID)
{
IxEthDBStatus local_result;
HashIterator iterator;
PortInfo *portInfo;
UINT32 recordCount = 0;
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
portInfo = &ixEthDBPortInfo[portID];
/* display table header */
printf("Ethernet database records for port ID [%d]\n", portID);
ixEthDBDependencyPortMapShow(portID, portInfo->dependencyPortMap);
if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
{
printf("NPE updates are %s\n\n", portInfo->updateMethod.updateEnabled ? "enabled" : "disabled");
}
else
{
printf("updates disabled (not an NPE)\n\n");
}
printf(" MAC address | Age | Type \n");
printf("___________________________________\n");
/* browse database */
BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
while (IS_ITERATOR_VALID(&iterator))
{
MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
if (descriptor->portID == portID && descriptor->type == IX_ETH_DB_FILTERING_RECORD)
{
recordCount++;
/* display entry */
printf(" %02X:%02X:%02X:%02X:%02X:%02X | %5d | %s\n",
descriptor->macAddress[0],
descriptor->macAddress[1],
descriptor->macAddress[2],
descriptor->macAddress[3],
descriptor->macAddress[4],
descriptor->macAddress[5],
descriptor->recordData.filteringData.age,
descriptor->recordData.filteringData.staticEntry ? "static" : "dynamic");
}
/* move to the next record */
BUSY_RETRY_WITH_RESULT(ixEthDBIncrementHashIterator(&dbHashtable, &iterator), local_result);
/* debug */
if (local_result == IX_ETH_DB_BUSY)
{
return IX_ETH_DB_FAIL;
}
}
/* display number of records */
printf("\nFound %d records\n", recordCount);
return IX_ETH_DB_SUCCESS;
}
/**
* @brief displays all the filtering records belonging to all the ports
*
* Note that this function is documented in the main component
* header file, IxEthDB.h.
*
* @warning deprecated, use @ref ixEthDBFilteringDatabaseShowRecords()
* instead. Calling this function is equivalent to calling
* ixEthDBFilteringDatabaseShowRecords(IX_ETH_DB_ALL_PORTS, IX_ETH_DB_FILTERING_RECORD)
*/
IX_ETH_DB_PUBLIC
void ixEthDBFilteringDatabaseShowAll()
{
IxEthDBPortId portIndex;
printf("\nEthernet learning/filtering database: listing %d ports\n\n", (UINT32) IX_ETH_DB_NUMBER_OF_PORTS);
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
{
ixEthDBFilteringDatabaseShow(portIndex);
if (portIndex < IX_ETH_DB_NUMBER_OF_PORTS - 1)
{
printf("\n");
}
}
}
/**
* @brief displays one record in a format depending on the record filter
*
* @param descriptor pointer to the record
* @param recordFilter format filter
*
* This function will display the fields in a record depending on the
* selected record filter.
*
* @internal
*/
IX_ETH_DB_PRIVATE
void ixEthDBRecordShow(MacDescriptor *descriptor, IxEthDBRecordType recordFilter)
{
if (recordFilter == IX_ETH_DB_FILTERING_VLAN_RECORD
|| recordFilter == (IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD))
{
/* display VLAN record header - leave this commented code in place, its purpose is to align the print format with the header
printf(" MAC address | Age | Type | VLAN ID | CFI | QoS class \n");
printf("___________________________________________________________________\n"); */
if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD)
{
printf("%02X:%02X:%02X:%02X:%02X:%02X | %3d | %s | %d | %d | %d\n",
descriptor->macAddress[0],
descriptor->macAddress[1],
descriptor->macAddress[2],
descriptor->macAddress[3],
descriptor->macAddress[4],
descriptor->macAddress[5],
descriptor->recordData.filteringVlanData.age,
descriptor->recordData.filteringVlanData.staticEntry ? "static" : "dynamic",
IX_ETH_DB_GET_VLAN_ID(descriptor->recordData.filteringVlanData.ieee802_1qTag),
(descriptor->recordData.filteringVlanData.ieee802_1qTag & 0x1000) >> 12,
IX_ETH_DB_GET_QOS_PRIORITY(descriptor->recordData.filteringVlanData.ieee802_1qTag));
}
else if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
{
printf("%02X:%02X:%02X:%02X:%02X:%02X | %3d | %s | - | - | -\n",
descriptor->macAddress[0],
descriptor->macAddress[1],
descriptor->macAddress[2],
descriptor->macAddress[3],
descriptor->macAddress[4],
descriptor->macAddress[5],
descriptor->recordData.filteringData.age,
descriptor->recordData.filteringData.staticEntry ? "static" : "dynamic");
}
}
else if (recordFilter == IX_ETH_DB_FILTERING_RECORD)
{
/* display filtering record header - leave this commented code in place, its purpose is to align the print format with the header
printf(" MAC address | Age | Type \n");
printf("_______________________________________\n"); */
if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
{
printf("%02X:%02X:%02X:%02X:%02X:%02X | %3d | %s \n",
descriptor->macAddress[0],
descriptor->macAddress[1],
descriptor->macAddress[2],
descriptor->macAddress[3],
descriptor->macAddress[4],
descriptor->macAddress[5],
descriptor->recordData.filteringData.age,
descriptor->recordData.filteringData.staticEntry ? "static" : "dynamic");
}
}
else if (recordFilter == IX_ETH_DB_WIFI_RECORD)
{
/* display WiFi record header - leave this commented code in place, its purpose is to align the print format with the header
printf(" MAC address | GW MAC address \n");
printf("_______________________________________\n"); */
if (descriptor->type == IX_ETH_DB_WIFI_RECORD)
{
if (descriptor->recordData.wifiData.type == IX_ETH_DB_WIFI_AP_TO_AP)
{
/* gateway address present */
printf("%02X:%02X:%02X:%02X:%02X:%02X | %02X:%02X:%02X:%02X:%02X:%02X \n",
descriptor->macAddress[0],
descriptor->macAddress[1],
descriptor->macAddress[2],
descriptor->macAddress[3],
descriptor->macAddress[4],
descriptor->macAddress[5],
descriptor->recordData.wifiData.gwMacAddress[0],
descriptor->recordData.wifiData.gwMacAddress[1],
descriptor->recordData.wifiData.gwMacAddress[2],
descriptor->recordData.wifiData.gwMacAddress[3],
descriptor->recordData.wifiData.gwMacAddress[4],
descriptor->recordData.wifiData.gwMacAddress[5]);
}
else
{
/* no gateway */
printf("%02X:%02X:%02X:%02X:%02X:%02X | ----no gateway----- \n",
descriptor->macAddress[0],
descriptor->macAddress[1],
descriptor->macAddress[2],
descriptor->macAddress[3],
descriptor->macAddress[4],
descriptor->macAddress[5]);
}
}
}
else if (recordFilter == IX_ETH_DB_FIREWALL_RECORD)
{
/* display Firewall record header - leave this commented code in place, its purpose is to align the print format with the header
printf(" MAC address \n");
printf("__________________\n"); */
if (descriptor->type == IX_ETH_DB_FIREWALL_RECORD)
{
printf("%02X:%02X:%02X:%02X:%02X:%02X \n",
descriptor->macAddress[0],
descriptor->macAddress[1],
descriptor->macAddress[2],
descriptor->macAddress[3],
descriptor->macAddress[4],
descriptor->macAddress[5]);
}
}
else if (recordFilter == IX_ETH_DB_ALL_RECORD_TYPES)
{
/* display composite record header - leave this commented code in place, its purpose is to align the print format with the header
printf(" MAC address | Record | Age| Type | VLAN |CFI| QoS | GW MAC address \n");
printf("_______________________________________________________________________________\n"); */
if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD)
{
printf("%02X:%02X:%02X:%02X:%02X:%02X | VLAN | %2d | %s | %4d | %1d | %1d | -----------------\n",
descriptor->macAddress[0],
descriptor->macAddress[1],
descriptor->macAddress[2],
descriptor->macAddress[3],
descriptor->macAddress[4],
descriptor->macAddress[5],
descriptor->recordData.filteringVlanData.age,
descriptor->recordData.filteringVlanData.staticEntry ? "static " : "dynamic",
IX_ETH_DB_GET_VLAN_ID(descriptor->recordData.filteringVlanData.ieee802_1qTag),
(descriptor->recordData.filteringVlanData.ieee802_1qTag & 0x1000) >> 12,
IX_ETH_DB_GET_QOS_PRIORITY(descriptor->recordData.filteringVlanData.ieee802_1qTag));
}
else if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
{
printf("%02X:%02X:%02X:%02X:%02X:%02X | Filter | %2d | %s | ---- | - | --- | -----------------\n",
descriptor->macAddress[0],
descriptor->macAddress[1],
descriptor->macAddress[2],
descriptor->macAddress[3],
descriptor->macAddress[4],
descriptor->macAddress[5],
descriptor->recordData.filteringData.age,
descriptor->recordData.filteringData.staticEntry ? "static " : "dynamic");
}
else if (descriptor->type == IX_ETH_DB_WIFI_RECORD)
{
if (descriptor->recordData.wifiData.type == IX_ETH_DB_WIFI_AP_TO_AP)
{
/* gateway address present */
printf("%02X:%02X:%02X:%02X:%02X:%02X | WiFi | -- | AP=>AP | ---- | - | --- | %02X:%02X:%02X:%02X:%02X:%02X\n",
descriptor->macAddress[0],
descriptor->macAddress[1],
descriptor->macAddress[2],
descriptor->macAddress[3],
descriptor->macAddress[4],
descriptor->macAddress[5],
descriptor->recordData.wifiData.gwMacAddress[0],
descriptor->recordData.wifiData.gwMacAddress[1],
descriptor->recordData.wifiData.gwMacAddress[2],
descriptor->recordData.wifiData.gwMacAddress[3],
descriptor->recordData.wifiData.gwMacAddress[4],
descriptor->recordData.wifiData.gwMacAddress[5]);
}
else
{
/* no gateway */
printf("%02X:%02X:%02X:%02X:%02X:%02X | WiFi | -- | AP=>ST | ---- | - | --- | -- no gateway -- \n",
descriptor->macAddress[0],
descriptor->macAddress[1],
descriptor->macAddress[2],
descriptor->macAddress[3],
descriptor->macAddress[4],
descriptor->macAddress[5]);
}
}
else if (descriptor->type == IX_ETH_DB_FIREWALL_RECORD)
{
printf("%02X:%02X:%02X:%02X:%02X:%02X | FW | -- | ------- | ---- | - | --- | -----------------\n",
descriptor->macAddress[0],
descriptor->macAddress[1],
descriptor->macAddress[2],
descriptor->macAddress[3],
descriptor->macAddress[4],
descriptor->macAddress[5]);
}
}
else
{
printf("invalid record filter\n");
}
}
/**
* @brief displays the status, records and configuration information of a port
*
* @param portID ID of the port
* @param recordFilter record filter to display
*
* @internal
*/
IX_ETH_DB_PRIVATE
void ixEthDBPortInfoShow(IxEthDBPortId portID, IxEthDBRecordType recordFilter)
{
PortInfo *portInfo = &ixEthDBPortInfo[portID];
UINT32 recordCount = 0;
HashIterator iterator;
IxEthDBStatus local_result;
/* display port status */
printf("== Port ID %d ==\n", portID);
/* display capabilities */
printf("- Capabilities: ");
if ((portInfo->featureCapability & IX_ETH_DB_LEARNING) != 0)
{
printf("Learning (%s) ", ((portInfo->featureStatus & IX_ETH_DB_LEARNING) != 0) ? "on" : "off");
}
if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0)
{
printf("VLAN/QoS (%s) ", ((portInfo->featureStatus & IX_ETH_DB_VLAN_QOS) != 0) ? "on" : "off");
}
if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0)
{
printf("Firewall (%s) ", ((portInfo->featureStatus & IX_ETH_DB_FIREWALL) != 0) ? "on" : "off");
}
if ((portInfo->featureCapability & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0)
{
printf("WiFi (%s) ", ((portInfo->featureStatus & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0) ? "on" : "off");
}
if ((portInfo->featureCapability & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0)
{
printf("STP (%s) ", ((portInfo->featureStatus & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0) ? "on" : "off");
}
printf("\n");
/* dependency map */
ixEthDBDependencyPortMapShow(portID, portInfo->dependencyPortMap);
/* NPE dynamic updates */
if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
{
printf(" - NPE dynamic update is %s\n", portInfo->updateMethod.updateEnabled ? "enabled" : "disabled");
}
else
{
printf(" - dynamic update disabled (not an NPE)\n");
}
if ((portInfo->featureCapability & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0)
{
if ((portInfo->featureStatus & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0)
{
/* WiFi header conversion */
if ((portInfo->frameControlDurationID
+ portInfo->bbsid[0]
+ portInfo->bbsid[1]
+ portInfo->bbsid[2]
+ portInfo->bbsid[3]
+ portInfo->bbsid[4]
+ portInfo->bbsid[5]) == 0)
{
printf(" - WiFi header conversion not configured\n");
}
else
{
printf(" - WiFi header conversion: BBSID [%02X:%02X:%02X:%02X:%02X:%02X], Frame Control 0x%X, Duration/ID 0x%X\n",
portInfo->bbsid[0],
portInfo->bbsid[1],
portInfo->bbsid[2],
portInfo->bbsid[3],
portInfo->bbsid[4],
portInfo->bbsid[5],
portInfo->frameControlDurationID >> 16,
portInfo->frameControlDurationID & 0xFFFF);
}
}
else
{
printf(" - WiFi header conversion not enabled\n");
}
}
/* Firewall */
if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0)
{
if ((portInfo->featureStatus & IX_ETH_DB_FIREWALL) != 0)
{
printf(" - Firewall is in %s-list mode\n", portInfo->firewallMode == IX_ETH_DB_FIREWALL_BLACK_LIST ? "black" : "white");
printf(" - Invalid source MAC address filtering is %s\n", portInfo->srcAddressFilterEnabled ? "enabled" : "disabled");
}
else
{
printf(" - Firewall not enabled\n");
}
}
/* browse database if asked to display records */
if (recordFilter != IX_ETH_DB_NO_RECORD_TYPE)
{
printf("\n");
ixEthDBHeaderShow(recordFilter);
BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
while (IS_ITERATOR_VALID(&iterator))
{
MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
if (descriptor->portID == portID && (descriptor->type & recordFilter) != 0)
{
recordCount++;
/* display entry */
ixEthDBRecordShow(descriptor, recordFilter);
}
/* move to the next record */
BUSY_RETRY_WITH_RESULT(ixEthDBIncrementHashIterator(&dbHashtable, &iterator), local_result);
/* debug */
if (local_result == IX_ETH_DB_BUSY)
{
printf("EthDB (API): Error, database browser failed (no access), giving up\n");
}
}
printf("\nFound %d records\n\n", recordCount);
}
}
/**
* @brief displays a record header
*
* @param recordFilter record type filter
*
* This function displays a record header, depending on
* the given record type filter. It is useful when used
* in conjunction with ixEthDBRecordShow which will display
* record fields formatted for the header, provided the same
* record filter is used.
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully or IX_ETH_DB_INVALID_ARG if the recordFilter
* parameter is invalid or not supported
*
* @internal
*/
IX_ETH_DB_PRIVATE
IxEthDBStatus ixEthDBHeaderShow(IxEthDBRecordType recordFilter)
{
if (recordFilter == IX_ETH_DB_FILTERING_VLAN_RECORD
|| recordFilter == (IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD))
{
/* display VLAN record header */
printf(" MAC address | Age | Type | VLAN ID | CFI | QoS class \n");
printf("___________________________________________________________________\n");
}
else if (recordFilter == IX_ETH_DB_FILTERING_RECORD)
{
/* display filtering record header */
printf(" MAC address | Age | Type \n");
printf("_______________________________________\n");
}
else if (recordFilter == IX_ETH_DB_WIFI_RECORD)
{
/* display WiFi record header */
printf(" MAC address | GW MAC address \n");
printf("_______________________________________\n");
}
else if (recordFilter == IX_ETH_DB_FIREWALL_RECORD)
{
/* display Firewall record header */
printf(" MAC address \n");
printf("__________________\n");
}
else if (recordFilter == IX_ETH_DB_ALL_RECORD_TYPES)
{
/* display composite record header */
printf(" MAC address | Record | Age| Type | VLAN |CFI| QoS | GW MAC address \n");
printf("_______________________________________________________________________________\n");
}
else
{
return IX_ETH_DB_INVALID_ARG;
}
return IX_ETH_DB_SUCCESS;
}
/**
* @brief displays database information (records and port information)
*
* @param portID ID of the port to display (or IX_ETH_DB_ALL_PORTS for all the ports)
* @param recordFilter record filter (use IX_ETH_DB_NO_RECORD_TYPE to display only
* port information)
*
* Note that this function is documented in the main component header
* file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed successfully or
* an appropriate error code otherwise
*
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFilteringDatabaseShowRecords(IxEthDBPortId portID, IxEthDBRecordType recordFilter)
{
IxEthDBPortId currentPort;
BOOL showAllPorts = (portID == IX_ETH_DB_ALL_PORTS);
IX_ETH_DB_CHECK_PORT_ALL(portID);
printf("\nEthernet learning/filtering database: listing %d port(s)\n\n", showAllPorts ? (UINT32) IX_ETH_DB_NUMBER_OF_PORTS : 1);
currentPort = showAllPorts ? 0 : portID;
while (currentPort != IX_ETH_DB_NUMBER_OF_PORTS)
{
/* display port info */
ixEthDBPortInfoShow(currentPort, recordFilter);
/* next port */
currentPort = showAllPorts ? currentPort + 1 : IX_ETH_DB_NUMBER_OF_PORTS;
}
return IX_ETH_DB_SUCCESS;
}

327
cpu/ixp/npe/IxEthDBSearch.c Normal file
View file

@ -0,0 +1,327 @@
/**
* @file IxEthDBSearch.c
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#include "IxEthDB_p.h"
extern HashTable dbHashtable;
/**
* @brief matches two database records based on their MAC addresses
*
* @param untypedReference record to match against
* @param untypedEntry record to match
*
* @return TRUE if the match is successful or FALSE otherwise
*
* @internal
*/
IX_ETH_DB_PUBLIC
BOOL ixEthDBAddressRecordMatch(void *untypedReference, void *untypedEntry)
{
MacDescriptor *entry = (MacDescriptor *) untypedEntry;
MacDescriptor *reference = (MacDescriptor *) untypedReference;
/* check accepted record types */
if ((entry->type & reference->type) == 0) return FALSE;
return (ixEthDBAddressCompare((UINT8 *) entry->macAddress, (UINT8 *) reference->macAddress) == 0);
}
/**
* @brief matches two database records based on their MAC addresses
* and VLAN IDs
*
* @param untypedReference record to match against
* @param untypedEntry record to match
*
* @return TRUE if the match is successful or FALSE otherwise
*
* @internal
*/
IX_ETH_DB_PUBLIC
BOOL ixEthDBVlanRecordMatch(void *untypedReference, void *untypedEntry)
{
MacDescriptor *entry = (MacDescriptor *) untypedEntry;
MacDescriptor *reference = (MacDescriptor *) untypedReference;
/* check accepted record types */
if ((entry->type & reference->type) == 0) return FALSE;
return (IX_ETH_DB_GET_VLAN_ID(entry->recordData.filteringVlanData.ieee802_1qTag) ==
IX_ETH_DB_GET_VLAN_ID(reference->recordData.filteringVlanData.ieee802_1qTag)) &&
(ixEthDBAddressCompare(entry->macAddress, reference->macAddress) == 0);
}
/**
* @brief matches two database records based on their MAC addresses
* and port IDs
*
* @param untypedReference record to match against
* @param untypedEntry record to match
*
* @return TRUE if the match is successful or FALSE otherwise
*
* @internal
*/
IX_ETH_DB_PUBLIC
BOOL ixEthDBPortRecordMatch(void *untypedReference, void *untypedEntry)
{
MacDescriptor *entry = (MacDescriptor *) untypedEntry;
MacDescriptor *reference = (MacDescriptor *) untypedReference;
/* check accepted record types */
if ((entry->type & reference->type) == 0) return FALSE;
return (entry->portID == reference->portID) &&
(ixEthDBAddressCompare(entry->macAddress, reference->macAddress) == 0);
}
/**
* @brief dummy matching function, registered for safety
*
* @param reference record to match against (unused)
* @param entry record to match (unused)
*
* This function is registered in the matching functions
* array on invalid types. Calling it will display an
* error message, indicating an error in the component logic.
*
* @return FALSE
*
* @internal
*/
IX_ETH_DB_PUBLIC
BOOL ixEthDBNullMatch(void *reference, void *entry)
{
/* display an error message */
ixOsalLog(IX_OSAL_LOG_LVL_WARNING, IX_OSAL_LOG_DEV_STDOUT, "DB: (Search) The NullMatch function was called, wrong key type?\n", 0, 0, 0, 0, 0, 0);
return FALSE;
}
/**
* @brief registers hash matching methods
*
* @param matchFunctions table of match functions to be populated
*
* This function registers the available record matching functions
* by indexing them on record types into the given function array.
*
* Note that it is compulsory to call this in ixEthDBInit(),
* otherwise hashtable searching and removal will not work
*
* @return number of registered functions
*
* @internal
*/
IX_ETH_DB_PUBLIC
UINT32 ixEthDBMatchMethodsRegister(MatchFunction *matchFunctions)
{
UINT32 i;
/* safety first */
for ( i = 0 ; i < IX_ETH_DB_MAX_KEY_INDEX + 1 ; i++)
{
matchFunctions[i] = ixEthDBNullMatch;
}
/* register MAC search method */
matchFunctions[IX_ETH_DB_MAC_KEY] = ixEthDBAddressRecordMatch;
/* register MAC/PortID search method */
matchFunctions[IX_ETH_DB_MAC_PORT_KEY] = ixEthDBPortRecordMatch;
/* register MAC/VLAN ID search method */
matchFunctions[IX_ETH_DB_MAC_VLAN_KEY] = ixEthDBVlanRecordMatch;
return 3; /* three methods */
}
/**
* @brief search a record in the Ethernet datbase
*
* @param macAddress MAC address to perform the search on
* @param typeFilter type of records to consider for matching
*
* @warning if searching is successful an implicit write lock
* to the search result is granted, therefore unlock the
* entry using @ref ixEthDBReleaseHashNode() as soon as possible.
*
* @see ixEthDBReleaseHashNode()
*
* @return the search result, or NULL if a record with the given
* MAC address was not found
*
* @internal
*/
IX_ETH_DB_PUBLIC
HashNode* ixEthDBSearch(IxEthDBMacAddr *macAddress, IxEthDBRecordType typeFilter)
{
HashNode *searchResult = NULL;
MacDescriptor reference;
TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER;
if (macAddress == NULL)
{
return NULL;
}
/* fill search fields */
memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr));
/* set acceptable record types */
reference.type = typeFilter;
BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, IX_ETH_DB_MAC_KEY, &reference, &searchResult));
return searchResult;
}
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBPeek(IxEthDBMacAddr *macAddress, IxEthDBRecordType typeFilter)
{
MacDescriptor reference;
IxEthDBStatus result;
TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER;
if (macAddress == NULL)
{
return IX_ETH_DB_INVALID_ARG;
}
/* fill search fields */
memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr));
/* set acceptable record types */
reference.type = typeFilter;
result = ixEthDBPeekHashEntry(&dbHashtable, IX_ETH_DB_MAC_KEY, &reference);
return result;
}
/**
* @brief search a record in the Ethernet datbase
*
* @param macAddress MAC address to perform the search on
* @param portID port ID to perform the search on
* @param typeFilter type of records to consider for matching
*
* @warning if searching is successful an implicit write lock
* to the search result is granted, therefore unlock the
* entry using @ref ixEthDBReleaseHashNode() as soon as possible.
*
* @see ixEthDBReleaseHashNode()
*
* @return the search result, or NULL if a record with the given
* MAC address/port ID combination was not found
*
* @internal
*/
IX_ETH_DB_PUBLIC
HashNode* ixEthDBPortSearch(IxEthDBMacAddr *macAddress, IxEthDBPortId portID, IxEthDBRecordType typeFilter)
{
HashNode *searchResult = NULL;
MacDescriptor reference;
if (macAddress == NULL)
{
return NULL;
}
/* fill search fields */
memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr));
reference.portID = portID;
/* set acceptable record types */
reference.type = typeFilter;
BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, IX_ETH_DB_MAC_PORT_KEY, &reference, &searchResult));
return searchResult;
}
/**
* @brief search a record in the Ethernet datbase
*
* @param macAddress MAC address to perform the search on
* @param vlanID VLAN ID to perform the search on
* @param typeFilter type of records to consider for matching
*
* @warning if searching is successful an implicit write lock
* to the search result is granted, therefore unlock the
* entry using @ref ixEthDBReleaseHashNode() as soon as possible.
*
* @see ixEthDBReleaseHashNode()
*
* @return the search result, or NULL if a record with the given
* MAC address/VLAN ID combination was not found
*
* @internal
*/
IX_ETH_DB_PUBLIC
HashNode* ixEthDBVlanSearch(IxEthDBMacAddr *macAddress, IxEthDBVlanId vlanID, IxEthDBRecordType typeFilter)
{
HashNode *searchResult = NULL;
MacDescriptor reference;
if (macAddress == NULL)
{
return NULL;
}
/* fill search fields */
memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr));
reference.recordData.filteringVlanData.ieee802_1qTag =
IX_ETH_DB_SET_VLAN_ID(reference.recordData.filteringVlanData.ieee802_1qTag, vlanID);
/* set acceptable record types */
reference.type = typeFilter;
BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, IX_ETH_DB_MAC_VLAN_KEY, &reference, &searchResult));
return searchResult;
}

View file

@ -0,0 +1,107 @@
/**
* @file IxEthDBSpanningTree.c
*
* @brief Implementation of the STP API
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#include "IxEthDB_p.h"
/**
* @brief sets the STP blocking state of a port
*
* @param portID ID of the port
* @param blocked TRUE to block the port or FALSE to unblock it
*
* Note that this function is documented in the main component
* header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed successfully
* or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBSpanningTreeBlockingStateSet(IxEthDBPortId portID, BOOL blocked)
{
IxNpeMhMessage message;
IX_STATUS result;
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_SPANNING_TREE_PROTOCOL);
ixEthDBPortInfo[portID].stpBlocked = blocked;
FILL_SETBLOCKINGSTATE_MSG(message, portID, blocked);
IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
return result;
}
/**
* @brief retrieves the STP blocking state of a port
*
* @param portID ID of the port
* @param blocked address to write the blocked status into
*
* Note that this function is documented in the main component
* header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed successfully
* or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBSpanningTreeBlockingStateGet(IxEthDBPortId portID, BOOL *blocked)
{
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_SPANNING_TREE_PROTOCOL);
IX_ETH_DB_CHECK_REFERENCE(blocked);
*blocked = ixEthDBPortInfo[portID].stpBlocked;
return IX_ETH_DB_SUCCESS;
}

120
cpu/ixp/npe/IxEthDBUtil.c Normal file
View file

@ -0,0 +1,120 @@
/**
* @file ethUtil.c
*
* @brief Utility functions
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#include "IxFeatureCtrl.h"
#include "IxEthDB_p.h"
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBSingleEthNpeCheck(IxEthDBPortId portID)
{
/* If not IXP42X A0 stepping, proceed to check for existence of coprocessors */
if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
(ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
|| (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
{
if ((portID == 0) &&
(ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) ==
IX_FEATURE_CTRL_COMPONENT_DISABLED))
{
return IX_ETH_DB_FAIL;
}
if ((portID == 1) &&
(ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) ==
IX_FEATURE_CTRL_COMPONENT_DISABLED))
{
return IX_ETH_DB_FAIL;
}
if ((portID == 2) &&
(ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA_ETH) ==
IX_FEATURE_CTRL_COMPONENT_DISABLED))
{
return IX_ETH_DB_FAIL;
}
}
return IX_ETH_DB_SUCCESS;
}
IX_ETH_DB_PUBLIC
BOOL ixEthDBCheckSingleBitValue(UINT32 value)
{
#if (CPU != SIMSPARCSOLARIS) && !defined (__wince)
UINT32 shift;
/* use the count-leading-zeros XScale instruction */
__asm__ ("clz %0, %1\n" : "=r" (shift) : "r" (value));
return ((value << shift) == 0x80000000UL);
#else
while (value != 0)
{
if (value == 1) return TRUE;
else if ((value & 1) == 1) return FALSE;
value >>= 1;
}
return FALSE;
#endif
}
const char *mac2string(const unsigned char *mac)
{
static char str[19];
if (mac == NULL)
{
return NULL;
}
sprintf(str, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
return str;
}

1179
cpu/ixp/npe/IxEthDBVlan.c Normal file

File diff suppressed because it is too large Load diff

480
cpu/ixp/npe/IxEthDBWiFi.c Normal file
View file

@ -0,0 +1,480 @@
/**
* @file IxEthDBAPI.c
*
* @brief Implementation of the public API
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#include "IxEthDB_p.h"
/* forward prototypes */
IX_ETH_DB_PUBLIC
MacTreeNode *ixEthDBGatewaySelect(MacTreeNode *stations);
/**
* @brief sets the BBSID value for the WiFi header conversion feature
*
* @param portID ID of the port
* @param bbsid pointer to the 6-byte BBSID value
*
* Note that this function is documented in the main component
* header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed successfully
* or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBWiFiBBSIDSet(IxEthDBPortId portID, IxEthDBMacAddr *bbsid)
{
IxNpeMhMessage message;
IX_STATUS result;
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
IX_ETH_DB_CHECK_REFERENCE(bbsid);
memcpy(ixEthDBPortInfo[portID].bbsid, bbsid, sizeof (IxEthDBMacAddr));
FILL_SETBBSID_MSG(message, portID, bbsid);
IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
return result;
}
/**
* @brief updates the Frame Control and Duration/ID WiFi header
* conversion parameters in an NPE
*
* @param portID ID of the port
*
* This function will send a message to the NPE updating the
* frame conversion parameters for 802.3 => 802.11 header conversion.
*
* @return IX_ETH_DB_SUCCESS if the operation completed successfully
* or IX_ETH_DB_FAIL otherwise
*
* @internal
*/
IX_ETH_DB_PRIVATE
IxEthDBStatus ixEthDBWiFiFrameControlDurationIDUpdate(IxEthDBPortId portID)
{
IxNpeMhMessage message;
IX_STATUS result;
FILL_SETFRAMECONTROLDURATIONID(message, portID, ixEthDBPortInfo[portID].frameControlDurationID);
IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
return result;
}
/**
* @brief sets the Duration/ID WiFi frame header conversion parameter
*
* @param portID ID of the port
* @param durationID 16-bit value containing the new Duration/ID parameter
*
* Note that this function is documented in the main component
* header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed successfully
* or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBWiFiDurationIDSet(IxEthDBPortId portID, UINT16 durationID)
{
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
ixEthDBPortInfo[portID].frameControlDurationID = (ixEthDBPortInfo[portID].frameControlDurationID & 0xFFFF0000) | durationID;
return ixEthDBWiFiFrameControlDurationIDUpdate(portID);
}
/**
* @brief sets the Frame Control WiFi frame header conversion parameter
*
* @param portID ID of the port
* @param durationID 16-bit value containing the new Frame Control parameter
*
* Note that this function is documented in the main component
* header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed successfully
* or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBWiFiFrameControlSet(IxEthDBPortId portID, UINT16 frameControl)
{
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
ixEthDBPortInfo[portID].frameControlDurationID = (ixEthDBPortInfo[portID].frameControlDurationID & 0xFFFF) | (frameControl << 16);
return ixEthDBWiFiFrameControlDurationIDUpdate(portID);
}
/**
* @brief removes a WiFi header conversion record
*
* @param portID ID of the port
* @param macAddr MAC address of the record to remove
*
* Note that this function is documented in the main
* component header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBWiFiEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
{
MacDescriptor recordTemplate;
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_REFERENCE(macAddr);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
memcpy(recordTemplate.macAddress, macAddr, sizeof (IxEthDBMacAddr));
recordTemplate.type = IX_ETH_DB_WIFI_RECORD;
recordTemplate.portID = portID;
return ixEthDBRemove(&recordTemplate, NULL);
}
/**
* @brief adds a WiFi header conversion record
*
* @param portID ID of the port
* @param macAddr MAC address of the record to add
* @param gatewayMacAddr address of the gateway (or
* NULL if this is a station record)
*
* This function adds a record of type AP_TO_AP (gateway is not NULL)
* or AP_TO_STA (gateway is NULL) in the main database as a
* WiFi header conversion record.
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully or an appropriate error message otherwise
*
* @internal
*/
IX_ETH_DB_PRIVATE
IxEthDBStatus ixEthDBWiFiEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr, IxEthDBMacAddr *gatewayMacAddr)
{
MacDescriptor recordTemplate;
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_REFERENCE(macAddr);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
memcpy(recordTemplate.macAddress, macAddr, sizeof (IxEthDBMacAddr));
recordTemplate.type = IX_ETH_DB_WIFI_RECORD;
recordTemplate.portID = portID;
if (gatewayMacAddr != NULL)
{
memcpy(recordTemplate.recordData.wifiData.gwMacAddress, gatewayMacAddr, sizeof (IxEthDBMacAddr));
recordTemplate.recordData.wifiData.type = IX_ETH_DB_WIFI_AP_TO_AP;
}
else
{
memset(recordTemplate.recordData.wifiData.gwMacAddress, 0, sizeof (IxEthDBMacAddr));
recordTemplate.recordData.wifiData.type = IX_ETH_DB_WIFI_AP_TO_STA;
}
return ixEthDBAdd(&recordTemplate, NULL);
}
/**
* @brief adds a WiFi header conversion record
*
* @param portID ID of the port
* @param macAddr MAC address of the record to add
* @param gatewayMacAddr address of the gateway
*
* This function adds a record of type AP_TO_AP
* in the main database as a WiFi header conversion record.
*
* This is simply a wrapper over @ref ixEthDBWiFiEntryAdd().
*
* Note that this function is documented in the main
* component header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBWiFiAccessPointEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr, IxEthDBMacAddr *gatewayMacAddr)
{
IX_ETH_DB_CHECK_REFERENCE(gatewayMacAddr);
return ixEthDBWiFiEntryAdd(portID, macAddr, gatewayMacAddr);
}
/**
* @brief adds a WiFi header conversion record
*
* @param portID ID of the port
* @param macAddr MAC address of the record to add
*
* This function adds a record of type AP_TO_STA
* in the main database as a WiFi header conversion record.
*
* This is simply a wrapper over @ref ixEthDBWiFiEntryAdd().
*
* Note that this function is documented in the main
* component header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBWiFiStationEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
{
return ixEthDBWiFiEntryAdd(portID, macAddr, NULL);
}
/**
* @brief selects a set of gateways from a tree of
* WiFi header conversion records
*
* @param stations binary tree containing pointers to WiFi header
* conversion records
*
* This function browses through the input binary tree, identifies
* records of type AP_TO_AP, clones these records and appends them
* to a vine (a single right-branch binary tree) which is returned
* as result. A maximum of MAX_GW_SIZE entries containing gateways
* will be cloned from the original tree.
*
* @return vine (linear binary tree) containing record
* clones of AP_TO_AP type, which have a gateway field
*
* @internal
*/
IX_ETH_DB_PUBLIC
MacTreeNode *ixEthDBGatewaySelect(MacTreeNode *stations)
{
MacTreeNodeStack *stack;
MacTreeNode *gateways, *insertionPlace;
UINT32 gwIndex = 1; /* skip the empty root */
if (stations == NULL)
{
return NULL;
}
stack = ixOsalCacheDmaMalloc(sizeof (MacTreeNodeStack));
if (stack == NULL)
{
ERROR_LOG("DB: (WiFi) failed to allocate the node stack for gateway tree linearization, out of memory?\n");
return NULL;
}
/* initialize root node */
gateways = insertionPlace = NULL;
/* start browsing the station tree */
NODE_STACK_INIT(stack);
/* initialize stack by pushing the tree root at offset 0 */
NODE_STACK_PUSH(stack, stations, 0);
while (NODE_STACK_NONEMPTY(stack))
{
MacTreeNode *node;
UINT32 offset;
NODE_STACK_POP(stack, node, offset);
/* we can store maximum 31 (32 total, 1 empty root) entries in the gateway tree */
if (offset > (MAX_GW_SIZE - 1)) break;
/* check if this record has a gateway address */
if (node->descriptor != NULL && node->descriptor->recordData.wifiData.type == IX_ETH_DB_WIFI_AP_TO_AP)
{
/* found a record, create an insertion place */
if (insertionPlace != NULL)
{
insertionPlace->right = ixEthDBAllocMacTreeNode();
insertionPlace = insertionPlace->right;
}
else
{
gateways = ixEthDBAllocMacTreeNode();
insertionPlace = gateways;
}
if (insertionPlace == NULL)
{
/* no nodes left, bail out with what we have */
ixOsalCacheDmaFree(stack);
return gateways;
}
/* clone the original record for the gateway tree */
insertionPlace->descriptor = ixEthDBCloneMacDescriptor(node->descriptor);
/* insert and update the offset in the original record */
node->descriptor->recordData.wifiData.gwAddressIndex = gwIndex++;
}
/* browse the tree */
if (node->left != NULL)
{
NODE_STACK_PUSH(stack, node->left, LEFT_CHILD_OFFSET(offset));
}
if (node->right != NULL)
{
NODE_STACK_PUSH(stack, node->right, RIGHT_CHILD_OFFSET(offset));
}
}
ixOsalCacheDmaFree(stack);
return gateways;
}
/**
* @brief downloads the WiFi header conversion table to an NPE
*
* @param portID ID of the port
*
* This function prepares the WiFi header conversion tables and
* downloads them to the specified NPE port.
*
* The header conversion tables consist in the main table of
* addresses and the secondary table of gateways. AP_TO_AP records
* from the first table contain index fields into the second table
* for gateway selection.
*
* Note that this function is documented in the main component
* header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed successfully
* or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBWiFiConversionTableDownload(IxEthDBPortId portID)
{
IxEthDBPortMap query;
MacTreeNode *stations = NULL, *gateways = NULL, *gateway = NULL;
IxNpeMhMessage message;
PortInfo *portInfo;
IX_STATUS result;
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
portInfo = &ixEthDBPortInfo[portID];
SET_DEPENDENCY_MAP(query, portID);
ixEthDBUpdateLock();
stations = ixEthDBQuery(NULL, query, IX_ETH_DB_WIFI_RECORD, MAX_ELT_SIZE);
gateways = ixEthDBGatewaySelect(stations);
/* clean up gw area */
memset((void *) portInfo->updateMethod.npeGwUpdateZone, FULL_GW_BYTE_SIZE, 0);
/* write all gateways */
gateway = gateways;
while (gateway != NULL)
{
ixEthDBNPEGatewayNodeWrite((void *) (((UINT32) portInfo->updateMethod.npeGwUpdateZone)
+ gateway->descriptor->recordData.wifiData.gwAddressIndex * ELT_ENTRY_SIZE),
gateway);
gateway = gateway->right;
}
/* free the gateway tree */
if (gateways != NULL)
{
ixEthDBFreeMacTreeNode(gateways);
}
FILL_SETAPMACTABLE_MSG(message,
IX_OSAL_MMU_VIRT_TO_PHYS(portInfo->updateMethod.npeGwUpdateZone));
IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
if (result == IX_SUCCESS)
{
/* update the main tree (the stations tree) */
portInfo->updateMethod.searchTree = stations;
result = ixEthDBNPEUpdateHandler(portID, IX_ETH_DB_WIFI_RECORD);
}
ixEthDBUpdateUnlock();
return result;
}

497
cpu/ixp/npe/IxEthMii.c Normal file
View file

@ -0,0 +1,497 @@
/**
* @file IxEthMii.c
*
* @author Intel Corporation
* @date
*
* @brief MII control functions
*
* Design Notes:
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#include "IxOsal.h"
#include "IxEthAcc.h"
#include "IxEthMii_p.h"
#ifdef __wince
#include "IxOsPrintf.h"
#endif
/* Array to store the phy IDs of the discovered phys */
PRIVATE UINT32 ixEthMiiPhyId[IXP425_ETH_ACC_MII_MAX_ADDR];
/*********************************************************
*
* Scan for PHYs on the MII bus. This function returns
* an array of booleans, one for each PHY address.
* If a PHY is found at a particular address, the
* corresponding entry in the array is set to TRUE.
*
*/
PUBLIC IX_STATUS
ixEthMiiPhyScan(BOOL phyPresent[], UINT32 maxPhyCount)
{
UINT32 i;
UINT16 regval, regvalId1, regvalId2;
/*Search for PHYs on the MII*/
/*Search for existant phys on the MDIO bus*/
if ((phyPresent == NULL) ||
(maxPhyCount > IXP425_ETH_ACC_MII_MAX_ADDR))
{
return IX_FAIL;
}
/* fill the array */
for(i=0;
i<IXP425_ETH_ACC_MII_MAX_ADDR;
i++)
{
phyPresent[i] = FALSE;
}
/* iterate through the PHY addresses */
for(i=0;
maxPhyCount > 0 && i<IXP425_ETH_ACC_MII_MAX_ADDR;
i++)
{
ixEthMiiPhyId[i] = IX_ETH_MII_INVALID_PHY_ID;
if(ixEthAccMiiReadRtn(i,
IX_ETH_MII_CTRL_REG,
&regval) == IX_ETH_ACC_SUCCESS)
{
if((regval & 0xffff) != 0xffff)
{
maxPhyCount--;
/*Need to read the register twice here to flush PHY*/
ixEthAccMiiReadRtn(i, IX_ETH_MII_PHY_ID1_REG, &regvalId1);
ixEthAccMiiReadRtn(i, IX_ETH_MII_PHY_ID1_REG, &regvalId1);
ixEthAccMiiReadRtn(i, IX_ETH_MII_PHY_ID2_REG, &regvalId2);
ixEthMiiPhyId[i] = (regvalId1 << IX_ETH_MII_REG_SHL) | regvalId2;
if ((ixEthMiiPhyId[i] == IX_ETH_MII_KS8995_PHY_ID)
|| (ixEthMiiPhyId[i] == IX_ETH_MII_LXT971_PHY_ID)
|| (ixEthMiiPhyId[i] == IX_ETH_MII_LXT972_PHY_ID)
|| (ixEthMiiPhyId[i] == IX_ETH_MII_LXT973_PHY_ID)
|| (ixEthMiiPhyId[i] == IX_ETH_MII_LXT973A3_PHY_ID)
|| (ixEthMiiPhyId[i] == IX_ETH_MII_LXT9785_PHY_ID)
)
{
/* supported phy */
phyPresent[i] = TRUE;
} /* end of if(ixEthMiiPhyId) */
else
{
if (ixEthMiiPhyId[i] != IX_ETH_MII_INVALID_PHY_ID)
{
/* unsupported phy */
ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
IX_OSAL_LOG_DEV_STDOUT,
"ixEthMiiPhyScan : unexpected Mii PHY ID %8.8x\n",
ixEthMiiPhyId[i], 2, 3, 4, 5, 6);
ixEthMiiPhyId[i] = IX_ETH_MII_UNKNOWN_PHY_ID;
phyPresent[i] = TRUE;
}
}
}
}
}
return IX_SUCCESS;
}
/************************************************************
*
* Configure the PHY at the specified address
*
*/
PUBLIC IX_STATUS
ixEthMiiPhyConfig(UINT32 phyAddr,
BOOL speed100,
BOOL fullDuplex,
BOOL autonegotiate)
{
UINT16 regval=0;
/* parameter check */
if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) &&
(ixEthMiiPhyId[phyAddr] != IX_ETH_MII_INVALID_PHY_ID))
{
/*
* set the control register
*/
if(autonegotiate)
{
regval |= IX_ETH_MII_CR_AUTO_EN | IX_ETH_MII_CR_RESTART;
}
else
{
if(speed100)
{
regval |= IX_ETH_MII_CR_100;
}
if(fullDuplex)
{
regval |= IX_ETH_MII_CR_FDX;
}
} /* end of if-else() */
if (ixEthAccMiiWriteRtn(phyAddr,
IX_ETH_MII_CTRL_REG,
regval) == IX_ETH_ACC_SUCCESS)
{
return IX_SUCCESS;
}
} /* end of if(phyAddr) */
return IX_FAIL;
}
/******************************************************************
*
* Enable the PHY Loopback at the specified address
*/
PUBLIC IX_STATUS
ixEthMiiPhyLoopbackEnable (UINT32 phyAddr)
{
UINT16 regval ;
if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) &&
(IX_ETH_MII_INVALID_PHY_ID != ixEthMiiPhyId[phyAddr]))
{
/* read/write the control register */
if(ixEthAccMiiReadRtn (phyAddr,
IX_ETH_MII_CTRL_REG,
&regval)
== IX_ETH_ACC_SUCCESS)
{
if(ixEthAccMiiWriteRtn (phyAddr,
IX_ETH_MII_CTRL_REG,
regval | IX_ETH_MII_CR_LOOPBACK)
== IX_ETH_ACC_SUCCESS)
{
return IX_SUCCESS;
}
}
}
return IX_FAIL;
}
/******************************************************************
*
* Disable the PHY Loopback at the specified address
*/
PUBLIC IX_STATUS
ixEthMiiPhyLoopbackDisable (UINT32 phyAddr)
{
UINT16 regval ;
if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) &&
(IX_ETH_MII_INVALID_PHY_ID != ixEthMiiPhyId[phyAddr]))
{
/* read/write the control register */
if(ixEthAccMiiReadRtn (phyAddr,
IX_ETH_MII_CTRL_REG,
&regval)
== IX_ETH_ACC_SUCCESS)
{
if(ixEthAccMiiWriteRtn (phyAddr,
IX_ETH_MII_CTRL_REG,
regval & (~IX_ETH_MII_CR_LOOPBACK))
== IX_ETH_ACC_SUCCESS)
{
return IX_SUCCESS;
}
}
}
return IX_FAIL;
}
/******************************************************************
*
* Reset the PHY at the specified address
*/
PUBLIC IX_STATUS
ixEthMiiPhyReset(UINT32 phyAddr)
{
UINT32 timeout;
UINT16 regval;
if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) &&
(ixEthMiiPhyId[phyAddr] != IX_ETH_MII_INVALID_PHY_ID))
{
if ((ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT971_PHY_ID) ||
(ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT972_PHY_ID) ||
(ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT973_PHY_ID) ||
(ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT973A3_PHY_ID) ||
(ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT9785_PHY_ID)
)
{
/* use the control register to reset the phy */
ixEthAccMiiWriteRtn(phyAddr,
IX_ETH_MII_CTRL_REG,
IX_ETH_MII_CR_RESET);
/* poll until the reset bit is cleared */
timeout = 0;
do
{
ixOsalSleep (IX_ETH_MII_RESET_POLL_MS);
/* read the control register and check for timeout */
ixEthAccMiiReadRtn(phyAddr,
IX_ETH_MII_CTRL_REG,
&regval);
if ((regval & IX_ETH_MII_CR_RESET) == 0)
{
/* timeout bit is self-cleared */
break;
}
timeout += IX_ETH_MII_RESET_POLL_MS;
}
while (timeout < IX_ETH_MII_RESET_DELAY_MS);
/* check for timeout */
if (timeout >= IX_ETH_MII_RESET_DELAY_MS)
{
ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG,
IX_ETH_MII_CR_NORM_EN);
return IX_FAIL;
}
return IX_SUCCESS;
} /* end of if(ixEthMiiPhyId) */
else if (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_KS8995_PHY_ID)
{
/* reset bit is reserved, just reset the control register */
ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG,
IX_ETH_MII_CR_NORM_EN);
return IX_SUCCESS;
}
else
{
/* unknown PHY, set the control register reset bit,
* wait 2 s. and clear the control register.
*/
ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG,
IX_ETH_MII_CR_RESET);
ixOsalSleep (IX_ETH_MII_RESET_DELAY_MS);
ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG,
IX_ETH_MII_CR_NORM_EN);
return IX_SUCCESS;
} /* end of if-else(ixEthMiiPhyId) */
} /* end of if(phyAddr) */
return IX_FAIL;
}
/*****************************************************************
*
* Link state query functions
*/
PUBLIC IX_STATUS
ixEthMiiLinkStatus(UINT32 phyAddr,
BOOL *linkUp,
BOOL *speed100,
BOOL *fullDuplex,
BOOL *autoneg)
{
UINT16 ctrlRegval, statRegval, regval, regval4, regval5;
/* check the parameters */
if ((linkUp == NULL) ||
(speed100 == NULL) ||
(fullDuplex == NULL) ||
(autoneg == NULL))
{
return IX_FAIL;
}
*linkUp = FALSE;
*speed100 = FALSE;
*fullDuplex = FALSE;
*autoneg = FALSE;
if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) &&
(ixEthMiiPhyId[phyAddr] != IX_ETH_MII_INVALID_PHY_ID))
{
if ((ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT971_PHY_ID) ||
(ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT972_PHY_ID) ||
(ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT9785_PHY_ID)
)
{
/* --------------------------------------------------*/
/* Retrieve information from PHY specific register */
/* --------------------------------------------------*/
if (ixEthAccMiiReadRtn(phyAddr,
IX_ETH_MII_STAT2_REG,
&regval) != IX_ETH_ACC_SUCCESS)
{
return IX_FAIL;
}
*linkUp = ((regval & IX_ETH_MII_SR2_LINK) != 0);
*speed100 = ((regval & IX_ETH_MII_SR2_100) != 0);
*fullDuplex = ((regval & IX_ETH_MII_SR2_FD) != 0);
*autoneg = ((regval & IX_ETH_MII_SR2_AUTO) != 0);
return IX_SUCCESS;
} /* end of if(ixEthMiiPhyId) */
else
{
/* ----------------------------------------------------*/
/* Retrieve information from status and ctrl registers */
/* ----------------------------------------------------*/
if (ixEthAccMiiReadRtn(phyAddr,
IX_ETH_MII_CTRL_REG,
&ctrlRegval) != IX_ETH_ACC_SUCCESS)
{
return IX_FAIL;
}
ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_STAT_REG, &statRegval);
*linkUp = ((statRegval & IX_ETH_MII_SR_LINK_STATUS) != 0);
if (*linkUp)
{
*autoneg = ((ctrlRegval & IX_ETH_MII_CR_AUTO_EN) != 0) &&
((statRegval & IX_ETH_MII_SR_AUTO_SEL) != 0) &&
((statRegval & IX_ETH_MII_SR_AUTO_NEG) != 0);
if (*autoneg)
{
/* mask the current stat values with the capabilities */
ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_AN_ADS_REG, &regval4);
ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_AN_PRTN_REG, &regval5);
/* merge the flags from the 3 registers */
regval = (statRegval & ((regval4 & regval5) << 6));
/* initialise from status register values */
if ((regval & IX_ETH_MII_SR_TX_FULL_DPX) != 0)
{
/* 100 Base X full dplx */
*speed100 = TRUE;
*fullDuplex = TRUE;
return IX_SUCCESS;
}
if ((regval & IX_ETH_MII_SR_TX_HALF_DPX) != 0)
{
/* 100 Base X half dplx */
*speed100 = TRUE;
return IX_SUCCESS;
}
if ((regval & IX_ETH_MII_SR_10T_FULL_DPX) != 0)
{
/* 10 mb full dplx */
*fullDuplex = TRUE;
return IX_SUCCESS;
}
if ((regval & IX_ETH_MII_SR_10T_HALF_DPX) != 0)
{
/* 10 mb half dplx */
return IX_SUCCESS;
}
} /* end of if(autoneg) */
else
{
/* autonegotiate not complete, return setup parameters */
*speed100 = ((ctrlRegval & IX_ETH_MII_CR_100) != 0);
*fullDuplex = ((ctrlRegval & IX_ETH_MII_CR_FDX) != 0);
}
} /* end of if(linkUp) */
} /* end of if-else(ixEthMiiPhyId) */
} /* end of if(phyAddr) */
else
{
return IX_FAIL;
} /* end of if-else(phyAddr) */
return IX_SUCCESS;
}
/*****************************************************************
*
* Link state display functions
*/
PUBLIC IX_STATUS
ixEthMiiPhyShow (UINT32 phyAddr)
{
BOOL linkUp, speed100, fullDuplex, autoneg;
UINT16 cregval;
UINT16 sregval;
ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_STAT_REG, &sregval);
ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_CTRL_REG, &cregval);
/* get link information */
if (ixEthMiiLinkStatus(phyAddr,
&linkUp,
&speed100,
&fullDuplex,
&autoneg) != IX_ETH_ACC_SUCCESS)
{
printf("PHY Status unknown\n");
return IX_FAIL;
}
printf("PHY ID [phyAddr]: %8.8x\n",ixEthMiiPhyId[phyAddr]);
printf( " Status reg: %4.4x\n",sregval);
printf( " control reg: %4.4x\n",cregval);
/* display link information */
printf("PHY Status:\n");
printf(" Link is %s\n",
(linkUp ? "Up" : "Down"));
if((sregval & IX_ETH_MII_SR_REMOTE_FAULT) != 0)
{
printf(" Remote fault detected\n");
}
printf(" Auto Negotiation %s\n",
(autoneg ? "Completed" : "Not Completed"));
printf("PHY Configuration:\n");
printf(" Speed %sMb/s\n",
(speed100 ? "100" : "10"));
printf(" %s Duplex\n",
(fullDuplex ? "Full" : "Half"));
printf(" Auto Negotiation %s\n",
(autoneg ? "Enabled" : "Disabled"));
return IX_SUCCESS;
}

422
cpu/ixp/npe/IxFeatureCtrl.c Normal file
View file

@ -0,0 +1,422 @@
/**
* @file IxFeatureCtrl.c
*
* @author Intel Corporation
* @date 29-Jan-2003
*
* @brief Feature Control Public API Implementation
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#include "IxOsal.h"
#include "IxVersionId.h"
#include "IxFeatureCtrl.h"
/* Macro to read from the Feature Control Register */
#define IX_FEATURE_CTRL_READ(result) \
do { \
ixFeatureCtrlExpMap(); \
(result) = IX_OSAL_READ_LONG(ixFeatureCtrlRegister); \
} while (0)
/* Macro to write to the Feature Control Register */
#define IX_FEATURE_CTRL_WRITE(value) \
do { \
ixFeatureCtrlExpMap(); \
IX_OSAL_WRITE_LONG(ixFeatureCtrlRegister, (value)); \
} while (0)
/*
* This is the offset of the feature register relative to the base of the
* Expansion Bus Controller MMR.
*/
#define IX_FEATURE_CTRL_REG_OFFSET (0x00000028)
/* Boolean to mark the fact that the EXP_CONFIG address space was mapped */
PRIVATE BOOL ixFeatureCtrlExpCfgRegionMapped = FALSE;
/* Pointer holding the virtual address of the Feature Control Register */
PRIVATE VUINT32 *ixFeatureCtrlRegister = NULL;
/* Place holder to store the software configuration */
PRIVATE BOOL swConfiguration[IX_FEATURECTRL_SWCONFIG_MAX];
/* Flag to control swConfiguration[] is initialized once */
PRIVATE BOOL swConfigurationFlag = FALSE ;
/* Array containing component mask values */
#ifdef __ixp42X
UINT32 componentMask[IX_FEATURECTRL_MAX_COMPONENTS] = {
(0x1<<IX_FEATURECTRL_RCOMP),
(0x1<<IX_FEATURECTRL_USB),
(0x1<<IX_FEATURECTRL_HASH),
(0x1<<IX_FEATURECTRL_AES),
(0x1<<IX_FEATURECTRL_DES),
(0x1<<IX_FEATURECTRL_HDLC),
(0x1<<IX_FEATURECTRL_AAL),
(0x1<<IX_FEATURECTRL_HSS),
(0x1<<IX_FEATURECTRL_UTOPIA),
(0x1<<IX_FEATURECTRL_ETH0),
(0x1<<IX_FEATURECTRL_ETH1),
(0x1<<IX_FEATURECTRL_NPEA),
(0x1<<IX_FEATURECTRL_NPEB),
(0x1<<IX_FEATURECTRL_NPEC),
(0x1<<IX_FEATURECTRL_PCI),
IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE,
(0x3<<IX_FEATURECTRL_UTOPIA_PHY_LIMIT),
(0x1<<IX_FEATURECTRL_UTOPIA_PHY_LIMIT_BIT2),
IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE,
IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE,
IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE,
IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE,
IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE
};
#elif defined (__ixp46X)
UINT32 componentMask[IX_FEATURECTRL_MAX_COMPONENTS] = {
(0x1<<IX_FEATURECTRL_RCOMP),
(0x1<<IX_FEATURECTRL_USB),
(0x1<<IX_FEATURECTRL_HASH),
(0x1<<IX_FEATURECTRL_AES),
(0x1<<IX_FEATURECTRL_DES),
(0x1<<IX_FEATURECTRL_HDLC),
IX_FEATURECTRL_COMPONENT_ALWAYS_AVAILABLE, /* AAL component is always on */
(0x1<<IX_FEATURECTRL_HSS),
(0x1<<IX_FEATURECTRL_UTOPIA),
(0x1<<IX_FEATURECTRL_ETH0),
(0x1<<IX_FEATURECTRL_ETH1),
(0x1<<IX_FEATURECTRL_NPEA),
(0x1<<IX_FEATURECTRL_NPEB),
(0x1<<IX_FEATURECTRL_NPEC),
(0x1<<IX_FEATURECTRL_PCI),
(0x1<<IX_FEATURECTRL_ECC_TIMESYNC),
(0x3<<IX_FEATURECTRL_UTOPIA_PHY_LIMIT),
(0x1<<IX_FEATURECTRL_UTOPIA_PHY_LIMIT_BIT2), /* NOT TO BE USED */
(0x1<<IX_FEATURECTRL_USB_HOST_CONTROLLER),
(0x1<<IX_FEATURECTRL_NPEA_ETH),
(0x1<<IX_FEATURECTRL_NPEB_ETH),
(0x1<<IX_FEATURECTRL_RSA),
(0x3<<IX_FEATURECTRL_XSCALE_MAX_FREQ),
(0x1<<IX_FEATURECTRL_XSCALE_MAX_FREQ_BIT2)
};
#endif /* __ixp42X */
/**
* Forward declaration
*/
PRIVATE
void ixFeatureCtrlExpMap(void);
PRIVATE
void ixFeatureCtrlSwConfigurationInit(void);
/**
* Function to map EXP_CONFIG space
*/
PRIVATE
void ixFeatureCtrlExpMap(void)
{
UINT32 expCfgBaseAddress = 0;
/* If the EXP Configuration space has already been mapped then
* return */
if (ixFeatureCtrlExpCfgRegionMapped == TRUE)
{
return;
}
/* Map (get virtual address) for the EXP_CONFIG space */
expCfgBaseAddress = (UINT32)
(IX_OSAL_MEM_MAP(IX_OSAL_IXP400_EXP_BUS_REGS_PHYS_BASE,
IX_OSAL_IXP400_EXP_REG_MAP_SIZE));
/* Assert that the mapping operation succeeded */
IX_OSAL_ASSERT(expCfgBaseAddress);
/* Set the address of the Feature register */
ixFeatureCtrlRegister =
(VUINT32 *) (expCfgBaseAddress + IX_FEATURE_CTRL_REG_OFFSET);
/* Mark the fact that the EXP_CONFIG space has already been mapped */
ixFeatureCtrlExpCfgRegionMapped = TRUE;
}
/**
* Function definition: ixFeatureCtrlSwConfigurationInit
* This function will only initialize software configuration once.
*/
PRIVATE void ixFeatureCtrlSwConfigurationInit(void)
{
UINT32 i;
if (FALSE == swConfigurationFlag)
{
for (i=0; i<IX_FEATURECTRL_SWCONFIG_MAX ; i++)
{
/* By default, all software configuration are enabled */
swConfiguration[i]= TRUE ;
}
/*Make sure this function only initializes swConfiguration[] once*/
swConfigurationFlag = TRUE ;
}
}
/**
* Function definition: ixFeatureCtrlRead
*/
IxFeatureCtrlReg
ixFeatureCtrlRead (void)
{
IxFeatureCtrlReg result;
#if CPU!=SIMSPARCSOLARIS
/* Read the feature control register */
IX_FEATURE_CTRL_READ(result);
return result;
#else
/* Return an invalid value for VxWorks simulation */
result = 0xFFFFFFFF;
return result;
#endif
}
/**
* Function definition: ixFeatureCtrlWrite
*/
void
ixFeatureCtrlWrite (IxFeatureCtrlReg expUnitReg)
{
#if CPU!=SIMSPARCSOLARIS
/* Write value to feature control register */
IX_FEATURE_CTRL_WRITE(expUnitReg);
#endif
}
/**
* Function definition: ixFeatureCtrlHwCapabilityRead
*/
IxFeatureCtrlReg
ixFeatureCtrlHwCapabilityRead (void)
{
IxFeatureCtrlReg currentReg, hwCapability;
/* Capture a copy of feature control register */
currentReg = ixFeatureCtrlRead();
/* Try to enable all hardware components.
* Only software disable hardware can be enabled again */
ixFeatureCtrlWrite(0);
/* Read feature control register to know the hardware capability. */
hwCapability = ixFeatureCtrlRead();
/* Restore initial feature control value */
ixFeatureCtrlWrite(currentReg);
/* return Hardware Capability */
return hwCapability;
}
/**
* Function definition: ixFeatureCtrlComponentCheck
*/
IX_STATUS
ixFeatureCtrlComponentCheck (IxFeatureCtrlComponentType componentType)
{
IxFeatureCtrlReg expUnitReg;
UINT32 mask = 0;
/* Lookup mask of component */
mask=componentMask[componentType];
/* Check if mask is available or not */
if(IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE == mask)
{
return IX_FEATURE_CTRL_COMPONENT_DISABLED;
}
if(IX_FEATURECTRL_COMPONENT_ALWAYS_AVAILABLE == mask)
{
return IX_FEATURE_CTRL_COMPONENT_ENABLED;
}
/* Read feature control register to know current hardware capability. */
expUnitReg = ixFeatureCtrlRead();
/* For example: To check for Hashing Coprocessor (bit-2)
* expUniteg = 0x0010
* ~expUnitReg = 0x1101
* componentType = 0x0100
* ~expUnitReg & componentType = 0x0100 (Not zero)
*/
/*
* Inverse the bit value because available component is 0 in value
*/
expUnitReg = ~expUnitReg ;
if (expUnitReg & mask)
{
return (IX_FEATURE_CTRL_COMPONENT_ENABLED);
}
else
{
return (IX_FEATURE_CTRL_COMPONENT_DISABLED);
}
}
/**
* Function definition: ixFeatureCtrlProductIdRead
*/
IxFeatureCtrlProductId
ixFeatureCtrlProductIdRead ()
{
#if CPU!=SIMSPARCSOLARIS
IxFeatureCtrlProductId pdId = 0 ;
/* Use ARM instruction to move register0 from coprocessor to ARM register */
#ifndef __wince
__asm("mrc p15, 0, %0, cr0, cr0, 0;" : "=r"(pdId) :);
#else
#ifndef IN_KERNEL
BOOL mode;
#endif
extern IxFeatureCtrlProductId AsmixFeatureCtrlProductIdRead();
#ifndef IN_KERNEL
mode = SetKMode(TRUE);
#endif
pdId = AsmixFeatureCtrlProductIdRead();
#ifndef IN_KERNEL
SetKMode(mode);
#endif
#endif
return (pdId);
#else
/* Return an invalid value for VxWorks simulation */
return 0xffffffff;
#endif
}
/**
* Function definition: ixFeatureCtrlDeviceRead
*/
IxFeatureCtrlDeviceId
ixFeatureCtrlDeviceRead ()
{
return ((ixFeatureCtrlProductIdRead() >> IX_FEATURE_CTRL_DEVICE_TYPE_OFFSET)
& IX_FEATURE_CTRL_DEVICE_TYPE_MASK);
} /* End function ixFeatureCtrlDeviceRead */
/**
* Function definition: ixFeatureCtrlSwConfigurationCheck
*/
IX_STATUS
ixFeatureCtrlSwConfigurationCheck (IxFeatureCtrlSwConfig swConfigType)
{
if (swConfigType >= IX_FEATURECTRL_SWCONFIG_MAX)
{
ixOsalLog(IX_OSAL_LOG_LVL_WARNING,
IX_OSAL_LOG_DEV_STDOUT,
"FeatureCtrl: Invalid software configuraiton input.\n",
0, 0, 0, 0, 0, 0);
return IX_FEATURE_CTRL_SWCONFIG_DISABLED;
}
/* The function will only initialize once. */
ixFeatureCtrlSwConfigurationInit();
/* Check and return software configuration */
return ((swConfiguration[(UINT32)swConfigType] == TRUE) ? IX_FEATURE_CTRL_SWCONFIG_ENABLED: IX_FEATURE_CTRL_SWCONFIG_DISABLED);
}
/**
* Function definition: ixFeatureCtrlSwConfigurationWrite
*/
void
ixFeatureCtrlSwConfigurationWrite (IxFeatureCtrlSwConfig swConfigType, BOOL enabled)
{
if (swConfigType >= IX_FEATURECTRL_SWCONFIG_MAX)
{
ixOsalLog(IX_OSAL_LOG_LVL_WARNING,
IX_OSAL_LOG_DEV_STDOUT,
"FeatureCtrl: Invalid software configuraiton input.\n",
0, 0, 0, 0, 0, 0);
return;
}
/* The function will only initialize once. */
ixFeatureCtrlSwConfigurationInit();
/* Write software configuration */
swConfiguration[(UINT32)swConfigType]=enabled ;
}
/**
* Function definition: ixFeatureCtrlIxp400SwVersionShow
*/
void
ixFeatureCtrlIxp400SwVersionShow (void)
{
printf ("\nIXP400 Software Release %s %s\n\n", IX_VERSION_ID, IX_VERSION_INTERNAL_ID);
}
/**
* Function definition: ixFeatureCtrlSoftwareBuildGet
*/
IxFeatureCtrlBuildDevice
ixFeatureCtrlSoftwareBuildGet (void)
{
#ifdef __ixp42X
return IX_FEATURE_CTRL_SW_BUILD_IXP42X;
#else
return IX_FEATURE_CTRL_SW_BUILD_IXP46X;
#endif
}

972
cpu/ixp/npe/IxNpeDl.c Normal file
View file

@ -0,0 +1,972 @@
/**
* @file IxNpeDl.c
*
* @author Intel Corporation
* @date 08 January 2002
*
* @brief This file contains the implementation of the public API for the
* IXP425 NPE Downloader component
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
/*
* Put the system defined include files required
*/
/*
* Put the user defined include files required
*/
#include "IxNpeDl.h"
#include "IxNpeDlImageMgr_p.h"
#include "IxNpeDlNpeMgr_p.h"
#include "IxNpeDlMacros_p.h"
#include "IxFeatureCtrl.h"
#include "IxOsal.h"
/*
* #defines used in this file
*/
#define IMAGEID_MAJOR_NUMBER_DEFAULT 0
#define IMAGEID_MINOR_NUMBER_DEFAULT 0
/*
* Typedefs whose scope is limited to this file.
*/
typedef struct
{
BOOL validImage;
IxNpeDlImageId imageId;
} IxNpeDlNpeState;
/* module statistics counters */
typedef struct
{
UINT32 attemptedDownloads;
UINT32 successfulDownloads;
UINT32 criticalFailDownloads;
} IxNpeDlStats;
/*
* Variable declarations global to this file only. Externs are followed
* by static variables.
*/
static IxNpeDlNpeState ixNpeDlNpeState[IX_NPEDL_NPEID_MAX] =
{
{FALSE, {IX_NPEDL_NPEID_MAX, 0, 0, 0}},
{FALSE, {IX_NPEDL_NPEID_MAX, 0, 0, 0}},
{FALSE, {IX_NPEDL_NPEID_MAX, 0, 0, 0}}
};
static IxNpeDlStats ixNpeDlStats;
/*
* Software guard to prevent NPE from being started multiple times.
*/
static BOOL ixNpeDlNpeStarted[IX_NPEDL_NPEID_MAX] ={FALSE, FALSE, FALSE} ;
/*
* static function prototypes.
*/
PRIVATE IX_STATUS
ixNpeDlNpeInitAndStartInternal (UINT32 *imageLibrary, UINT32 imageId);
/*
* Function definition: ixNpeDlMicrocodeImageLibraryOverride
*/
PUBLIC IX_STATUS
ixNpeDlMicrocodeImageLibraryOverride (UINT32 *clientImageLibrary)
{
IX_STATUS status = IX_SUCCESS;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlMicrocodeImageLibraryOverride\n");
if (clientImageLibrary == NULL)
{
status = IX_NPEDL_PARAM_ERR;
IX_NPEDL_ERROR_REPORT ("ixNpeDlMicrocodeImageLibraryOverride - "
"invalid parameter\n");
}
else
{
status = ixNpeDlImageMgrMicrocodeImageLibraryOverride (clientImageLibrary);
if (status != IX_SUCCESS)
{
status = IX_FAIL;
}
} /* end of if-else(clientImageLibrary) */
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlMicrocodeImageLibraryOverride : "
"status = %d\n", status);
return status;
}
/*
* Function definition: ixNpeDlImageDownload
*/
PUBLIC IX_STATUS
ixNpeDlImageDownload (IxNpeDlImageId *imageIdPtr,
BOOL verify)
{
UINT32 imageSize;
UINT32 *imageCodePtr = NULL;
IX_STATUS status;
IxNpeDlNpeId npeId = imageIdPtr->npeId;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlImageDownload\n");
ixNpeDlStats.attemptedDownloads++;
/* Check input parameters */
if ((npeId >= IX_NPEDL_NPEID_MAX) || (npeId < 0))
{
status = IX_NPEDL_PARAM_ERR;
IX_NPEDL_ERROR_REPORT ("ixNpeDlImageDownload - invalid parameter\n");
}
else
{
/* Ensure initialisation has been completed */
ixNpeDlNpeMgrInit();
/* If not IXP42X A0 stepping, proceed to check for existence of npe's */
if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
(ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
|| (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
{
if (npeId == IX_NPEDL_NPEID_NPEA)
{
if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) ==
IX_FEATURE_CTRL_COMPONENT_DISABLED)
{
IX_NPEDL_WARNING_REPORT("Warning: the NPE A component you specified does"
" not exist\n");
return IX_SUCCESS;
}
} /* end of if(npeId) */
else if (npeId == IX_NPEDL_NPEID_NPEB)
{
if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)==
IX_FEATURE_CTRL_COMPONENT_DISABLED)
{
IX_NPEDL_WARNING_REPORT("Warning: the NPE B component you specified"
" does not exist\n");
return IX_SUCCESS;
}
} /* end of elseif(npeId) */
else if (npeId == IX_NPEDL_NPEID_NPEC)
{
if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)==
IX_FEATURE_CTRL_COMPONENT_DISABLED)
{
IX_NPEDL_WARNING_REPORT("Warning: the NPE C component you specified"
" does not exist\n");
return IX_SUCCESS;
}
} /* end of elseif(npeId) */
} /* end of if(IX_FEATURE_CTRL_SILICON_TYPE_B0) */ /*End of Silicon Type Check*/
/* stop and reset the NPE */
if (IX_SUCCESS != ixNpeDlNpeStopAndReset (npeId))
{
IX_NPEDL_ERROR_REPORT ("Failed to stop and reset NPE\n");
return IX_FAIL;
}
/* Locate image */
status = ixNpeDlImageMgrImageLocate (imageIdPtr, &imageCodePtr,
&imageSize);
if (IX_SUCCESS == status)
{
/*
* If download was successful, store image Id in list of
* currently loaded images. If a critical error occured
* during download, record that the NPE has an invalid image
*/
status = ixNpeDlNpeMgrImageLoad (npeId, imageCodePtr,
verify);
if (IX_SUCCESS == status)
{
ixNpeDlNpeState[npeId].imageId = *imageIdPtr;
ixNpeDlNpeState[npeId].validImage = TRUE;
ixNpeDlStats.successfulDownloads++;
status = ixNpeDlNpeExecutionStart (npeId);
}
else if ((status == IX_NPEDL_CRITICAL_NPE_ERR) ||
(status == IX_NPEDL_CRITICAL_MICROCODE_ERR))
{
ixNpeDlNpeState[npeId].imageId = *imageIdPtr;
ixNpeDlNpeState[npeId].validImage = FALSE;
ixNpeDlStats.criticalFailDownloads++;
}
} /* end of if(IX_SUCCESS) */ /* condition: image located successfully in microcode image */
} /* end of if-else(npeId) */ /* condition: parameter checks ok */
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlImageDownload : status = %d\n", status);
return status;
}
/*
* Function definition: ixNpeDlAvailableImagesCountGet
*/
PUBLIC IX_STATUS
ixNpeDlAvailableImagesCountGet (UINT32 *numImagesPtr)
{
IX_STATUS status;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlAvailableImagesCountGet\n");
/* Check input parameters */
if (numImagesPtr == NULL)
{
status = IX_NPEDL_PARAM_ERR;
IX_NPEDL_ERROR_REPORT ("ixNpeDlAvailableImagesCountGet - "
"invalid parameter\n");
}
else
{
/*
* Use ImageMgr module to get no. of images listed in Image Library Header.
* If NULL is passed as imageListPtr parameter to following function,
* it will only fill number of images into numImagesPtr
*/
status = ixNpeDlImageMgrImageListExtract (NULL, numImagesPtr);
} /* end of if-else(numImagesPtr) */
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlAvailableImagesCountGet : "
"status = %d\n", status);
return status;
}
/*
* Function definition: ixNpeDlAvailableImagesListGet
*/
PUBLIC IX_STATUS
ixNpeDlAvailableImagesListGet (IxNpeDlImageId *imageIdListPtr,
UINT32 *listSizePtr)
{
IX_STATUS status;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlAvailableImagesListGet\n");
/* Check input parameters */
if ((imageIdListPtr == NULL) || (listSizePtr == NULL))
{
status = IX_NPEDL_PARAM_ERR;
IX_NPEDL_ERROR_REPORT ("ixNpeDlAvailableImagesListGet - "
"invalid parameter\n");
}
else
{
/* Call ImageMgr to get list of images listed in Image Library Header */
status = ixNpeDlImageMgrImageListExtract (imageIdListPtr,
listSizePtr);
} /* end of if-else(imageIdListPtr) */
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlAvailableImagesListGet : status = %d\n",
status);
return status;
}
/*
* Function definition: ixNpeDlLoadedImageGet
*/
PUBLIC IX_STATUS
ixNpeDlLoadedImageGet (IxNpeDlNpeId npeId,
IxNpeDlImageId *imageIdPtr)
{
IX_STATUS status = IX_SUCCESS;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlLoadedImageGet\n");
/* Check input parameters */
if ((npeId >= IX_NPEDL_NPEID_MAX) || (npeId < 0) || (imageIdPtr == NULL))
{
status = IX_NPEDL_PARAM_ERR;
IX_NPEDL_ERROR_REPORT ("ixNpeDlLoadedImageGet - invalid parameter\n");
}
else
{
/* If not IXP42X A0 stepping, proceed to check for existence of npe's */
if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
(ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
|| (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
{
if (npeId == IX_NPEDL_NPEID_NPEA &&
(ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) ==
IX_FEATURE_CTRL_COMPONENT_DISABLED))
{
IX_NPEDL_WARNING_REPORT("Warning: the NPE A component you specified does"
" not exist\n");
return IX_SUCCESS;
} /* end of if(npeId) */
if (npeId == IX_NPEDL_NPEID_NPEB &&
(ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB) ==
IX_FEATURE_CTRL_COMPONENT_DISABLED))
{
IX_NPEDL_WARNING_REPORT("Warning: the NPE B component you specified does"
" not exist\n");
return IX_SUCCESS;
} /* end of if(npeId) */
if (npeId == IX_NPEDL_NPEID_NPEC &&
(ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC) ==
IX_FEATURE_CTRL_COMPONENT_DISABLED))
{
IX_NPEDL_WARNING_REPORT("Warning: the NPE C component you specified does"
" not exist\n");
return IX_SUCCESS;
} /* end of if(npeId) */
} /* end of if not IXP42x-A0 silicon */
if (ixNpeDlNpeState[npeId].validImage)
{
/* use npeId to get imageId from list of currently loaded
images */
*imageIdPtr = ixNpeDlNpeState[npeId].imageId;
}
else
{
status = IX_FAIL;
} /* end of if-else(ixNpeDlNpeState) */
} /* end of if-else(npeId) */
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlLoadedImageGet : status = %d\n",
status);
return status;
}
/*
* Function definition: ixNpeDlLatestImageGet
*/
PUBLIC IX_STATUS
ixNpeDlLatestImageGet (
IxNpeDlNpeId npeId,
IxNpeDlFunctionalityId functionalityId,
IxNpeDlImageId *imageIdPtr)
{
IX_STATUS status;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlLatestImageGet\n");
/* Check input parameters */
if ((npeId >= IX_NPEDL_NPEID_MAX) ||
(npeId < 0) ||
(imageIdPtr == NULL))
{
status = IX_NPEDL_PARAM_ERR;
IX_NPEDL_ERROR_REPORT ("ixNpeDlLatestImageGet - "
"invalid parameter\n");
} /* end of if(npeId) */
else
{
/* If not IXP42X A0 stepping, proceed to check for existence of npe's */
if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
(ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
|| (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
{
if (npeId == IX_NPEDL_NPEID_NPEA &&
(ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) ==
IX_FEATURE_CTRL_COMPONENT_DISABLED))
{
IX_NPEDL_WARNING_REPORT("Warning: the NPE A component you specified does"
" not exist\n");
return IX_SUCCESS;
} /* end of if(npeId) */
if (npeId == IX_NPEDL_NPEID_NPEB &&
(ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB) ==
IX_FEATURE_CTRL_COMPONENT_DISABLED))
{
IX_NPEDL_WARNING_REPORT("Warning: the NPE B component you specified does"
" not exist\n");
return IX_SUCCESS;
} /* end of if(npeId) */
if (npeId == IX_NPEDL_NPEID_NPEC &&
(ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC) ==
IX_FEATURE_CTRL_COMPONENT_DISABLED))
{
IX_NPEDL_WARNING_REPORT("Warning: the NPE C component you specified does"
" not exist\n");
return IX_SUCCESS;
} /* end of if(npeId) */
} /* end of if not IXP42x-A0 silicon */
imageIdPtr->npeId = npeId;
imageIdPtr->functionalityId = functionalityId;
imageIdPtr->major = IMAGEID_MAJOR_NUMBER_DEFAULT;
imageIdPtr->minor = IMAGEID_MINOR_NUMBER_DEFAULT;
/* Call ImageMgr to get list of images listed in Image Library Header */
status = ixNpeDlImageMgrLatestImageExtract(imageIdPtr);
} /* end of if-else(npeId) */
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlLatestImageGet : status = %d\n",
status);
return status;
}
/*
* Function definition: ixNpeDlNpeStopAndReset
*/
PUBLIC IX_STATUS
ixNpeDlNpeStopAndReset (IxNpeDlNpeId npeId)
{
IX_STATUS status = IX_SUCCESS;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlNpeStopAndReset\n");
/* Ensure initialisation has been completed */
ixNpeDlNpeMgrInit();
/* If not IXP42X A0 stepping, proceed to check for existence of npe's */
if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
(ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
|| (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
{
/*
* Check whether NPE is present
*/
if (IX_NPEDL_NPEID_NPEA == npeId)
{
/* Check whether NPE A is present */
if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA)==
IX_FEATURE_CTRL_COMPONENT_DISABLED)
{
/* NPE A does not present */
IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeStopAndReset - Warning:NPEA does not present.\n");
return IX_SUCCESS;
}
} /* end of if(IX_NPEDL_NPEID_NPEA) */
else if (IX_NPEDL_NPEID_NPEB == npeId)
{
/* Check whether NPE B is present */
if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)==
IX_FEATURE_CTRL_COMPONENT_DISABLED)
{
/* NPE B does not present */
IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeStopAndReset - Warning:NPEB does not present.\n");
return IX_SUCCESS;
}
} /* end of elseif(IX_NPEDL_NPEID_NPEB) */
else if (IX_NPEDL_NPEID_NPEC == npeId)
{
/* Check whether NPE C is present */
if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)==
IX_FEATURE_CTRL_COMPONENT_DISABLED)
{
/* NPE C does not present */
IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeStopAndReset - Warning:NPEC does not present.\n");
return IX_SUCCESS;
}
} /* end of elseif(IX_NPEDL_NPEID_NPEC) */
else
{
/* Invalid NPE ID */
IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeStopAndReset - invalid Npe ID\n");
status = IX_NPEDL_PARAM_ERR;
} /* end of if-else(IX_NPEDL_NPEID_NPEC) */
} /* end of if not IXP42x-A0 Silicon */
if (status == IX_SUCCESS)
{
/* call NpeMgr function to stop the NPE */
status = ixNpeDlNpeMgrNpeStop (npeId);
if (status == IX_SUCCESS)
{
/* call NpeMgr function to reset the NPE */
status = ixNpeDlNpeMgrNpeReset (npeId);
}
} /* end of if(status) */
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlNpeStopAndReset : status = %d\n", status);
if (IX_SUCCESS == status)
{
/* Indicate NPE has been stopped */
ixNpeDlNpeStarted[npeId] = FALSE ;
}
return status;
}
/*
* Function definition: ixNpeDlNpeExecutionStart
*/
PUBLIC IX_STATUS
ixNpeDlNpeExecutionStart (IxNpeDlNpeId npeId)
{
IX_STATUS status = IX_SUCCESS;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlNpeExecutionStart\n");
/* If not IXP42X A0 stepping, proceed to check for existence of npe's */
if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
(ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
|| (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
{
/*
* Check whether NPE is present
*/
if (IX_NPEDL_NPEID_NPEA == npeId)
{
/* Check whether NPE A is present */
if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA)==
IX_FEATURE_CTRL_COMPONENT_DISABLED)
{
/* NPE A does not present */
IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStart - Warning:NPEA does not present.\n");
return IX_SUCCESS;
}
} /* end of if(IX_NPEDL_NPEID_NPEA) */
else if (IX_NPEDL_NPEID_NPEB == npeId)
{
/* Check whether NPE B is present */
if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)==
IX_FEATURE_CTRL_COMPONENT_DISABLED)
{
/* NPE B does not present */
IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStart - Warning:NPEB does not present.\n");
return IX_SUCCESS;
}
} /* end of elseif(IX_NPEDL_NPEID_NPEB) */
else if (IX_NPEDL_NPEID_NPEC == npeId)
{
/* Check whether NPE C is present */
if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)==
IX_FEATURE_CTRL_COMPONENT_DISABLED)
{
/* NPE C does not present */
IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStart - Warning:NPEC does not present.\n");
return IX_SUCCESS;
}
} /* end of elseif(IX_NPEDL_NPEID_NPEC) */
else
{
/* Invalid NPE ID */
IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeExecutionStart - invalid Npe ID\n");
return IX_NPEDL_PARAM_ERR;
} /* end of if-else(IX_NPEDL_NPEID_NPEC) */
} /* end of if not IXP42x-A0 Silicon */
if (TRUE == ixNpeDlNpeStarted[npeId])
{
/* NPE has been started. */
return IX_SUCCESS ;
}
/* Ensure initialisation has been completed */
ixNpeDlNpeMgrInit();
/* call NpeMgr function to start the NPE */
status = ixNpeDlNpeMgrNpeStart (npeId);
if (IX_SUCCESS == status)
{
/* Indicate NPE has started */
ixNpeDlNpeStarted[npeId] = TRUE ;
}
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlNpeExecutionStart : status = %d\n",
status);
return status;
}
/*
* Function definition: ixNpeDlNpeExecutionStop
*/
PUBLIC IX_STATUS
ixNpeDlNpeExecutionStop (IxNpeDlNpeId npeId)
{
IX_STATUS status = IX_SUCCESS;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlNpeExecutionStop\n");
/* Ensure initialisation has been completed */
ixNpeDlNpeMgrInit();
/* If not IXP42X A0 stepping, proceed to check for existence of npe's */
if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
(ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
|| (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
{
/*
* Check whether NPE is present
*/
if (IX_NPEDL_NPEID_NPEA == npeId)
{
/* Check whether NPE A is present */
if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA)==
IX_FEATURE_CTRL_COMPONENT_DISABLED)
{
/* NPE A does not present */
IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStop - Warning:NPEA does not present.\n");
return IX_SUCCESS;
}
} /* end of if(IX_NPEDL_NPEID_NPEA) */
else if (IX_NPEDL_NPEID_NPEB == npeId)
{
/* Check whether NPE B is present */
if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)==
IX_FEATURE_CTRL_COMPONENT_DISABLED)
{
/* NPE B does not present */
IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStop - Warning:NPEB does not present.\n");
return IX_SUCCESS;
}
} /* end of elseif(IX_NPEDL_NPEID_NPEB) */
else if (IX_NPEDL_NPEID_NPEC == npeId)
{
/* Check whether NPE C is present */
if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)==
IX_FEATURE_CTRL_COMPONENT_DISABLED)
{
/* NPE C does not present */
IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStop - Warning:NPEC does not present.\n");
return IX_SUCCESS;
}
} /* end of elseif(IX_NPEDL_NPEID_NPEC) */
else
{
/* Invalid NPE ID */
IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeExecutionStop - invalid Npe ID\n");
status = IX_NPEDL_PARAM_ERR;
} /* end of if-else(IX_NPEDL_NPEID_NPEC) */
} /* end of if not IXP42X-AO Silicon */
if (status == IX_SUCCESS)
{
/* call NpeMgr function to stop the NPE */
status = ixNpeDlNpeMgrNpeStop (npeId);
}
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlNpeExecutionStop : status = %d\n",
status);
if (IX_SUCCESS == status)
{
/* Indicate NPE has been stopped */
ixNpeDlNpeStarted[npeId] = FALSE ;
}
return status;
}
/*
* Function definition: ixNpeDlUnload
*/
PUBLIC IX_STATUS
ixNpeDlUnload (void)
{
IX_STATUS status;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlUnload\n");
status = ixNpeDlNpeMgrUninit();
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlUnload : status = %d\n",
status);
return status;
}
/*
* Function definition: ixNpeDlStatsShow
*/
PUBLIC void
ixNpeDlStatsShow (void)
{
ixOsalLog (IX_OSAL_LOG_LVL_USER,
IX_OSAL_LOG_DEV_STDOUT,
"\nixNpeDlStatsShow:\n"
"\tDownloads Attempted by user: %u\n"
"\tSuccessful Downloads: %u\n"
"\tFailed Downloads (due to Critical Error): %u\n\n",
ixNpeDlStats.attemptedDownloads,
ixNpeDlStats.successfulDownloads,
ixNpeDlStats.criticalFailDownloads,
0,0,0);
ixNpeDlImageMgrStatsShow ();
ixNpeDlNpeMgrStatsShow ();
}
/*
* Function definition: ixNpeDlStatsReset
*/
PUBLIC void
ixNpeDlStatsReset (void)
{
ixNpeDlStats.attemptedDownloads = 0;
ixNpeDlStats.successfulDownloads = 0;
ixNpeDlStats.criticalFailDownloads = 0;
ixNpeDlImageMgrStatsReset ();
ixNpeDlNpeMgrStatsReset ();
}
/*
* Function definition: ixNpeDlNpeInitAndStartInternal
*/
PRIVATE IX_STATUS
ixNpeDlNpeInitAndStartInternal (UINT32 *imageLibrary,
UINT32 imageId)
{
UINT32 imageSize;
UINT32 *imageCodePtr = NULL;
IX_STATUS status;
IxNpeDlNpeId npeId = IX_NPEDL_NPEID_FROM_IMAGEID_GET(imageId);
IxFeatureCtrlDeviceId deviceId = IX_NPEDL_DEVICEID_FROM_IMAGEID_GET(imageId);
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlNpeInitAndStartInternal\n");
ixNpeDlStats.attemptedDownloads++;
/* Check input parameter device correctness */
if ((deviceId >= IX_FEATURE_CTRL_DEVICE_TYPE_MAX) ||
(deviceId < IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X))
{
status = IX_NPEDL_PARAM_ERR;
IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeInitAndStartInternal - "
"invalid parameter\n");
} /* End valid device id checking */
/* Check input parameters */
else if ((npeId >= IX_NPEDL_NPEID_MAX) || (npeId < 0))
{
status = IX_NPEDL_PARAM_ERR;
IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeInitAndStartInternal - "
"invalid parameter\n");
}
else
{
/* Ensure initialisation has been completed */
ixNpeDlNpeMgrInit();
/* Checking if image being loaded is meant for device that is running.
* Image is forward compatible. i.e Image built for IXP42X should run
* on IXP46X but not vice versa.*/
if (deviceId > (ixFeatureCtrlDeviceRead() & IX_FEATURE_CTRL_DEVICE_TYPE_MASK))
{
IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeInitAndStartInternal - "
"Device type mismatch. NPE Image not "
"meant for device in use \n");
return IX_NPEDL_DEVICE_ERR;
}/* if statement - matching image device and current device */
/* If not IXP42X A0 stepping, proceed to check for existence of npe's */
if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
(ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
|| (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
{
if (npeId == IX_NPEDL_NPEID_NPEA)
{
if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) ==
IX_FEATURE_CTRL_COMPONENT_DISABLED)
{
IX_NPEDL_WARNING_REPORT("Warning: the NPE A component you specified does"
" not exist\n");
return IX_SUCCESS;
}
} /* end of if(npeId) */
else if (npeId == IX_NPEDL_NPEID_NPEB)
{
if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)==
IX_FEATURE_CTRL_COMPONENT_DISABLED)
{
IX_NPEDL_WARNING_REPORT("Warning: the NPE B component you specified"
" does not exist\n");
return IX_SUCCESS;
}
} /* end of elseif(npeId) */
else if (npeId == IX_NPEDL_NPEID_NPEC)
{
if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)==
IX_FEATURE_CTRL_COMPONENT_DISABLED)
{
IX_NPEDL_WARNING_REPORT("Warning: the NPE C component you specified"
" does not exist\n");
return IX_SUCCESS;
}
} /* end of elseif(npeId) */
} /* end of if not IXP42X-A0 Silicon */
/* stop and reset the NPE */
status = ixNpeDlNpeStopAndReset (npeId);
if (IX_SUCCESS != status)
{
IX_NPEDL_ERROR_REPORT ("Failed to stop and reset NPE\n");
return status;
}
/* Locate image */
status = ixNpeDlImageMgrImageFind (imageLibrary, imageId,
&imageCodePtr, &imageSize);
if (IX_SUCCESS == status)
{
/*
* If download was successful, store image Id in list of
* currently loaded images. If a critical error occured
* during download, record that the NPE has an invalid image
*/
status = ixNpeDlNpeMgrImageLoad (npeId, imageCodePtr, TRUE);
if (IX_SUCCESS == status)
{
ixNpeDlNpeState[npeId].validImage = TRUE;
ixNpeDlStats.successfulDownloads++;
status = ixNpeDlNpeExecutionStart (npeId);
}
else if ((status == IX_NPEDL_CRITICAL_NPE_ERR) ||
(status == IX_NPEDL_CRITICAL_MICROCODE_ERR))
{
ixNpeDlNpeState[npeId].validImage = FALSE;
ixNpeDlStats.criticalFailDownloads++;
}
/* NOTE - The following section of code is here to support
* a deprecated function ixNpeDlLoadedImageGet(). When that
* function is removed from the API, this code should be revised.
*/
ixNpeDlNpeState[npeId].imageId.npeId = npeId;
ixNpeDlNpeState[npeId].imageId.functionalityId =
IX_NPEDL_FUNCTIONID_FROM_IMAGEID_GET(imageId);
ixNpeDlNpeState[npeId].imageId.major =
IX_NPEDL_MAJOR_FROM_IMAGEID_GET(imageId);
ixNpeDlNpeState[npeId].imageId.minor =
IX_NPEDL_MINOR_FROM_IMAGEID_GET(imageId);
} /* end of if(IX_SUCCESS) */ /* condition: image located successfully in microcode image */
} /* end of if-else(npeId-deviceId) */ /* condition: parameter checks ok */
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlNpeInitAndStartInternal : "
"status = %d\n", status);
return status;
}
/*
* Function definition: ixNpeDlCustomImageNpeInitAndStart
*/
PUBLIC IX_STATUS
ixNpeDlCustomImageNpeInitAndStart (UINT32 *imageLibrary,
UINT32 imageId)
{
IX_STATUS status;
if (imageLibrary == NULL)
{
status = IX_NPEDL_PARAM_ERR;
IX_NPEDL_ERROR_REPORT ("ixNpeDlCustomImageNpeInitAndStart "
"- invalid parameter\n");
}
else
{
status = ixNpeDlNpeInitAndStartInternal (imageLibrary, imageId);
} /* end of if-else(imageLibrary) */
return status;
}
/*
* Function definition: ixNpeDlNpeInitAndStart
*/
PUBLIC IX_STATUS
ixNpeDlNpeInitAndStart (UINT32 imageId)
{
return ixNpeDlNpeInitAndStartInternal (NULL, imageId);
}
/*
* Function definition: ixNpeDlLoadedImageFunctionalityGet
*/
PUBLIC IX_STATUS
ixNpeDlLoadedImageFunctionalityGet (IxNpeDlNpeId npeId,
UINT8 *functionalityId)
{
/* Check input parameters */
if ((npeId >= IX_NPEDL_NPEID_MAX) || (npeId < 0))
{
IX_NPEDL_ERROR_REPORT ("ixNpeDlLoadedImageFunctionalityGet "
"- invalid parameter\n");
return IX_NPEDL_PARAM_ERR;
}
if (functionalityId == NULL)
{
IX_NPEDL_ERROR_REPORT ("ixNpeDlLoadedImageFunctionalityGet "
"- invalid parameter\n");
return IX_NPEDL_PARAM_ERR;
}
if (ixNpeDlNpeState[npeId].validImage)
{
*functionalityId = ixNpeDlNpeState[npeId].imageId.functionalityId;
return IX_SUCCESS;
}
else
{
return IX_FAIL;
}
}

View file

@ -0,0 +1,675 @@
/**
* @file IxNpeDlImageMgr.c
*
* @author Intel Corporation
* @date 09 January 2002
*
* @brief This file contains the implementation of the private API for the
* IXP425 NPE Downloader ImageMgr module
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
/*
* Put the system defined include files required.
*/
#include "IxOsal.h"
/*
* Put the user defined include files required.
*/
#include "IxNpeDlImageMgr_p.h"
#include "IxNpeDlMacros_p.h"
/*
* define the flag which toggles the firmare inclusion
*/
#define IX_NPE_MICROCODE_FIRMWARE_INCLUDED 1
#include "IxNpeMicrocode.h"
/*
* Indicates the start of an NPE Image, in new NPE Image Library format.
* 2 consecutive occurances indicates the end of the NPE Image Library
*/
#define NPE_IMAGE_MARKER 0xfeedf00d
/*
* Typedefs whose scope is limited to this file.
*/
/*
* FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
* TO BE DEPRECATED IN A FUTURE RELEASE
*/
typedef struct
{
UINT32 size;
UINT32 offset;
UINT32 id;
} IxNpeDlImageMgrImageEntry;
/*
* FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
* TO BE DEPRECATED IN A FUTURE RELEASE
*/
typedef union
{
IxNpeDlImageMgrImageEntry image;
UINT32 eohMarker;
} IxNpeDlImageMgrHeaderEntry;
/*
* FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
* TO BE DEPRECATED IN A FUTURE RELEASE
*/
typedef struct
{
UINT32 signature;
/* 1st entry in the header (there may be more than one) */
IxNpeDlImageMgrHeaderEntry entry[1];
} IxNpeDlImageMgrImageLibraryHeader;
/*
* NPE Image Header definition, used in new NPE Image Library format
*/
typedef struct
{
UINT32 marker;
UINT32 id;
UINT32 size;
} IxNpeDlImageMgrImageHeader;
/* module statistics counters */
typedef struct
{
UINT32 invalidSignature;
UINT32 imageIdListOverflow;
UINT32 imageIdNotFound;
} IxNpeDlImageMgrStats;
/*
* Variable declarations global to this file only. Externs are followed by
* static variables.
*/
static IxNpeDlImageMgrStats ixNpeDlImageMgrStats;
/* default image */
#ifdef IX_NPEDL_READ_MICROCODE_FROM_FILE
static UINT32 *IxNpeMicroCodeImageLibrary = NULL; /* Gets set to proper value at runtime */
#else
static UINT32 *IxNpeMicroCodeImageLibrary = (UINT32 *)IxNpeMicrocode_array;
#endif
/*
* static function prototypes.
*/
PRIVATE BOOL
ixNpeDlImageMgrSignatureCheck (UINT32 *microCodeImageLibrary);
PRIVATE void
ixNpeDlImageMgrImageIdFormat (UINT32 rawImageId, IxNpeDlImageId *imageId);
PRIVATE BOOL
ixNpeDlImageMgrImageIdCompare (IxNpeDlImageId *imageIdA,
IxNpeDlImageId *imageIdB);
PRIVATE BOOL
ixNpeDlImageMgrNpeFunctionIdCompare (IxNpeDlImageId *imageIdA,
IxNpeDlImageId *imageIdB);
PRIVATE IX_STATUS
ixNpeDlImageMgrImageFind_legacy (UINT32 *imageLibrary,
UINT32 imageId,
UINT32 **imagePtr,
UINT32 *imageSize);
/*
* Function definition: ixNpeDlImageMgrMicrocodeImageLibraryOverride
*
* FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
* AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
*/
IX_STATUS
ixNpeDlImageMgrMicrocodeImageLibraryOverride (
UINT32 *clientImageLibrary)
{
IX_STATUS status = IX_SUCCESS;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlImageMgrMicrocodeImageLibraryOverride\n");
if (ixNpeDlImageMgrSignatureCheck (clientImageLibrary))
{
IxNpeMicroCodeImageLibrary = clientImageLibrary;
}
else
{
IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrMicrocodeImageLibraryOverride: "
"Client-supplied image has invalid signature\n");
status = IX_FAIL;
}
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlImageMgrMicrocodeImageLibraryOverride: status = %d\n",
status);
return status;
}
/*
* Function definition: ixNpeDlImageMgrImageListExtract
*
* FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
* AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
*/
IX_STATUS
ixNpeDlImageMgrImageListExtract (
IxNpeDlImageId *imageListPtr,
UINT32 *numImages)
{
UINT32 rawImageId;
IxNpeDlImageId formattedImageId;
IX_STATUS status = IX_SUCCESS;
UINT32 imageCount = 0;
IxNpeDlImageMgrImageLibraryHeader *header;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlImageMgrImageListExtract\n");
header = (IxNpeDlImageMgrImageLibraryHeader *) IxNpeMicroCodeImageLibrary;
if (ixNpeDlImageMgrSignatureCheck (IxNpeMicroCodeImageLibrary))
{
/* for each image entry in the image header ... */
while (header->entry[imageCount].eohMarker !=
IX_NPEDL_IMAGEMGR_END_OF_HEADER)
{
/*
* if the image list container from calling function has capacity,
* add the image id to the list
*/
if ((imageListPtr != NULL) && (imageCount < *numImages))
{
rawImageId = header->entry[imageCount].image.id;
ixNpeDlImageMgrImageIdFormat (rawImageId, &formattedImageId);
imageListPtr[imageCount] = formattedImageId;
}
/* imageCount reflects no. of image entries in image library header */
imageCount++;
}
/*
* if image list container from calling function was too small to
* contain all image ids in the header, set return status to FAIL
*/
if ((imageListPtr != NULL) && (imageCount > *numImages))
{
status = IX_FAIL;
IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageListExtract: "
"number of Ids found exceeds list capacity\n");
ixNpeDlImageMgrStats.imageIdListOverflow++;
}
/* return number of image ids found in image library header */
*numImages = imageCount;
}
else
{
status = IX_FAIL;
IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageListExtract: "
"invalid signature in image\n");
}
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlImageMgrImageListExtract: status = %d\n",
status);
return status;
}
/*
* Function definition: ixNpeDlImageMgrImageLocate
*
* FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
* AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
*/
IX_STATUS
ixNpeDlImageMgrImageLocate (
IxNpeDlImageId *imageId,
UINT32 **imagePtr,
UINT32 *imageSize)
{
UINT32 imageOffset;
UINT32 rawImageId;
IxNpeDlImageId formattedImageId;
/* used to index image entries in image library header */
UINT32 imageCount = 0;
IX_STATUS status = IX_FAIL;
IxNpeDlImageMgrImageLibraryHeader *header;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlImageMgrImageLocate\n");
header = (IxNpeDlImageMgrImageLibraryHeader *) IxNpeMicroCodeImageLibrary;
if (ixNpeDlImageMgrSignatureCheck (IxNpeMicroCodeImageLibrary))
{
/* for each image entry in the image library header ... */
while (header->entry[imageCount].eohMarker !=
IX_NPEDL_IMAGEMGR_END_OF_HEADER)
{
rawImageId = header->entry[imageCount].image.id;
ixNpeDlImageMgrImageIdFormat (rawImageId, &formattedImageId);
/* if a match for imageId is found in the image library header... */
if (ixNpeDlImageMgrImageIdCompare (imageId, &formattedImageId))
{
/*
* get pointer to the image in the image library using offset from
* 1st word in image library
*/
imageOffset = header->entry[imageCount].image.offset;
*imagePtr = &IxNpeMicroCodeImageLibrary[imageOffset];
/* get the image size */
*imageSize = header->entry[imageCount].image.size;
status = IX_SUCCESS;
break;
}
imageCount++;
}
if (status != IX_SUCCESS)
{
IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageLocate: "
"imageId not found in image library header\n");
ixNpeDlImageMgrStats.imageIdNotFound++;
}
}
else
{
IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageLocate: "
"invalid signature in image library\n");
}
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlImageMgrImageLocate: status = %d\n", status);
return status;
}
/*
* Function definition: ixNpeDlImageMgrLatestImageExtract
*
* FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
* AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
*/
IX_STATUS
ixNpeDlImageMgrLatestImageExtract (IxNpeDlImageId *imageId)
{
UINT32 imageCount = 0;
UINT32 rawImageId;
IxNpeDlImageId formattedImageId;
IX_STATUS status = IX_FAIL;
IxNpeDlImageMgrImageLibraryHeader *header;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlImageMgrLatestImageExtract\n");
header = (IxNpeDlImageMgrImageLibraryHeader *) IxNpeMicroCodeImageLibrary;
if (ixNpeDlImageMgrSignatureCheck (IxNpeMicroCodeImageLibrary))
{
/* for each image entry in the image library header ... */
while (header->entry[imageCount].eohMarker !=
IX_NPEDL_IMAGEMGR_END_OF_HEADER)
{
rawImageId = header->entry[imageCount].image.id;
ixNpeDlImageMgrImageIdFormat (rawImageId, &formattedImageId);
/*
* if a match for the npe Id and functionality Id of the imageId is
* found in the image library header...
*/
if(ixNpeDlImageMgrNpeFunctionIdCompare(imageId, &formattedImageId))
{
if(imageId->major <= formattedImageId.major)
{
if(imageId->minor < formattedImageId.minor)
{
imageId->minor = formattedImageId.minor;
}
imageId->major = formattedImageId.major;
}
status = IX_SUCCESS;
}
imageCount++;
}
if (status != IX_SUCCESS)
{
IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrLatestImageExtract: "
"imageId not found in image library header\n");
ixNpeDlImageMgrStats.imageIdNotFound++;
}
}
else
{
IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrLatestImageGet: "
"invalid signature in image library\n");
}
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlImageMgrLatestImageGet: status = %d\n", status);
return status;
}
/*
* Function definition: ixNpeDlImageMgrSignatureCheck
*
* FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
* AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
*/
PRIVATE BOOL
ixNpeDlImageMgrSignatureCheck (UINT32 *microCodeImageLibrary)
{
IxNpeDlImageMgrImageLibraryHeader *header =
(IxNpeDlImageMgrImageLibraryHeader *) microCodeImageLibrary;
BOOL result = TRUE;
if (header->signature != IX_NPEDL_IMAGEMGR_SIGNATURE)
{
result = FALSE;
ixNpeDlImageMgrStats.invalidSignature++;
}
return result;
}
/*
* Function definition: ixNpeDlImageMgrImageIdFormat
*
* FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
* AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
*/
PRIVATE void
ixNpeDlImageMgrImageIdFormat (
UINT32 rawImageId,
IxNpeDlImageId *imageId)
{
imageId->npeId = (rawImageId >>
IX_NPEDL_IMAGEID_NPEID_OFFSET) &
IX_NPEDL_NPEIMAGE_FIELD_MASK;
imageId->functionalityId = (rawImageId >>
IX_NPEDL_IMAGEID_FUNCTIONID_OFFSET) &
IX_NPEDL_NPEIMAGE_FIELD_MASK;
imageId->major = (rawImageId >>
IX_NPEDL_IMAGEID_MAJOR_OFFSET) &
IX_NPEDL_NPEIMAGE_FIELD_MASK;
imageId->minor = (rawImageId >>
IX_NPEDL_IMAGEID_MINOR_OFFSET) &
IX_NPEDL_NPEIMAGE_FIELD_MASK;
}
/*
* Function definition: ixNpeDlImageMgrImageIdCompare
*
* FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
* AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
*/
PRIVATE BOOL
ixNpeDlImageMgrImageIdCompare (
IxNpeDlImageId *imageIdA,
IxNpeDlImageId *imageIdB)
{
if ((imageIdA->npeId == imageIdB->npeId) &&
(imageIdA->functionalityId == imageIdB->functionalityId) &&
(imageIdA->major == imageIdB->major) &&
(imageIdA->minor == imageIdB->minor))
{
return TRUE;
}
else
{
return FALSE;
}
}
/*
* Function definition: ixNpeDlImageMgrNpeFunctionIdCompare
*
* FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
* AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
*/
PRIVATE BOOL
ixNpeDlImageMgrNpeFunctionIdCompare (
IxNpeDlImageId *imageIdA,
IxNpeDlImageId *imageIdB)
{
if ((imageIdA->npeId == imageIdB->npeId) &&
(imageIdA->functionalityId == imageIdB->functionalityId))
{
return TRUE;
}
else
{
return FALSE;
}
}
/*
* Function definition: ixNpeDlImageMgrStatsShow
*/
void
ixNpeDlImageMgrStatsShow (void)
{
ixOsalLog (IX_OSAL_LOG_LVL_USER,
IX_OSAL_LOG_DEV_STDOUT,
"\nixNpeDlImageMgrStatsShow:\n"
"\tInvalid Image Signatures: %u\n"
"\tImage Id List capacity too small: %u\n"
"\tImage Id not found: %u\n\n",
ixNpeDlImageMgrStats.invalidSignature,
ixNpeDlImageMgrStats.imageIdListOverflow,
ixNpeDlImageMgrStats.imageIdNotFound,
0,0,0);
}
/*
* Function definition: ixNpeDlImageMgrStatsReset
*/
void
ixNpeDlImageMgrStatsReset (void)
{
ixNpeDlImageMgrStats.invalidSignature = 0;
ixNpeDlImageMgrStats.imageIdListOverflow = 0;
ixNpeDlImageMgrStats.imageIdNotFound = 0;
}
/*
* Function definition: ixNpeDlImageMgrImageFind_legacy
*
* FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
* AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
*/
PRIVATE IX_STATUS
ixNpeDlImageMgrImageFind_legacy (
UINT32 *imageLibrary,
UINT32 imageId,
UINT32 **imagePtr,
UINT32 *imageSize)
{
UINT32 imageOffset;
/* used to index image entries in image library header */
UINT32 imageCount = 0;
IX_STATUS status = IX_FAIL;
IxNpeDlImageMgrImageLibraryHeader *header;
BOOL imageFound = FALSE;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlImageMgrImageFind\n");
/* If user didn't specify a library to use, use the default
* one from IxNpeMicrocode.h
*/
if (imageLibrary == NULL)
{
imageLibrary = IxNpeMicroCodeImageLibrary;
}
if (ixNpeDlImageMgrSignatureCheck (imageLibrary))
{
header = (IxNpeDlImageMgrImageLibraryHeader *) imageLibrary;
/* for each image entry in the image library header ... */
while ((header->entry[imageCount].eohMarker !=
IX_NPEDL_IMAGEMGR_END_OF_HEADER) && !(imageFound))
{
/* if a match for imageId is found in the image library header... */
if (imageId == header->entry[imageCount].image.id)
{
/*
* get pointer to the image in the image library using offset from
* 1st word in image library
*/
imageOffset = header->entry[imageCount].image.offset;
*imagePtr = &imageLibrary[imageOffset];
/* get the image size */
*imageSize = header->entry[imageCount].image.size;
status = IX_SUCCESS;
imageFound = TRUE;
}
imageCount++;
}
if (status != IX_SUCCESS)
{
IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageFind: "
"imageId not found in image library header\n");
ixNpeDlImageMgrStats.imageIdNotFound++;
}
}
else
{
IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageFind: "
"invalid signature in image library\n");
}
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlImageMgrImageFind: status = %d\n", status);
return status;
}
/*
* Function definition: ixNpeDlImageMgrImageFind
*/
IX_STATUS
ixNpeDlImageMgrImageFind (
UINT32 *imageLibrary,
UINT32 imageId,
UINT32 **imagePtr,
UINT32 *imageSize)
{
IxNpeDlImageMgrImageHeader *image;
UINT32 offset = 0;
/* If user didn't specify a library to use, use the default
* one from IxNpeMicrocode.h
*/
if (imageLibrary == NULL)
{
#ifdef IX_NPEDL_READ_MICROCODE_FROM_FILE
if (ixNpeMicrocode_binaryArray == NULL)
{
printk (KERN_ERR "ixp400.o: ERROR, no Microcode found in memory\n");
return IX_FAIL;
}
else
{
imageLibrary = ixNpeMicrocode_binaryArray;
}
#else
imageLibrary = IxNpeMicroCodeImageLibrary;
#endif /* IX_NPEDL_READ_MICROCODE_FROM_FILE */
}
/* For backward's compatibility with previous image format */
if (ixNpeDlImageMgrSignatureCheck(imageLibrary))
{
return ixNpeDlImageMgrImageFind_legacy(imageLibrary,
imageId,
imagePtr,
imageSize);
}
while (*(imageLibrary+offset) == NPE_IMAGE_MARKER)
{
image = (IxNpeDlImageMgrImageHeader *)(imageLibrary+offset);
offset += sizeof(IxNpeDlImageMgrImageHeader)/sizeof(UINT32);
if (image->id == imageId)
{
*imagePtr = imageLibrary + offset;
*imageSize = image->size;
return IX_SUCCESS;
}
/* 2 consecutive NPE_IMAGE_MARKER's indicates end of library */
else if (image->id == NPE_IMAGE_MARKER)
{
IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageFind: "
"imageId not found in image library header\n");
ixNpeDlImageMgrStats.imageIdNotFound++;
/* reached end of library, image not found */
return IX_FAIL;
}
offset += image->size;
}
/* If we get here, our image library may be corrupted */
IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageFind: "
"image library format may be invalid or corrupted\n");
return IX_FAIL;
}

936
cpu/ixp/npe/IxNpeDlNpeMgr.c Normal file
View file

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

View file

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

582
cpu/ixp/npe/IxNpeMh.c Normal file
View file

@ -0,0 +1,582 @@
/**
* @file IxNpeMh.c
*
* @author Intel Corporation
* @date 18 Jan 2002
*
* @brief This file contains the implementation of the public API for the
* IXP425 NPE Message Handler component.
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
/*
* Put the system defined include files required.
*/
/*
* Put the user defined include files required.
*/
#include "IxOsal.h"
#include "IxNpeMhMacros_p.h"
#include "IxNpeMh.h"
#include "IxNpeMhConfig_p.h"
#include "IxNpeMhReceive_p.h"
#include "IxNpeMhSend_p.h"
#include "IxNpeMhSolicitedCbMgr_p.h"
#include "IxNpeMhUnsolicitedCbMgr_p.h"
/*
* #defines and macros used in this file.
*/
/*
* Typedefs whose scope is limited to this file.
*/
/*
* Variable declarations global to this file only. Externs are followed by
* static variables.
*/
PRIVATE BOOL ixNpeMhInitialized = FALSE;
/*
* Extern function prototypes.
*/
/*
* Static function prototypes.
*/
/*
* Function definition: ixNpeMhInitialize
*/
PUBLIC IX_STATUS ixNpeMhInitialize (
IxNpeMhNpeInterrupts npeInterrupts)
{
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhInitialize\n");
/* check the npeInterrupts parameter */
if ((npeInterrupts != IX_NPEMH_NPEINTERRUPTS_NO) &&
(npeInterrupts != IX_NPEMH_NPEINTERRUPTS_YES))
{
IX_NPEMH_ERROR_REPORT ("Illegal npeInterrupts parameter value\n");
return IX_FAIL;
}
/* parameters are ok ... */
/* initialize the Receive module */
ixNpeMhReceiveInitialize ();
/* initialize the Solicited Callback Manager module */
ixNpeMhSolicitedCbMgrInitialize ();
/* initialize the Unsolicited Callback Manager module */
ixNpeMhUnsolicitedCbMgrInitialize ();
/* initialize the Configuration module
*
* NOTE: This module was originally configured before the
* others, but the sequence was changed so that interrupts
* would only be enabled after the handler functions were
* set up. The above modules need to be initialised to
* handle the NPE interrupts. See SCR #2231.
*/
ixNpeMhConfigInitialize (npeInterrupts);
ixNpeMhInitialized = TRUE;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhInitialize\n");
return IX_SUCCESS;
}
/*
* Function definition: ixNpeMhUnload
*/
PUBLIC IX_STATUS ixNpeMhUnload (void)
{
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhUnload\n");
if (!ixNpeMhInitialized)
{
return IX_FAIL;
}
/* Uninitialize the Configuration module */
ixNpeMhConfigUninit ();
ixNpeMhInitialized = FALSE;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhUnload\n");
return IX_SUCCESS;
}
/*
* Function definition: ixNpeMhUnsolicitedCallbackRegister
*/
PUBLIC IX_STATUS ixNpeMhUnsolicitedCallbackRegister (
IxNpeMhNpeId npeId,
IxNpeMhMessageId messageId,
IxNpeMhCallback unsolicitedCallback)
{
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhUnsolicitedCallbackRegister\n");
/* check that we are initialized */
if (!ixNpeMhInitialized)
{
IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n");
return IX_FAIL;
}
/* check the npeId parameter */
if (!ixNpeMhConfigNpeIdIsValid (npeId))
{
IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n");
return IX_FAIL;
}
/* check the messageId parameter */
if ((messageId < IX_NPEMH_MIN_MESSAGE_ID)
|| (messageId > IX_NPEMH_MAX_MESSAGE_ID))
{
IX_NPEMH_ERROR_REPORT ("Message ID is out of range\n");
return IX_FAIL;
}
/* the unsolicitedCallback parameter is allowed to be NULL */
/* parameters are ok ... */
/* get the lock to prevent other clients from entering */
ixNpeMhConfigLockGet (npeId);
/* save the unsolicited callback for the message ID */
ixNpeMhUnsolicitedCbMgrCallbackSave (
npeId, messageId, unsolicitedCallback);
/* release the lock to allow other clients back in */
ixNpeMhConfigLockRelease (npeId);
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhUnsolicitedCallbackRegister\n");
return IX_SUCCESS;
}
/*
* Function definition: ixNpeMhUnsolicitedCallbackForRangeRegister
*/
PUBLIC IX_STATUS ixNpeMhUnsolicitedCallbackForRangeRegister (
IxNpeMhNpeId npeId,
IxNpeMhMessageId minMessageId,
IxNpeMhMessageId maxMessageId,
IxNpeMhCallback unsolicitedCallback)
{
IxNpeMhMessageId messageId;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhUnsolicitedCallbackForRangeRegister\n");
/* check that we are initialized */
if (!ixNpeMhInitialized)
{
IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n");
return IX_FAIL;
}
/* check the npeId parameter */
if (!ixNpeMhConfigNpeIdIsValid (npeId))
{
IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n");
return IX_FAIL;
}
/* check the minMessageId parameter */
if ((minMessageId < IX_NPEMH_MIN_MESSAGE_ID)
|| (minMessageId > IX_NPEMH_MAX_MESSAGE_ID))
{
IX_NPEMH_ERROR_REPORT ("Min message ID is out of range\n");
return IX_FAIL;
}
/* check the maxMessageId parameter */
if ((maxMessageId < IX_NPEMH_MIN_MESSAGE_ID)
|| (maxMessageId > IX_NPEMH_MAX_MESSAGE_ID))
{
IX_NPEMH_ERROR_REPORT ("Max message ID is out of range\n");
return IX_FAIL;
}
/* check the semantics of the message range parameters */
if (minMessageId > maxMessageId)
{
IX_NPEMH_ERROR_REPORT ("Min message ID greater than max message "
"ID\n");
return IX_FAIL;
}
/* the unsolicitedCallback parameter is allowed to be NULL */
/* parameters are ok ... */
/* get the lock to prevent other clients from entering */
ixNpeMhConfigLockGet (npeId);
/* for each message ID in the range ... */
for (messageId = minMessageId; messageId <= maxMessageId; messageId++)
{
/* save the unsolicited callback for the message ID */
ixNpeMhUnsolicitedCbMgrCallbackSave (
npeId, messageId, unsolicitedCallback);
}
/* release the lock to allow other clients back in */
ixNpeMhConfigLockRelease (npeId);
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhUnsolicitedCallbackForRangeRegister\n");
return IX_SUCCESS;
}
/*
* Function definition: ixNpeMhMessageSend
*/
PUBLIC IX_STATUS ixNpeMhMessageSend (
IxNpeMhNpeId npeId,
IxNpeMhMessage message,
UINT32 maxSendRetries)
{
IX_STATUS status = IX_SUCCESS;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhMessageSend\n");
/* check that we are initialized */
if (!ixNpeMhInitialized)
{
IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n");
return IX_FAIL;
}
/* check the npeId parameter */
if (!ixNpeMhConfigNpeIdIsValid (npeId))
{
IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n");
return IX_FAIL;
}
/* parameters are ok ... */
/* get the lock to prevent other clients from entering */
ixNpeMhConfigLockGet (npeId);
/* send the message */
status = ixNpeMhSendMessageSend (npeId, message, maxSendRetries);
if (status != IX_SUCCESS)
{
IX_NPEMH_ERROR_REPORT ("Failed to send message\n");
}
/* release the lock to allow other clients back in */
ixNpeMhConfigLockRelease (npeId);
IX_NPEMH_TRACE1 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhMessageSend"
" : status = %d\n", status);
return status;
}
/*
* Function definition: ixNpeMhMessageWithResponseSend
*/
PUBLIC IX_STATUS ixNpeMhMessageWithResponseSend (
IxNpeMhNpeId npeId,
IxNpeMhMessage message,
IxNpeMhMessageId solicitedMessageId,
IxNpeMhCallback solicitedCallback,
UINT32 maxSendRetries)
{
IX_STATUS status = IX_SUCCESS;
IxNpeMhCallback unsolicitedCallback = NULL;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhMessageWithResponseSend\n");
/* check that we are initialized */
if (!ixNpeMhInitialized)
{
IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n");
return IX_FAIL;
}
/* the solicitecCallback parameter is allowed to be NULL. this */
/* signifies the client is not interested in the response message */
/* check the npeId parameter */
if (!ixNpeMhConfigNpeIdIsValid (npeId))
{
IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n");
return IX_FAIL;
}
/* check the solicitedMessageId parameter */
if ((solicitedMessageId < IX_NPEMH_MIN_MESSAGE_ID)
|| (solicitedMessageId > IX_NPEMH_MAX_MESSAGE_ID))
{
IX_NPEMH_ERROR_REPORT ("Solicited message ID is out of range\n");
return IX_FAIL;
}
/* check the solicitedMessageId parameter. if an unsolicited */
/* callback has been registered for the specified message ID then */
/* report an error and return failure */
ixNpeMhUnsolicitedCbMgrCallbackRetrieve (
npeId, solicitedMessageId, &unsolicitedCallback);
if (unsolicitedCallback != NULL)
{
IX_NPEMH_ERROR_REPORT ("Solicited message ID conflicts with "
"unsolicited message ID\n");
return IX_FAIL;
}
/* parameters are ok ... */
/* get the lock to prevent other clients from entering */
ixNpeMhConfigLockGet (npeId);
/* send the message */
status = ixNpeMhSendMessageWithResponseSend (
npeId, message, solicitedMessageId, solicitedCallback,
maxSendRetries);
if (status != IX_SUCCESS)
{
IX_NPEMH_ERROR_REPORT ("Failed to send message\n");
}
/* release the lock to allow other clients back in */
ixNpeMhConfigLockRelease (npeId);
IX_NPEMH_TRACE1 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhMessageWithResponseSend"
" : status = %d\n", status);
return status;
}
/*
* Function definition: ixNpeMhMessagesReceive
*/
PUBLIC IX_STATUS ixNpeMhMessagesReceive (
IxNpeMhNpeId npeId)
{
IX_STATUS status = IX_SUCCESS;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhMessagesReceive\n");
/* check that we are initialized */
if (!ixNpeMhInitialized)
{
IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n");
return IX_FAIL;
}
/* check the npeId parameter */
if (!ixNpeMhConfigNpeIdIsValid (npeId))
{
IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n");
return IX_FAIL;
}
/* parameters are ok ... */
/* get the lock to prevent other clients from entering */
ixNpeMhConfigLockGet (npeId);
/* receive messages from the NPE */
status = ixNpeMhReceiveMessagesReceive (npeId);
if (status != IX_SUCCESS)
{
IX_NPEMH_ERROR_REPORT ("Failed to receive message\n");
}
/* release the lock to allow other clients back in */
ixNpeMhConfigLockRelease (npeId);
IX_NPEMH_TRACE1 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhMessagesReceive"
" : status = %d\n", status);
return status;
}
/*
* Function definition: ixNpeMhShow
*/
PUBLIC IX_STATUS ixNpeMhShow (
IxNpeMhNpeId npeId)
{
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhShow\n");
/* check that we are initialized */
if (!ixNpeMhInitialized)
{
IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n");
return IX_FAIL;
}
/* check the npeId parameter */
if (!ixNpeMhConfigNpeIdIsValid (npeId))
{
IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n");
return IX_FAIL;
}
/* parameters are ok ... */
/* note we don't get the lock here as printing the statistics */
/* to a console may take some time and we don't want to impact */
/* system performance. this means that the statistics displayed */
/* may be in a state of flux and make not represent a consistent */
/* snapshot. */
/* display a header */
ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT,
"Current state of NPE ID %d:\n\n", npeId, 0, 0, 0, 0, 0);
/* show the current state of each module */
/* show the current state of the Configuration module */
ixNpeMhConfigShow (npeId);
/* show the current state of the Receive module */
ixNpeMhReceiveShow (npeId);
/* show the current state of the Send module */
ixNpeMhSendShow (npeId);
/* show the current state of the Solicited Callback Manager module */
ixNpeMhSolicitedCbMgrShow (npeId);
/* show the current state of the Unsolicited Callback Manager module */
ixNpeMhUnsolicitedCbMgrShow (npeId);
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhShow\n");
return IX_SUCCESS;
}
/*
* Function definition: ixNpeMhShowReset
*/
PUBLIC IX_STATUS ixNpeMhShowReset (
IxNpeMhNpeId npeId)
{
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhShowReset\n");
/* check that we are initialized */
if (!ixNpeMhInitialized)
{
IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n");
return IX_FAIL;
}
/* check the npeId parameter */
if (!ixNpeMhConfigNpeIdIsValid (npeId))
{
IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n");
return IX_FAIL;
}
/* parameters are ok ... */
/* note we don't get the lock here as resetting the statistics */
/* shouldn't impact system performance. */
/* reset the current state of each module */
/* reset the current state of the Configuration module */
ixNpeMhConfigShowReset (npeId);
/* reset the current state of the Receive module */
ixNpeMhReceiveShowReset (npeId);
/* reset the current state of the Send module */
ixNpeMhSendShowReset (npeId);
/* reset the current state of the Solicited Callback Manager module */
ixNpeMhSolicitedCbMgrShowReset (npeId);
/* reset the current state of the Unsolicited Callback Manager module */
ixNpeMhUnsolicitedCbMgrShowReset (npeId);
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhShowReset\n");
return IX_SUCCESS;
}

608
cpu/ixp/npe/IxNpeMhConfig.c Normal file
View file

@ -0,0 +1,608 @@
/**
* @file IxNpeMhConfig.c
*
* @author Intel Corporation
* @date 18 Jan 2002
*
* @brief This file contains the implementation of the private API for the
* Configuration module.
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
/*
* Put the system defined include files required.
*/
/*
* Put the user defined include files required.
*/
#include "IxOsal.h"
#include "IxNpeMhMacros_p.h"
#include "IxNpeMhConfig_p.h"
/*
* #defines and macros used in this file.
*/
#define IX_NPE_MH_MAX_NUM_OF_RETRIES 1000000 /**< Maximum number of
* retries before
* timeout
*/
/*
* Typedefs whose scope is limited to this file.
*/
/**
* @struct IxNpeMhConfigStats
*
* @brief This structure is used to maintain statistics for the
* Configuration module.
*/
typedef struct
{
UINT32 outFifoReads; /**< outFifo reads */
UINT32 inFifoWrites; /**< inFifo writes */
UINT32 maxInFifoFullRetries; /**< max retries if inFIFO full */
UINT32 maxOutFifoEmptyRetries; /**< max retries if outFIFO empty */
} IxNpeMhConfigStats;
/*
* Variable declarations global to this file only. Externs are followed by
* static variables.
*/
IxNpeMhConfigNpeInfo ixNpeMhConfigNpeInfo[IX_NPEMH_NUM_NPES] =
{
{
0,
IX_NPEMH_NPEA_INT,
0,
0,
0,
0,
0,
NULL,
FALSE
},
{
0,
IX_NPEMH_NPEB_INT,
0,
0,
0,
0,
0,
NULL,
FALSE
},
{
0,
IX_NPEMH_NPEC_INT,
0,
0,
0,
0,
0,
NULL,
FALSE
}
};
PRIVATE IxNpeMhConfigStats ixNpeMhConfigStats[IX_NPEMH_NUM_NPES];
/*
* Extern function prototypes.
*/
/*
* Static function prototypes.
*/
PRIVATE
void ixNpeMhConfigIsr (void *parameter);
/*
* Function definition: ixNpeMhConfigIsr
*/
PRIVATE
void ixNpeMhConfigIsr (void *parameter)
{
IxNpeMhNpeId npeId = (IxNpeMhNpeId)parameter;
UINT32 ofint;
volatile UINT32 *statusReg =
(UINT32 *)ixNpeMhConfigNpeInfo[npeId].statusRegister;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhConfigIsr\n");
/* get the OFINT (OutFifo interrupt) bit of the status register */
IX_NPEMH_REGISTER_READ_BITS (statusReg, &ofint, IX_NPEMH_NPE_STAT_OFINT);
/* if the OFINT status bit is set */
if (ofint)
{
/* if there is an ISR registered for this NPE */
if (ixNpeMhConfigNpeInfo[npeId].isr != NULL)
{
/* invoke the ISR routine */
ixNpeMhConfigNpeInfo[npeId].isr (npeId);
}
else
{
/* if we don't service the interrupt the NPE will continue */
/* to trigger the interrupt indefinitely */
IX_NPEMH_ERROR_REPORT ("No ISR registered to service "
"interrupt\n");
}
}
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhConfigIsr\n");
}
/*
* Function definition: ixNpeMhConfigInitialize
*/
void ixNpeMhConfigInitialize (
IxNpeMhNpeInterrupts npeInterrupts)
{
IxNpeMhNpeId npeId;
UINT32 virtualAddr[IX_NPEMH_NUM_NPES];
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhConfigInitialize\n");
/* Request a mapping for the NPE-A config register address space */
virtualAddr[IX_NPEMH_NPEID_NPEA] =
(UINT32) IX_OSAL_MEM_MAP (IX_NPEMH_NPEA_BASE,
IX_OSAL_IXP400_NPEA_MAP_SIZE);
IX_OSAL_ASSERT (virtualAddr[IX_NPEMH_NPEID_NPEA]);
/* Request a mapping for the NPE-B config register address space */
virtualAddr[IX_NPEMH_NPEID_NPEB] =
(UINT32) IX_OSAL_MEM_MAP (IX_NPEMH_NPEB_BASE,
IX_OSAL_IXP400_NPEB_MAP_SIZE);
IX_OSAL_ASSERT (virtualAddr[IX_NPEMH_NPEID_NPEB]);
/* Request a mapping for the NPE-C config register address space */
virtualAddr[IX_NPEMH_NPEID_NPEC] =
(UINT32) IX_OSAL_MEM_MAP (IX_NPEMH_NPEC_BASE,
IX_OSAL_IXP400_NPEC_MAP_SIZE);
IX_OSAL_ASSERT (virtualAddr[IX_NPEMH_NPEID_NPEC]);
/* for each NPE ... */
for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
{
/* declare a convenience pointer */
IxNpeMhConfigNpeInfo *npeInfo = &ixNpeMhConfigNpeInfo[npeId];
/* store the virtual addresses of the NPE registers for later use */
npeInfo->virtualRegisterBase = virtualAddr[npeId];
npeInfo->statusRegister = virtualAddr[npeId] + IX_NPEMH_NPESTAT_OFFSET;
npeInfo->controlRegister = virtualAddr[npeId] + IX_NPEMH_NPECTL_OFFSET;
npeInfo->inFifoRegister = virtualAddr[npeId] + IX_NPEMH_NPEFIFO_OFFSET;
npeInfo->outFifoRegister = virtualAddr[npeId] + IX_NPEMH_NPEFIFO_OFFSET;
/* for test purposes - to verify the register addresses */
IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d status register = "
"0x%08X\n", npeId, npeInfo->statusRegister);
IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d control register = "
"0x%08X\n", npeId, npeInfo->controlRegister);
IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d inFifo register = "
"0x%08X\n", npeId, npeInfo->inFifoRegister);
IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d outFifo register = "
"0x%08X\n", npeId, npeInfo->outFifoRegister);
/* connect our ISR to the NPE interrupt */
(void) ixOsalIrqBind (
npeInfo->interruptId, ixNpeMhConfigIsr, (void *)npeId);
/* initialise a mutex for this NPE */
(void) ixOsalMutexInit (&npeInfo->mutex);
/* if we should service the NPE's "outFIFO not empty" interrupt */
if (npeInterrupts == IX_NPEMH_NPEINTERRUPTS_YES)
{
/* enable the NPE's "outFIFO not empty" interrupt */
ixNpeMhConfigNpeInterruptEnable (npeId);
}
else
{
/* disable the NPE's "outFIFO not empty" interrupt */
ixNpeMhConfigNpeInterruptDisable (npeId);
}
}
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhConfigInitialize\n");
}
/*
* Function definition: ixNpeMhConfigUninit
*/
void ixNpeMhConfigUninit (void)
{
IxNpeMhNpeId npeId;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhConfigUninit\n");
/* for each NPE ... */
for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
{
/* declare a convenience pointer */
IxNpeMhConfigNpeInfo *npeInfo = &ixNpeMhConfigNpeInfo[npeId];
/* disconnect ISR */
ixOsalIrqUnbind(npeInfo->interruptId);
/* destroy mutex associated with this NPE */
ixOsalMutexDestroy(&npeInfo->mutex);
IX_OSAL_MEM_UNMAP (npeInfo->virtualRegisterBase);
npeInfo->virtualRegisterBase = 0;
npeInfo->statusRegister = 0;
npeInfo->controlRegister = 0;
npeInfo->inFifoRegister = 0;
npeInfo->outFifoRegister = 0;
}
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhConfigUninit\n");
}
/*
* Function definition: ixNpeMhConfigIsrRegister
*/
void ixNpeMhConfigIsrRegister (
IxNpeMhNpeId npeId,
IxNpeMhConfigIsr isr)
{
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhConfigIsrRegister\n");
/* check if there is already an ISR registered for this NPE */
if (ixNpeMhConfigNpeInfo[npeId].isr != NULL)
{
IX_NPEMH_TRACE0 (IX_NPEMH_DEBUG, "Over-writing registered NPE ISR\n");
}
/* save the ISR routine with the NPE info */
ixNpeMhConfigNpeInfo[npeId].isr = isr;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhConfigIsrRegister\n");
}
/*
* Function definition: ixNpeMhConfigNpeInterruptEnable
*/
BOOL ixNpeMhConfigNpeInterruptEnable (
IxNpeMhNpeId npeId)
{
UINT32 ofe;
volatile UINT32 *controlReg =
(UINT32 *)ixNpeMhConfigNpeInfo[npeId].controlRegister;
/* get the OFE (OutFifoEnable) bit of the control register */
IX_NPEMH_REGISTER_READ_BITS (controlReg, &ofe, IX_NPEMH_NPE_CTL_OFE);
/* if the interrupt is disabled then we must enable it */
if (!ofe)
{
/* set the OFE (OutFifoEnable) bit of the control register */
/* we must set the OFEWE (OutFifoEnableWriteEnable) at the same */
/* time for the write to have effect */
IX_NPEMH_REGISTER_WRITE_BITS (controlReg,
(IX_NPEMH_NPE_CTL_OFE |
IX_NPEMH_NPE_CTL_OFEWE),
(IX_NPEMH_NPE_CTL_OFE |
IX_NPEMH_NPE_CTL_OFEWE));
}
/* return the previous state of the interrupt */
return (ofe != 0);
}
/*
* Function definition: ixNpeMhConfigNpeInterruptDisable
*/
BOOL ixNpeMhConfigNpeInterruptDisable (
IxNpeMhNpeId npeId)
{
UINT32 ofe;
volatile UINT32 *controlReg =
(UINT32 *)ixNpeMhConfigNpeInfo[npeId].controlRegister;
/* get the OFE (OutFifoEnable) bit of the control register */
IX_NPEMH_REGISTER_READ_BITS (controlReg, &ofe, IX_NPEMH_NPE_CTL_OFE);
/* if the interrupt is enabled then we must disable it */
if (ofe)
{
/* unset the OFE (OutFifoEnable) bit of the control register */
/* we must set the OFEWE (OutFifoEnableWriteEnable) at the same */
/* time for the write to have effect */
IX_NPEMH_REGISTER_WRITE_BITS (controlReg,
(0 |
IX_NPEMH_NPE_CTL_OFEWE),
(IX_NPEMH_NPE_CTL_OFE |
IX_NPEMH_NPE_CTL_OFEWE));
}
/* return the previous state of the interrupt */
return (ofe != 0);
}
/*
* Function definition: ixNpeMhConfigMessageIdGet
*/
IxNpeMhMessageId ixNpeMhConfigMessageIdGet (
IxNpeMhMessage message)
{
/* return the most-significant byte of the first word of the */
/* message */
return ((IxNpeMhMessageId) ((message.data[0] >> 24) & 0xFF));
}
/*
* Function definition: ixNpeMhConfigNpeIdIsValid
*/
BOOL ixNpeMhConfigNpeIdIsValid (
IxNpeMhNpeId npeId)
{
/* check that the npeId parameter is within the range of valid IDs */
return (npeId >= 0 && npeId < IX_NPEMH_NUM_NPES);
}
/*
* Function definition: ixNpeMhConfigLockGet
*/
void ixNpeMhConfigLockGet (
IxNpeMhNpeId npeId)
{
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhConfigLockGet\n");
/* lock the mutex for this NPE */
(void) ixOsalMutexLock (&ixNpeMhConfigNpeInfo[npeId].mutex,
IX_OSAL_WAIT_FOREVER);
/* disable the NPE's "outFIFO not empty" interrupt */
ixNpeMhConfigNpeInfo[npeId].oldInterruptState =
ixNpeMhConfigNpeInterruptDisable (npeId);
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhConfigLockGet\n");
}
/*
* Function definition: ixNpeMhConfigLockRelease
*/
void ixNpeMhConfigLockRelease (
IxNpeMhNpeId npeId)
{
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhConfigLockRelease\n");
/* if the interrupt was previously enabled */
if (ixNpeMhConfigNpeInfo[npeId].oldInterruptState)
{
/* enable the NPE's "outFIFO not empty" interrupt */
ixNpeMhConfigNpeInfo[npeId].oldInterruptState =
ixNpeMhConfigNpeInterruptEnable (npeId);
}
/* unlock the mutex for this NPE */
(void) ixOsalMutexUnlock (&ixNpeMhConfigNpeInfo[npeId].mutex);
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhConfigLockRelease\n");
}
/*
* Function definition: ixNpeMhConfigInFifoWrite
*/
IX_STATUS ixNpeMhConfigInFifoWrite (
IxNpeMhNpeId npeId,
IxNpeMhMessage message)
{
volatile UINT32 *npeInFifo =
(UINT32 *)ixNpeMhConfigNpeInfo[npeId].inFifoRegister;
UINT32 retriesCount = 0;
/* write the first word of the message to the NPE's inFIFO */
IX_NPEMH_REGISTER_WRITE (npeInFifo, message.data[0]);
/* need to wait for room to write second word - see SCR #493,
poll for maximum number of retries, if exceed maximum
retries, exit from while loop */
while ((IX_NPE_MH_MAX_NUM_OF_RETRIES > retriesCount)
&& ixNpeMhConfigInFifoIsFull (npeId))
{
retriesCount++;
}
/* Return TIMEOUT status to caller, indicate that NPE Hang / Halt */
if (IX_NPE_MH_MAX_NUM_OF_RETRIES == retriesCount)
{
return IX_NPEMH_CRITICAL_NPE_ERR;
}
/* write the second word of the message to the NPE's inFIFO */
IX_NPEMH_REGISTER_WRITE (npeInFifo, message.data[1]);
/* record in the stats the maximum number of retries needed */
if (ixNpeMhConfigStats[npeId].maxInFifoFullRetries < retriesCount)
{
ixNpeMhConfigStats[npeId].maxInFifoFullRetries = retriesCount;
}
/* update statistical info */
ixNpeMhConfigStats[npeId].inFifoWrites++;
return IX_SUCCESS;
}
/*
* Function definition: ixNpeMhConfigOutFifoRead
*/
IX_STATUS ixNpeMhConfigOutFifoRead (
IxNpeMhNpeId npeId,
IxNpeMhMessage *message)
{
volatile UINT32 *npeOutFifo =
(UINT32 *)ixNpeMhConfigNpeInfo[npeId].outFifoRegister;
UINT32 retriesCount = 0;
/* read the first word of the message from the NPE's outFIFO */
IX_NPEMH_REGISTER_READ (npeOutFifo, &message->data[0]);
/* need to wait for NPE to write second word - see SCR #493
poll for maximum number of retries, if exceed maximum
retries, exit from while loop */
while ((IX_NPE_MH_MAX_NUM_OF_RETRIES > retriesCount)
&& ixNpeMhConfigOutFifoIsEmpty (npeId))
{
retriesCount++;
}
/* Return TIMEOUT status to caller, indicate that NPE Hang / Halt */
if (IX_NPE_MH_MAX_NUM_OF_RETRIES == retriesCount)
{
return IX_NPEMH_CRITICAL_NPE_ERR;
}
/* read the second word of the message from the NPE's outFIFO */
IX_NPEMH_REGISTER_READ (npeOutFifo, &message->data[1]);
/* record in the stats the maximum number of retries needed */
if (ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries < retriesCount)
{
ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries = retriesCount;
}
/* update statistical info */
ixNpeMhConfigStats[npeId].outFifoReads++;
return IX_SUCCESS;
}
/*
* Function definition: ixNpeMhConfigShow
*/
void ixNpeMhConfigShow (
IxNpeMhNpeId npeId)
{
/* show the message fifo read counter */
IX_NPEMH_SHOW ("Message FIFO reads",
ixNpeMhConfigStats[npeId].outFifoReads);
/* show the message fifo write counter */
IX_NPEMH_SHOW ("Message FIFO writes",
ixNpeMhConfigStats[npeId].inFifoWrites);
/* show the max retries performed when inFIFO full */
IX_NPEMH_SHOW ("Max inFIFO Full retries",
ixNpeMhConfigStats[npeId].maxInFifoFullRetries);
/* show the max retries performed when outFIFO empty */
IX_NPEMH_SHOW ("Max outFIFO Empty retries",
ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries);
/* show the current status of the inFifo */
ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT,
"InFifo is %s and %s\n",
(ixNpeMhConfigInFifoIsEmpty (npeId) ?
(int) "EMPTY" : (int) "NOT EMPTY"),
(ixNpeMhConfigInFifoIsFull (npeId) ?
(int) "FULL" : (int) "NOT FULL"),
0, 0, 0, 0);
/* show the current status of the outFifo */
ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT,
"OutFifo is %s and %s\n",
(ixNpeMhConfigOutFifoIsEmpty (npeId) ?
(int) "EMPTY" : (int) "NOT EMPTY"),
(ixNpeMhConfigOutFifoIsFull (npeId) ?
(int) "FULL" : (int) "NOT FULL"),
0, 0, 0, 0);
}
/*
* Function definition: ixNpeMhConfigShowReset
*/
void ixNpeMhConfigShowReset (
IxNpeMhNpeId npeId)
{
/* reset the message fifo read counter */
ixNpeMhConfigStats[npeId].outFifoReads = 0;
/* reset the message fifo write counter */
ixNpeMhConfigStats[npeId].inFifoWrites = 0;
/* reset the max inFIFO Full retries counter */
ixNpeMhConfigStats[npeId].maxInFifoFullRetries = 0;
/* reset the max outFIFO empty retries counter */
ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries = 0;
}

View file

@ -0,0 +1,320 @@
/**
* @file IxNpeMhReceive.c
*
* @author Intel Corporation
* @date 18 Jan 2002
*
* @brief This file contains the implementation of the private API for the
* Receive module.
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
/*
* Put the system defined include files required.
*/
/*
* Put the user defined include files required.
*/
#include "IxOsal.h"
#include "IxNpeMhMacros_p.h"
#include "IxNpeMhConfig_p.h"
#include "IxNpeMhReceive_p.h"
#include "IxNpeMhSolicitedCbMgr_p.h"
#include "IxNpeMhUnsolicitedCbMgr_p.h"
/*
* #defines and macros used in this file.
*/
/*
* Typedefs whose scope is limited to this file.
*/
/**
* @struct IxNpeMhReceiveStats
*
* @brief This structure is used to maintain statistics for the Receive
* module.
*/
typedef struct
{
UINT32 isrs; /**< receive ISR invocations */
UINT32 receives; /**< receive messages invocations */
UINT32 messages; /**< messages received */
UINT32 solicited; /**< solicited messages received */
UINT32 unsolicited; /**< unsolicited messages received */
UINT32 callbacks; /**< callbacks invoked */
} IxNpeMhReceiveStats;
/*
* Variable declarations global to this file only. Externs are followed by
* static variables.
*/
PRIVATE IxNpeMhReceiveStats ixNpeMhReceiveStats[IX_NPEMH_NUM_NPES];
/*
* Extern function prototypes.
*/
/*
* Static function prototypes.
*/
PRIVATE
void ixNpeMhReceiveIsr (int npeId);
PRIVATE
void ixNpeMhReceiveIsr (int npeId)
{
int lockKey;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhReceiveIsr\n");
lockKey = ixOsalIrqLock ();
/* invoke the message receive routine to get messages from the NPE */
ixNpeMhReceiveMessagesReceive (npeId);
/* update statistical info */
ixNpeMhReceiveStats[npeId].isrs++;
ixOsalIrqUnlock (lockKey);
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhReceiveIsr\n");
}
/*
* Function definition: ixNpeMhReceiveInitialize
*/
void ixNpeMhReceiveInitialize (void)
{
IxNpeMhNpeId npeId = 0;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhReceiveInitialize\n");
/* for each NPE ... */
for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
{
/* register our internal ISR for the NPE to handle "outFIFO not */
/* empty" interrupts */
ixNpeMhConfigIsrRegister (npeId, ixNpeMhReceiveIsr);
}
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhReceiveInitialize\n");
}
/*
* Function definition: ixNpeMhReceiveMessagesReceive
*/
IX_STATUS ixNpeMhReceiveMessagesReceive (
IxNpeMhNpeId npeId)
{
IxNpeMhMessage message = { { 0, 0 } };
IxNpeMhMessageId messageId = 0;
IxNpeMhCallback callback = NULL;
IX_STATUS status;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhReceiveMessagesReceive\n");
/* update statistical info */
ixNpeMhReceiveStats[npeId].receives++;
/* while the NPE has messages in its outFIFO */
while (!ixNpeMhConfigOutFifoIsEmpty (npeId))
{
/* read a message from the NPE's outFIFO */
status = ixNpeMhConfigOutFifoRead (npeId, &message);
if (IX_SUCCESS != status)
{
return status;
}
/* get the ID of the message */
messageId = ixNpeMhConfigMessageIdGet (message);
IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG,
"Received message from NPE %d with ID 0x%02X\n",
npeId, messageId);
/* update statistical info */
ixNpeMhReceiveStats[npeId].messages++;
/* try to find a matching unsolicited callback for this message. */
/* we assume the message is unsolicited. only if there is no */
/* unsolicited callback for this message type do we assume the */
/* message is solicited. it is much faster to check for an */
/* unsolicited callback, so doing this check first should result */
/* in better performance. */
ixNpeMhUnsolicitedCbMgrCallbackRetrieve (
npeId, messageId, &callback);
if (callback != NULL)
{
IX_NPEMH_TRACE0 (IX_NPEMH_DEBUG,
"Found matching unsolicited callback\n");
/* update statistical info */
ixNpeMhReceiveStats[npeId].unsolicited++;
}
/* if no unsolicited callback was found try to find a matching */
/* solicited callback for this message */
if (callback == NULL)
{
ixNpeMhSolicitedCbMgrCallbackRetrieve (
npeId, messageId, &callback);
if (callback != NULL)
{
IX_NPEMH_TRACE0 (IX_NPEMH_DEBUG,
"Found matching solicited callback\n");
/* update statistical info */
ixNpeMhReceiveStats[npeId].solicited++;
}
}
/* if a callback (either unsolicited or solicited) was found */
if (callback != NULL)
{
/* invoke the callback to pass the message back to the client */
callback (npeId, message);
/* update statistical info */
ixNpeMhReceiveStats[npeId].callbacks++;
}
else /* no callback (neither unsolicited nor solicited) was found */
{
IX_NPEMH_TRACE2 (IX_NPEMH_WARNING,
"No matching callback for NPE %d"
" and ID 0x%02X, discarding message\n",
npeId, messageId);
/* the message will be discarded. this is normal behaviour */
/* if the client passes a NULL solicited callback when */
/* sending a message. this indicates that the client is not */
/* interested in receiving the response. alternatively a */
/* NULL callback here may signify an unsolicited message */
/* with no appropriate registered callback. */
}
}
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhReceiveMessagesReceive\n");
return IX_SUCCESS;
}
/*
* Function definition: ixNpeMhReceiveShow
*/
void ixNpeMhReceiveShow (
IxNpeMhNpeId npeId)
{
/* show the ISR invocation counter */
IX_NPEMH_SHOW ("Receive ISR invocations",
ixNpeMhReceiveStats[npeId].isrs);
/* show the receive message invocation counter */
IX_NPEMH_SHOW ("Receive messages invocations",
ixNpeMhReceiveStats[npeId].receives);
/* show the message received counter */
IX_NPEMH_SHOW ("Messages received",
ixNpeMhReceiveStats[npeId].messages);
/* show the solicited message counter */
IX_NPEMH_SHOW ("Solicited messages received",
ixNpeMhReceiveStats[npeId].solicited);
/* show the unsolicited message counter */
IX_NPEMH_SHOW ("Unsolicited messages received",
ixNpeMhReceiveStats[npeId].unsolicited);
/* show the callback invoked counter */
IX_NPEMH_SHOW ("Callbacks invoked",
ixNpeMhReceiveStats[npeId].callbacks);
/* show the message discarded counter */
IX_NPEMH_SHOW ("Received messages discarded",
(ixNpeMhReceiveStats[npeId].messages -
ixNpeMhReceiveStats[npeId].callbacks));
}
/*
* Function definition: ixNpeMhReceiveShowReset
*/
void ixNpeMhReceiveShowReset (
IxNpeMhNpeId npeId)
{
/* reset the ISR invocation counter */
ixNpeMhReceiveStats[npeId].isrs = 0;
/* reset the receive message invocation counter */
ixNpeMhReceiveStats[npeId].receives = 0;
/* reset the message received counter */
ixNpeMhReceiveStats[npeId].messages = 0;
/* reset the solicited message counter */
ixNpeMhReceiveStats[npeId].solicited = 0;
/* reset the unsolicited message counter */
ixNpeMhReceiveStats[npeId].unsolicited = 0;
/* reset the callback invoked counter */
ixNpeMhReceiveStats[npeId].callbacks = 0;
}

307
cpu/ixp/npe/IxNpeMhSend.c Normal file
View file

@ -0,0 +1,307 @@
/**
* @file IxNpeMhSend.c
*
* @author Intel Corporation
* @date 18 Jan 2002
*
* @brief This file contains the implementation of the private API for the
* Send module.
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
/*
* Put the system defined include files required.
*/
/*
* Put the user defined include files required.
*/
#include "IxNpeMhMacros_p.h"
#include "IxNpeMhConfig_p.h"
#include "IxNpeMhSend_p.h"
#include "IxNpeMhSolicitedCbMgr_p.h"
/*
* #defines and macros used in this file.
*/
/**
* @def IX_NPEMH_INFIFO_RETRY_DELAY_US
*
* @brief Amount of time (uSecs) to delay between retries
* while inFIFO is Full when attempting to send a message
*/
#define IX_NPEMH_INFIFO_RETRY_DELAY_US (1)
/*
* Typedefs whose scope is limited to this file.
*/
/**
* @struct IxNpeMhSendStats
*
* @brief This structure is used to maintain statistics for the Send
* module.
*/
typedef struct
{
UINT32 sends; /**< send invocations */
UINT32 sendWithResponses; /**< send with response invocations */
UINT32 queueFulls; /**< fifo queue full occurrences */
UINT32 queueFullRetries; /**< fifo queue full retry occurrences */
UINT32 maxQueueFullRetries; /**< max fifo queue full retries */
UINT32 callbackFulls; /**< callback list full occurrences */
} IxNpeMhSendStats;
/*
* Variable declarations global to this file only. Externs are followed by
* static variables.
*/
PRIVATE IxNpeMhSendStats ixNpeMhSendStats[IX_NPEMH_NUM_NPES];
/*
* Extern function prototypes.
*/
/*
* Static function prototypes.
*/
PRIVATE
BOOL ixNpeMhSendInFifoIsFull(
IxNpeMhNpeId npeId,
UINT32 maxSendRetries);
/*
* Function definition: ixNpeMhSendInFifoIsFull
*/
PRIVATE
BOOL ixNpeMhSendInFifoIsFull(
IxNpeMhNpeId npeId,
UINT32 maxSendRetries)
{
BOOL isFull = FALSE;
UINT32 numRetries = 0;
/* check the NPE's inFIFO */
isFull = ixNpeMhConfigInFifoIsFull (npeId);
/* we retry a few times, just to give the NPE a chance to read from */
/* the FIFO if the FIFO is currently full */
while (isFull && (numRetries++ < maxSendRetries))
{
if (numRetries >= IX_NPEMH_SEND_RETRIES_DEFAULT)
{
/* Delay here for as short a time as possible (1 us). */
/* Adding a delay here should ensure we are not hogging */
/* the AHB bus while we are retrying */
ixOsalBusySleep (IX_NPEMH_INFIFO_RETRY_DELAY_US);
}
/* re-check the NPE's inFIFO */
isFull = ixNpeMhConfigInFifoIsFull (npeId);
/* update statistical info */
ixNpeMhSendStats[npeId].queueFullRetries++;
}
/* record the highest number of retries that occurred */
if (ixNpeMhSendStats[npeId].maxQueueFullRetries < numRetries)
{
ixNpeMhSendStats[npeId].maxQueueFullRetries = numRetries;
}
if (isFull)
{
/* update statistical info */
ixNpeMhSendStats[npeId].queueFulls++;
}
return isFull;
}
/*
* Function definition: ixNpeMhSendMessageSend
*/
IX_STATUS ixNpeMhSendMessageSend (
IxNpeMhNpeId npeId,
IxNpeMhMessage message,
UINT32 maxSendRetries)
{
IX_STATUS status;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhSendMessageSend\n");
/* update statistical info */
ixNpeMhSendStats[npeId].sends++;
/* check if the NPE's inFIFO is full - if so return an error */
if (ixNpeMhSendInFifoIsFull (npeId, maxSendRetries))
{
IX_NPEMH_TRACE0 (IX_NPEMH_WARNING, "NPE's inFIFO is full\n");
return IX_FAIL;
}
/* write the message to the NPE's inFIFO */
status = ixNpeMhConfigInFifoWrite (npeId, message);
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhSendMessageSend\n");
return status;
}
/*
* Function definition: ixNpeMhSendMessageWithResponseSend
*/
IX_STATUS ixNpeMhSendMessageWithResponseSend (
IxNpeMhNpeId npeId,
IxNpeMhMessage message,
IxNpeMhMessageId solicitedMessageId,
IxNpeMhCallback solicitedCallback,
UINT32 maxSendRetries)
{
IX_STATUS status = IX_SUCCESS;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhSendMessageWithResponseSend\n");
/* update statistical info */
ixNpeMhSendStats[npeId].sendWithResponses++;
/* sr: this sleep will call the receive routine (no interrupts used!!!) */
ixOsalSleep (IX_NPEMH_INFIFO_RETRY_DELAY_US);
/* check if the NPE's inFIFO is full - if so return an error */
if (ixNpeMhSendInFifoIsFull (npeId, maxSendRetries))
{
IX_NPEMH_TRACE0 (IX_NPEMH_WARNING, "NPE's inFIFO is full\n");
return IX_FAIL;
}
/* save the solicited callback */
status = ixNpeMhSolicitedCbMgrCallbackSave (
npeId, solicitedMessageId, solicitedCallback);
if (status != IX_SUCCESS)
{
IX_NPEMH_ERROR_REPORT ("Failed to save solicited callback\n");
/* update statistical info */
ixNpeMhSendStats[npeId].callbackFulls++;
return status;
}
/* write the message to the NPE's inFIFO */
status = ixNpeMhConfigInFifoWrite (npeId, message);
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhSendMessageWithResponseSend\n");
return status;
}
/*
* Function definition: ixNpeMhSendShow
*/
void ixNpeMhSendShow (
IxNpeMhNpeId npeId)
{
/* show the message send invocation counter */
IX_NPEMH_SHOW ("Send invocations",
ixNpeMhSendStats[npeId].sends);
/* show the message send with response invocation counter */
IX_NPEMH_SHOW ("Send with response invocations",
ixNpeMhSendStats[npeId].sendWithResponses);
/* show the fifo queue full occurrence counter */
IX_NPEMH_SHOW ("Fifo queue full occurrences",
ixNpeMhSendStats[npeId].queueFulls);
/* show the fifo queue full retry occurrence counter */
IX_NPEMH_SHOW ("Fifo queue full retry occurrences",
ixNpeMhSendStats[npeId].queueFullRetries);
/* show the fifo queue full maximum retries counter */
IX_NPEMH_SHOW ("Maximum fifo queue full retries",
ixNpeMhSendStats[npeId].maxQueueFullRetries);
/* show the callback list full occurrence counter */
IX_NPEMH_SHOW ("Solicited callback list full occurrences",
ixNpeMhSendStats[npeId].callbackFulls);
}
/*
* Function definition: ixNpeMhSendShowReset
*/
void ixNpeMhSendShowReset (
IxNpeMhNpeId npeId)
{
/* reset the message send invocation counter */
ixNpeMhSendStats[npeId].sends = 0;
/* reset the message send with response invocation counter */
ixNpeMhSendStats[npeId].sendWithResponses = 0;
/* reset the fifo queue full occurrence counter */
ixNpeMhSendStats[npeId].queueFulls = 0;
/* reset the fifo queue full retry occurrence counter */
ixNpeMhSendStats[npeId].queueFullRetries = 0;
/* reset the max fifo queue full retries counter */
ixNpeMhSendStats[npeId].maxQueueFullRetries = 0;
/* reset the callback list full occurrence counter */
ixNpeMhSendStats[npeId].callbackFulls = 0;
}

View file

@ -0,0 +1,358 @@
/**
* @file IxNpeMhSolicitedCbMgr.c
*
* @author Intel Corporation
* @date 18 Jan 2002
*
* @brief This file contains the implementation of the private API for the
* Solicited Callback Manager module.
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#ifndef IXNPEMHCONFIG_P_H
# define IXNPEMHSOLICITEDCBMGR_C
#else
# error "Error, IxNpeMhConfig_p.h should not be included before this definition."
#endif
/*
* Put the system defined include files required.
*/
/*
* Put the user defined include files required.
*/
#include "IxOsal.h"
#include "IxNpeMhMacros_p.h"
#include "IxNpeMhSolicitedCbMgr_p.h"
#include "IxNpeMhConfig_p.h"
/*
* #defines and macros used in this file.
*/
/*
* Typedefs whose scope is limited to this file.
*/
/**
* @struct IxNpeMhSolicitedCallbackListEntry
*
* @brief This structure is used to store the information associated with
* an entry in the callback list. This consists of the ID of the send
* message (which indicates the ID of the corresponding response message)
* and the callback function pointer itself.
*
*/
typedef struct IxNpeMhSolicitedCallbackListEntry
{
/** message ID */
IxNpeMhMessageId messageId;
/** callback function pointer */
IxNpeMhCallback callback;
/** pointer to next entry in the list */
struct IxNpeMhSolicitedCallbackListEntry *next;
} IxNpeMhSolicitedCallbackListEntry;
/**
* @struct IxNpeMhSolicitedCallbackList
*
* @brief This structure is used to maintain the list of response
* callbacks. The number of entries in this list will be variable, and
* they will be stored in a linked list fashion for ease of addition and
* removal. The entries themselves are statically allocated, and are
* organised into a "free" list and a "callback" list. Adding an entry
* means taking an entry from the "free" list and adding it to the
* "callback" list. Removing an entry means removing it from the
* "callback" list and returning it to the "free" list.
*/
typedef struct
{
/** pointer to the head of the free list */
IxNpeMhSolicitedCallbackListEntry *freeHead;
/** pointer to the head of the callback list */
IxNpeMhSolicitedCallbackListEntry *callbackHead;
/** pointer to the tail of the callback list */
IxNpeMhSolicitedCallbackListEntry *callbackTail;
/** array of entries - the first entry is used as a dummy entry to */
/* avoid the scenario of having an empty list, hence '+ 1' */
IxNpeMhSolicitedCallbackListEntry entries[IX_NPEMH_MAX_CALLBACKS + 1];
} IxNpeMhSolicitedCallbackList;
/**
* @struct IxNpeMhSolicitedCbMgrStats
*
* @brief This structure is used to maintain statistics for the Solicited
* Callback Manager module.
*/
typedef struct
{
UINT32 saves; /**< callback list saves */
UINT32 retrieves; /**< callback list retrieves */
} IxNpeMhSolicitedCbMgrStats;
/*
* Variable declarations global to this file only. Externs are followed by
* static variables.
*/
PRIVATE IxNpeMhSolicitedCallbackList
ixNpeMhSolicitedCbMgrCallbackLists[IX_NPEMH_NUM_NPES];
PRIVATE IxNpeMhSolicitedCbMgrStats
ixNpeMhSolicitedCbMgrStats[IX_NPEMH_NUM_NPES];
/*
* Extern function prototypes.
*/
/*
* Static function prototypes.
*/
/*
* Function definition: ixNpeMhSolicitedCbMgrInitialize
*/
void ixNpeMhSolicitedCbMgrInitialize (void)
{
IxNpeMhNpeId npeId;
UINT32 localIndex;
IxNpeMhSolicitedCallbackList *list = NULL;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhSolicitedCbMgrInitialize\n");
/* for each NPE ... */
for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
{
/* initialise a pointer to the list for convenience */
list = &ixNpeMhSolicitedCbMgrCallbackLists[npeId];
/* for each entry in the list, after the dummy entry ... */
for (localIndex = 1; localIndex <= IX_NPEMH_MAX_CALLBACKS; localIndex++)
{
/* initialise the entry */
list->entries[localIndex].messageId = 0x00;
list->entries[localIndex].callback = NULL;
/* if this entry is before the last entry */
if (localIndex < IX_NPEMH_MAX_CALLBACKS)
{
/* chain this entry to the following entry */
list->entries[localIndex].next = &(list->entries[localIndex + 1]);
}
else /* this entry is the last entry */
{
/* the last entry isn't chained to anything */
list->entries[localIndex].next = NULL;
}
}
/* set the free list pointer to point to the first real entry */
/* (all real entries begin chained together on the free list) */
list->freeHead = &(list->entries[1]);
/* set the callback list pointers to point to the dummy entry */
/* (the callback list is initially empty) */
list->callbackHead = &(list->entries[0]);
list->callbackTail = &(list->entries[0]);
}
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhSolicitedCbMgrInitialize\n");
}
/*
* Function definition: ixNpeMhSolicitedCbMgrCallbackSave
*/
IX_STATUS ixNpeMhSolicitedCbMgrCallbackSave (
IxNpeMhNpeId npeId,
IxNpeMhMessageId solicitedMessageId,
IxNpeMhCallback solicitedCallback)
{
IxNpeMhSolicitedCallbackList *list = NULL;
IxNpeMhSolicitedCallbackListEntry *callbackEntry = NULL;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhSolicitedCbMgrCallbackSave\n");
/* initialise a pointer to the list for convenience */
list = &ixNpeMhSolicitedCbMgrCallbackLists[npeId];
/* check to see if there are any entries in the free list */
if (list->freeHead == NULL)
{
IX_NPEMH_ERROR_REPORT ("Solicited callback list is full\n");
return IX_FAIL;
}
/* there is an entry in the free list we can use */
/* update statistical info */
ixNpeMhSolicitedCbMgrStats[npeId].saves++;
/* remove a callback entry from the start of the free list */
callbackEntry = list->freeHead;
list->freeHead = callbackEntry->next;
/* fill in the callback entry with the new data */
callbackEntry->messageId = solicitedMessageId;
callbackEntry->callback = solicitedCallback;
/* the new callback entry will be added to the tail of the callback */
/* list, so it isn't chained to anything */
callbackEntry->next = NULL;
/* chain new callback entry to the last entry of the callback list */
list->callbackTail->next = callbackEntry;
list->callbackTail = callbackEntry;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhSolicitedCbMgrCallbackSave\n");
return IX_SUCCESS;
}
/*
* Function definition: ixNpeMhSolicitedCbMgrCallbackRetrieve
*/
void ixNpeMhSolicitedCbMgrCallbackRetrieve (
IxNpeMhNpeId npeId,
IxNpeMhMessageId solicitedMessageId,
IxNpeMhCallback *solicitedCallback)
{
IxNpeMhSolicitedCallbackList *list = NULL;
IxNpeMhSolicitedCallbackListEntry *callbackEntry = NULL;
IxNpeMhSolicitedCallbackListEntry *previousEntry = NULL;
/* initialise a pointer to the list for convenience */
list = &ixNpeMhSolicitedCbMgrCallbackLists[npeId];
/* initialise the callback entry to the first entry of the callback */
/* list - we must skip over the dummy entry, which is the previous */
callbackEntry = list->callbackHead->next;
previousEntry = list->callbackHead;
/* traverse the callback list looking for an entry with a matching */
/* message ID. note we also save the previous entry's pointer to */
/* allow us to unchain the matching entry from the callback list */
while ((callbackEntry != NULL) &&
(callbackEntry->messageId != solicitedMessageId))
{
previousEntry = callbackEntry;
callbackEntry = callbackEntry->next;
}
/* if we didn't find a matching callback entry */
if (callbackEntry == NULL)
{
/* return a NULL callback in the outgoing parameter */
*solicitedCallback = NULL;
}
else /* we found a matching callback entry */
{
/* update statistical info */
ixNpeMhSolicitedCbMgrStats[npeId].retrieves++;
/* return the callback in the outgoing parameter */
*solicitedCallback = callbackEntry->callback;
/* unchain callback entry by chaining previous entry to next */
previousEntry->next = callbackEntry->next;
/* if the callback entry is at the tail of the list */
if (list->callbackTail == callbackEntry)
{
/* update the tail of the callback list */
list->callbackTail = previousEntry;
}
/* re-initialise the callback entry */
callbackEntry->messageId = 0x00;
callbackEntry->callback = NULL;
/* add the callback entry to the start of the free list */
callbackEntry->next = list->freeHead;
list->freeHead = callbackEntry;
}
}
/*
* Function definition: ixNpeMhSolicitedCbMgrShow
*/
void ixNpeMhSolicitedCbMgrShow (
IxNpeMhNpeId npeId)
{
/* show the solicited callback list save counter */
IX_NPEMH_SHOW ("Solicited callback list saves",
ixNpeMhSolicitedCbMgrStats[npeId].saves);
/* show the solicited callback list retrieve counter */
IX_NPEMH_SHOW ("Solicited callback list retrieves",
ixNpeMhSolicitedCbMgrStats[npeId].retrieves);
}
/*
* Function definition: ixNpeMhSolicitedCbMgrShowReset
*/
void ixNpeMhSolicitedCbMgrShowReset (
IxNpeMhNpeId npeId)
{
/* reset the solicited callback list save counter */
ixNpeMhSolicitedCbMgrStats[npeId].saves = 0;
/* reset the solicited callback list retrieve counter */
ixNpeMhSolicitedCbMgrStats[npeId].retrieves = 0;
}

View file

@ -0,0 +1,246 @@
/**
* @file IxNpeMhUnsolicitedCbMgr.c
*
* @author Intel Corporation
* @date 18 Jan 2002
*
* @brief This file contains the implementation of the private API for
* the Unsolicited Callback Manager module.
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
/*
* Put the system defined include files required.
*/
/*
* Put the user defined include files required.
*/
#include "IxOsal.h"
#include "IxNpeMhMacros_p.h"
#include "IxNpeMhUnsolicitedCbMgr_p.h"
/*
* #defines and macros used in this file.
*/
/*
* Typedefs whose scope is limited to this file.
*/
/**
* @struct IxNpeMhUnsolicitedCallbackTable
*
* @brief This structure is used to maintain the list of registered
* callbacks. One entry exists for each message ID, and a NULL entry will
* signify that no callback has been registered for that ID.
*/
typedef struct
{
/** array of entries */
IxNpeMhCallback entries[IX_NPEMH_MAX_MESSAGE_ID + 1];
} IxNpeMhUnsolicitedCallbackTable;
/**
* @struct IxNpeMhUnsolicitedCbMgrStats
*
* @brief This structure is used to maintain statistics for the Unsolicited
* Callback Manager module.
*/
typedef struct
{
UINT32 saves; /**< callback table saves */
UINT32 overwrites; /**< callback table overwrites */
} IxNpeMhUnsolicitedCbMgrStats;
/*
* Variable declarations global to this file only. Externs are followed by
* static variables.
*/
PRIVATE IxNpeMhUnsolicitedCallbackTable
ixNpeMhUnsolicitedCallbackTables[IX_NPEMH_NUM_NPES];
PRIVATE IxNpeMhUnsolicitedCbMgrStats
ixNpeMhUnsolicitedCbMgrStats[IX_NPEMH_NUM_NPES];
/*
* Extern function prototypes.
*/
/*
* Static function prototypes.
*/
/*
* Function definition: ixNpeMhUnsolicitedCbMgrInitialize
*/
void ixNpeMhUnsolicitedCbMgrInitialize (void)
{
IxNpeMhNpeId npeId = 0;
IxNpeMhUnsolicitedCallbackTable *table = NULL;
IxNpeMhMessageId messageId = 0;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhUnsolicitedCbMgrInitialize\n");
/* for each NPE ... */
for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
{
/* initialise a pointer to the table for convenience */
table = &ixNpeMhUnsolicitedCallbackTables[npeId];
/* for each message ID ... */
for (messageId = IX_NPEMH_MIN_MESSAGE_ID;
messageId <= IX_NPEMH_MAX_MESSAGE_ID; messageId++)
{
/* initialise the callback for this message ID to NULL */
table->entries[messageId] = NULL;
}
}
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhUnsolicitedCbMgrInitialize\n");
}
/*
* Function definition: ixNpeMhUnsolicitedCbMgrCallbackSave
*/
void ixNpeMhUnsolicitedCbMgrCallbackSave (
IxNpeMhNpeId npeId,
IxNpeMhMessageId unsolicitedMessageId,
IxNpeMhCallback unsolicitedCallback)
{
IxNpeMhUnsolicitedCallbackTable *table = NULL;
/* initialise a pointer to the table for convenience */
table = &ixNpeMhUnsolicitedCallbackTables[npeId];
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhUnsolicitedCbMgrCallbackSave\n");
/* update statistical info */
ixNpeMhUnsolicitedCbMgrStats[npeId].saves++;
/* check if there is a callback already registered for this NPE and */
/* message ID */
if (table->entries[unsolicitedMessageId] != NULL)
{
/* if we are overwriting an existing callback */
if (unsolicitedCallback != NULL)
{
IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "Unsolicited callback "
"overwriting existing callback for NPE ID %d "
"message ID 0x%02X\n", npeId, unsolicitedMessageId);
}
else /* if we are clearing an existing callback */
{
IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NULL unsolicited callback "
"clearing existing callback for NPE ID %d "
"message ID 0x%02X\n", npeId, unsolicitedMessageId);
}
/* update statistical info */
ixNpeMhUnsolicitedCbMgrStats[npeId].overwrites++;
}
/* save the callback into the table */
table->entries[unsolicitedMessageId] = unsolicitedCallback;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhUnsolicitedCbMgrCallbackSave\n");
}
/*
* Function definition: ixNpeMhUnsolicitedCbMgrCallbackRetrieve
*/
void ixNpeMhUnsolicitedCbMgrCallbackRetrieve (
IxNpeMhNpeId npeId,
IxNpeMhMessageId unsolicitedMessageId,
IxNpeMhCallback *unsolicitedCallback)
{
IxNpeMhUnsolicitedCallbackTable *table = NULL;
/* initialise a pointer to the table for convenience */
table = &ixNpeMhUnsolicitedCallbackTables[npeId];
/* retrieve the callback from the table */
*unsolicitedCallback = table->entries[unsolicitedMessageId];
}
/*
* Function definition: ixNpeMhUnsolicitedCbMgrShow
*/
void ixNpeMhUnsolicitedCbMgrShow (
IxNpeMhNpeId npeId)
{
/* show the unsolicited callback table save counter */
IX_NPEMH_SHOW ("Unsolicited callback table saves",
ixNpeMhUnsolicitedCbMgrStats[npeId].saves);
/* show the unsolicited callback table overwrite counter */
IX_NPEMH_SHOW ("Unsolicited callback table overwrites",
ixNpeMhUnsolicitedCbMgrStats[npeId].overwrites);
}
/*
* Function definition: ixNpeMhUnsolicitedCbMgrShowReset
*/
void ixNpeMhUnsolicitedCbMgrShowReset (
IxNpeMhNpeId npeId)
{
/* reset the unsolicited callback table save counter */
ixNpeMhUnsolicitedCbMgrStats[npeId].saves = 0;
/* reset the unsolicited callback table overwrite counter */
ixNpeMhUnsolicitedCbMgrStats[npeId].overwrites = 0;
}

View file

@ -0,0 +1,800 @@
/**
* @file IxOsalBufferMgt.c
*
* @brief Default buffer pool management and buffer management
* Implementation.
*
* Design Notes:
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
/*
* OS may choose to use default bufferMgt by defining
* IX_OSAL_USE_DEFAULT_BUFFER_MGT in IxOsalOsBufferMgt.h
*/
#include "IxOsal.h"
#define IX_OSAL_BUFFER_FREE_PROTECTION /* Define this to enable Illegal MBuf Freed Protection*/
/*
* The implementation is only used when the following
* is defined.
*/
#ifdef IX_OSAL_USE_DEFAULT_BUFFER_MGT
#define IX_OSAL_MBUF_SYS_SIGNATURE (0x8BADF00D)
#define IX_OSAL_MBUF_SYS_SIGNATURE_MASK (0xEFFFFFFF)
#define IX_OSAL_MBUF_USED_FLAG (0x10000000)
#define IX_OSAL_MBUF_SYS_SIGNATURE_INIT(bufPtr) IX_OSAL_MBUF_SIGNATURE (bufPtr) = (UINT32)IX_OSAL_MBUF_SYS_SIGNATURE
/*
* This implementation is protect, the buffer pool management's ixOsalMBufFree
* against an invalid MBUF pointer argument that already has been freed earlier
* or in other words resides in the free pool of MBUFs. This added feature,
* checks the MBUF "USED" FLAG. The Flag tells if the MBUF is still not freed
* back to the Buffer Pool.
* Disable this feature for performance reasons by undef
* IX_OSAL_BUFFER_FREE_PROTECTION macro.
*/
#ifdef IX_OSAL_BUFFER_FREE_PROTECTION /*IX_OSAL_BUFFER_FREE_PROTECTION With Buffer Free protection*/
#define IX_OSAL_MBUF_GET_SYS_SIGNATURE(bufPtr) (IX_OSAL_MBUF_SIGNATURE (bufPtr)&(IX_OSAL_MBUF_SYS_SIGNATURE_MASK) )
#define IX_OSAL_MBUF_SET_SYS_SIGNATURE(bufPtr) do { \
IX_OSAL_MBUF_SIGNATURE (bufPtr)&(~IX_OSAL_MBUF_SYS_SIGNATURE_MASK);\
IX_OSAL_MBUF_SIGNATURE (bufPtr)|=IX_OSAL_MBUF_SYS_SIGNATURE; \
}while(0)
#define IX_OSAL_MBUF_SET_USED_FLAG(bufPtr) IX_OSAL_MBUF_SIGNATURE (bufPtr)|=IX_OSAL_MBUF_USED_FLAG
#define IX_OSAL_MBUF_CLEAR_USED_FLAG(bufPtr) IX_OSAL_MBUF_SIGNATURE (bufPtr)&=~IX_OSAL_MBUF_USED_FLAG
#define IX_OSAL_MBUF_ISSET_USED_FLAG(bufPtr) (IX_OSAL_MBUF_SIGNATURE (bufPtr)&IX_OSAL_MBUF_USED_FLAG)
#else
#define IX_OSAL_MBUF_GET_SYS_SIGNATURE(bufPtr) IX_OSAL_MBUF_SIGNATURE (bufPtr)
#define IX_OSAL_MBUF_SET_SYS_SIGNATURE(bufPtr) IX_OSAL_MBUF_SIGNATURE (bufPtr) = IX_OSAL_MBUF_SYS_SIGNATURE
#endif /*IX_OSAL_BUFFER_FREE_PROTECTION With Buffer Free protection*/
/*
* Variable declarations global to this file only. Externs are followed by
* static variables.
*/
/*
* A unit of 32, used to provide bit-shift for pool
* management. Needs some work if users want more than 32 pools.
*/
#define IX_OSAL_BUFF_FREE_BITS 32
PRIVATE UINT32 ixOsalBuffFreePools[IX_OSAL_MBUF_MAX_POOLS /
IX_OSAL_BUFF_FREE_BITS];
PUBLIC IX_OSAL_MBUF_POOL ixOsalBuffPools[IX_OSAL_MBUF_MAX_POOLS];
static int ixOsalBuffPoolsInUse = 0;
#ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY
PRIVATE IX_OSAL_MBUF *
ixOsalBuffPoolMbufInit (UINT32 mbufSizeAligned,
UINT32 dataSizeAligned,
IX_OSAL_MBUF_POOL *poolPtr);
#endif
PRIVATE IX_OSAL_MBUF_POOL * ixOsalPoolAlloc (void);
/*
* Function definition: ixOsalPoolAlloc
*/
/****************************/
PRIVATE IX_OSAL_MBUF_POOL *
ixOsalPoolAlloc (void)
{
register unsigned int i = 0;
/*
* Scan for the first free buffer. Free buffers are indicated by 0
* on the corrsponding bit in ixOsalBuffFreePools.
*/
if (ixOsalBuffPoolsInUse >= IX_OSAL_MBUF_MAX_POOLS)
{
/*
* Fail to grab a ptr this time
*/
return NULL;
}
while (ixOsalBuffFreePools[i / IX_OSAL_BUFF_FREE_BITS] &
(1 << (i % IX_OSAL_BUFF_FREE_BITS)))
i++;
/*
* Free buffer found. Mark it as busy and initialize.
*/
ixOsalBuffFreePools[i / IX_OSAL_BUFF_FREE_BITS] |=
(1 << (i % IX_OSAL_BUFF_FREE_BITS));
memset (&ixOsalBuffPools[i], 0, sizeof (IX_OSAL_MBUF_POOL));
ixOsalBuffPools[i].poolIdx = i;
ixOsalBuffPoolsInUse++;
return &ixOsalBuffPools[i];
}
#ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY
PRIVATE IX_OSAL_MBUF *
ixOsalBuffPoolMbufInit (UINT32 mbufSizeAligned,
UINT32 dataSizeAligned,
IX_OSAL_MBUF_POOL *poolPtr)
{
UINT8 *dataPtr;
IX_OSAL_MBUF *realMbufPtr;
/* Allocate cache-aligned memory for mbuf header */
realMbufPtr = (IX_OSAL_MBUF *) IX_OSAL_CACHE_DMA_MALLOC (mbufSizeAligned);
IX_OSAL_ASSERT (realMbufPtr != NULL);
memset (realMbufPtr, 0, mbufSizeAligned);
/* Allocate cache-aligned memory for mbuf data */
dataPtr = (UINT8 *) IX_OSAL_CACHE_DMA_MALLOC (dataSizeAligned);
IX_OSAL_ASSERT (dataPtr != NULL);
memset (dataPtr, 0, dataSizeAligned);
/* Fill in mbuf header fields */
IX_OSAL_MBUF_MDATA (realMbufPtr) = dataPtr;
IX_OSAL_MBUF_ALLOCATED_BUFF_DATA (realMbufPtr) = (UINT32)dataPtr;
IX_OSAL_MBUF_MLEN (realMbufPtr) = dataSizeAligned;
IX_OSAL_MBUF_ALLOCATED_BUFF_LEN (realMbufPtr) = dataSizeAligned;
IX_OSAL_MBUF_NET_POOL (realMbufPtr) = (IX_OSAL_MBUF_POOL *) poolPtr;
IX_OSAL_MBUF_SYS_SIGNATURE_INIT(realMbufPtr);
/* update some statistical information */
poolPtr->mbufMemSize += mbufSizeAligned;
poolPtr->dataMemSize += dataSizeAligned;
return realMbufPtr;
}
#endif /* #ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY */
/*
* Function definition: ixOsalBuffPoolInit
*/
PUBLIC IX_OSAL_MBUF_POOL *
ixOsalPoolInit (UINT32 count, UINT32 size, const char *name)
{
/* These variables are only used if UX_OSAL_BUFFER_ALLOC_SEPERATELY
* is defined .
*/
#ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY
UINT32 i, mbufSizeAligned, dataSizeAligned;
IX_OSAL_MBUF *currentMbufPtr = NULL;
#else
void *poolBufPtr;
void *poolDataPtr;
int mbufMemSize;
int dataMemSize;
#endif
IX_OSAL_MBUF_POOL *poolPtr = NULL;
if (count <= 0)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
IX_OSAL_LOG_DEV_STDOUT,
"ixOsalPoolInit(): " "count = 0 \n", 0, 0, 0, 0, 0, 0);
return NULL;
}
if (name == NULL)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
IX_OSAL_LOG_DEV_STDOUT,
"ixOsalPoolInit(): " "NULL name \n", 0, 0, 0, 0, 0, 0);
return NULL;
}
if (strlen (name) > IX_OSAL_MBUF_POOL_NAME_LEN)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
IX_OSAL_LOG_DEV_STDOUT,
"ixOsalPoolInit(): "
"ERROR - name length should be no greater than %d \n",
IX_OSAL_MBUF_POOL_NAME_LEN, 0, 0, 0, 0, 0);
return NULL;
}
/* OS can choose whether to allocate all buffers all together (if it
* can handle a huge single alloc request), or to allocate buffers
* separately by the defining IX_OSAL_BUFFER_ALLOC_SEPARATELY.
*/
#ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY
/* Get a pool Ptr */
poolPtr = ixOsalPoolAlloc ();
if (poolPtr == NULL)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
IX_OSAL_LOG_DEV_STDOUT,
"ixOsalPoolInit(): " "Fail to Get PoolPtr \n", 0, 0, 0, 0, 0, 0);
return NULL;
}
mbufSizeAligned = IX_OSAL_MBUF_POOL_SIZE_ALIGN (sizeof (IX_OSAL_MBUF));
dataSizeAligned = IX_OSAL_MBUF_POOL_SIZE_ALIGN(size);
poolPtr->nextFreeBuf = NULL;
poolPtr->mbufMemPtr = NULL;
poolPtr->dataMemPtr = NULL;
poolPtr->bufDataSize = dataSizeAligned;
poolPtr->totalBufsInPool = count;
poolPtr->poolAllocType = IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC;
strcpy (poolPtr->name, name);
for (i = 0; i < count; i++)
{
/* create an mbuf */
currentMbufPtr = ixOsalBuffPoolMbufInit (mbufSizeAligned,
dataSizeAligned,
poolPtr);
#ifdef IX_OSAL_BUFFER_FREE_PROTECTION
/* Set the Buffer USED Flag. If not, ixOsalMBufFree will fail.
ixOsalMbufFree used here is in a special case whereby, it's
used to add MBUF to the Pool. By specification, ixOsalMbufFree
deallocates an allocated MBUF from Pool.
*/
IX_OSAL_MBUF_SET_USED_FLAG(currentMbufPtr);
#endif
/* Add it to the pool */
ixOsalMbufFree (currentMbufPtr);
/* flush the pool information to RAM */
IX_OSAL_CACHE_FLUSH (currentMbufPtr, mbufSizeAligned);
}
/*
* update the number of free buffers in the pool
*/
poolPtr->freeBufsInPool = count;
#else
/* Otherwise allocate buffers in a continuous block fashion */
poolBufPtr = IX_OSAL_MBUF_POOL_MBUF_AREA_ALLOC (count, mbufMemSize);
IX_OSAL_ASSERT (poolBufPtr != NULL);
poolDataPtr =
IX_OSAL_MBUF_POOL_DATA_AREA_ALLOC (count, size, dataMemSize);
IX_OSAL_ASSERT (poolDataPtr != NULL);
poolPtr = ixOsalNoAllocPoolInit (poolBufPtr, poolDataPtr,
count, size, name);
if (poolPtr == NULL)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
IX_OSAL_LOG_DEV_STDOUT,
"ixOsalPoolInit(): " "Fail to get pool ptr \n", 0, 0, 0, 0, 0, 0);
return NULL;
}
poolPtr->poolAllocType = IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC;
#endif /* IX_OSAL_BUFFER_ALLOC_SEPARATELY */
return poolPtr;
}
PUBLIC IX_OSAL_MBUF_POOL *
ixOsalNoAllocPoolInit (void *poolBufPtr,
void *poolDataPtr, UINT32 count, UINT32 size, const char *name)
{
UINT32 i, mbufSizeAligned, sizeAligned;
IX_OSAL_MBUF *currentMbufPtr = NULL;
IX_OSAL_MBUF *nextMbufPtr = NULL;
IX_OSAL_MBUF_POOL *poolPtr = NULL;
/*
* check parameters
*/
if (poolBufPtr == NULL)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
IX_OSAL_LOG_DEV_STDOUT,
"ixOsalNoAllocPoolInit(): "
"ERROR - NULL poolBufPtr \n", 0, 0, 0, 0, 0, 0);
return NULL;
}
if (count <= 0)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
IX_OSAL_LOG_DEV_STDOUT,
"ixOsalNoAllocPoolInit(): "
"ERROR - count must > 0 \n", 0, 0, 0, 0, 0, 0);
return NULL;
}
if (name == NULL)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
IX_OSAL_LOG_DEV_STDOUT,
"ixOsalNoAllocPoolInit(): "
"ERROR - NULL name ptr \n", 0, 0, 0, 0, 0, 0);
return NULL;
}
if (strlen (name) > IX_OSAL_MBUF_POOL_NAME_LEN)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
IX_OSAL_LOG_DEV_STDOUT,
"ixOsalNoAllocPoolInit(): "
"ERROR - name length should be no greater than %d \n",
IX_OSAL_MBUF_POOL_NAME_LEN, 0, 0, 0, 0, 0);
return NULL;
}
poolPtr = ixOsalPoolAlloc ();
if (poolPtr == NULL)
{
return NULL;
}
/*
* Adjust sizes to ensure alignment on cache line boundaries
*/
mbufSizeAligned =
IX_OSAL_MBUF_POOL_SIZE_ALIGN (sizeof (IX_OSAL_MBUF));
/*
* clear the mbuf memory area
*/
memset (poolBufPtr, 0, mbufSizeAligned * count);
if (poolDataPtr != NULL)
{
/*
* Adjust sizes to ensure alignment on cache line boundaries
*/
sizeAligned = IX_OSAL_MBUF_POOL_SIZE_ALIGN (size);
/*
* clear the data memory area
*/
memset (poolDataPtr, 0, sizeAligned * count);
}
else
{
sizeAligned = 0;
}
/*
* initialise pool fields
*/
strcpy ((poolPtr)->name, name);
poolPtr->dataMemPtr = poolDataPtr;
poolPtr->mbufMemPtr = poolBufPtr;
poolPtr->bufDataSize = sizeAligned;
poolPtr->totalBufsInPool = count;
poolPtr->mbufMemSize = mbufSizeAligned * count;
poolPtr->dataMemSize = sizeAligned * count;
currentMbufPtr = (IX_OSAL_MBUF *) poolBufPtr;
poolPtr->nextFreeBuf = currentMbufPtr;
for (i = 0; i < count; i++)
{
if (i < (count - 1))
{
nextMbufPtr =
(IX_OSAL_MBUF *) ((unsigned) currentMbufPtr +
mbufSizeAligned);
}
else
{ /* last mbuf in chain */
nextMbufPtr = NULL;
}
IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (currentMbufPtr) = nextMbufPtr;
IX_OSAL_MBUF_NET_POOL (currentMbufPtr) = poolPtr;
IX_OSAL_MBUF_SYS_SIGNATURE_INIT(currentMbufPtr);
if (poolDataPtr != NULL)
{
IX_OSAL_MBUF_MDATA (currentMbufPtr) = poolDataPtr;
IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(currentMbufPtr) = (UINT32) poolDataPtr;
IX_OSAL_MBUF_MLEN (currentMbufPtr) = sizeAligned;
IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(currentMbufPtr) = sizeAligned;
poolDataPtr = (void *) ((unsigned) poolDataPtr + sizeAligned);
}
currentMbufPtr = nextMbufPtr;
}
/*
* update the number of free buffers in the pool
*/
poolPtr->freeBufsInPool = count;
poolPtr->poolAllocType = IX_OSAL_MBUF_POOL_TYPE_USER_ALLOC;
return poolPtr;
}
/*
* Get a mbuf ptr from the pool
*/
PUBLIC IX_OSAL_MBUF *
ixOsalMbufAlloc (IX_OSAL_MBUF_POOL * poolPtr)
{
int lock;
IX_OSAL_MBUF *newBufPtr = NULL;
/*
* check parameters
*/
if (poolPtr == NULL)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
IX_OSAL_LOG_DEV_STDOUT,
"ixOsalMbufAlloc(): "
"ERROR - Invalid Parameter\n", 0, 0, 0, 0, 0, 0);
return NULL;
}
lock = ixOsalIrqLock ();
newBufPtr = poolPtr->nextFreeBuf;
if (newBufPtr)
{
poolPtr->nextFreeBuf =
IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (newBufPtr);
IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (newBufPtr) = NULL;
/*
* update the number of free buffers in the pool
*/
poolPtr->freeBufsInPool--;
}
else
{
/* Return NULL to indicate to caller that request is denied. */
ixOsalIrqUnlock (lock);
return NULL;
}
#ifdef IX_OSAL_BUFFER_FREE_PROTECTION
/* Set Buffer Used Flag to indicate state.*/
IX_OSAL_MBUF_SET_USED_FLAG(newBufPtr);
#endif
ixOsalIrqUnlock (lock);
return newBufPtr;
}
PUBLIC IX_OSAL_MBUF *
ixOsalMbufFree (IX_OSAL_MBUF * bufPtr)
{
int lock;
IX_OSAL_MBUF_POOL *poolPtr;
IX_OSAL_MBUF *nextBufPtr = NULL;
/*
* check parameters
*/
if (bufPtr == NULL)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
IX_OSAL_LOG_DEV_STDOUT,
"ixOsalMbufFree(): "
"ERROR - Invalid Parameter\n", 0, 0, 0, 0, 0, 0);
return NULL;
}
lock = ixOsalIrqLock ();
#ifdef IX_OSAL_BUFFER_FREE_PROTECTION
/* Prevention for Buffer freed more than once*/
if(!IX_OSAL_MBUF_ISSET_USED_FLAG(bufPtr))
{
return NULL;
}
IX_OSAL_MBUF_CLEAR_USED_FLAG(bufPtr);
#endif
poolPtr = IX_OSAL_MBUF_NET_POOL (bufPtr);
/*
* check the mbuf wrapper signature (if mbuf wrapper was used)
*/
if (poolPtr->poolAllocType == IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC)
{
IX_OSAL_ENSURE ( (IX_OSAL_MBUF_GET_SYS_SIGNATURE(bufPtr) == IX_OSAL_MBUF_SYS_SIGNATURE),
"ixOsalBuffPoolBufFree: ERROR - Invalid mbuf signature.");
}
nextBufPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (bufPtr);
IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (bufPtr) = poolPtr->nextFreeBuf;
poolPtr->nextFreeBuf = bufPtr;
/*
* update the number of free buffers in the pool
*/
poolPtr->freeBufsInPool++;
ixOsalIrqUnlock (lock);
return nextBufPtr;
}
PUBLIC void
ixOsalMbufChainFree (IX_OSAL_MBUF * bufPtr)
{
while ((bufPtr = ixOsalMbufFree (bufPtr)));
}
/*
* Function definition: ixOsalBuffPoolShow
*/
PUBLIC void
ixOsalMbufPoolShow (IX_OSAL_MBUF_POOL * poolPtr)
{
IX_OSAL_MBUF *nextBufPtr;
int count = 0;
int lock;
/*
* check parameters
*/
if (poolPtr == NULL)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
IX_OSAL_LOG_DEV_STDOUT,
"ixOsalBuffPoolShow(): "
"ERROR - Invalid Parameter", 0, 0, 0, 0, 0, 0);
/*
* return IX_FAIL;
*/
return;
}
lock = ixOsalIrqLock ();
count = poolPtr->freeBufsInPool;
nextBufPtr = poolPtr->nextFreeBuf;
ixOsalIrqUnlock (lock);
ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE,
IX_OSAL_LOG_DEV_STDOUT, "=== POOL INFORMATION ===\n", 0, 0, 0,
0, 0, 0);
ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
"Pool Name: %s\n",
(unsigned int) poolPtr->name, 0, 0, 0, 0, 0);
ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
"Pool Allocation Type: %d\n",
(unsigned int) poolPtr->poolAllocType, 0, 0, 0, 0, 0);
ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
"Pool Mbuf Mem Usage (bytes): %d\n",
(unsigned int) poolPtr->mbufMemSize, 0, 0, 0, 0, 0);
ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
"Pool Data Mem Usage (bytes): %d\n",
(unsigned int) poolPtr->dataMemSize, 0, 0, 0, 0, 0);
ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
"Mbuf Data Capacity (bytes): %d\n",
(unsigned int) poolPtr->bufDataSize, 0, 0, 0, 0, 0);
ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
"Total Mbufs in Pool: %d\n",
(unsigned int) poolPtr->totalBufsInPool, 0, 0, 0, 0, 0);
ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
"Available Mbufs: %d\n", (unsigned int) count, 0,
0, 0, 0, 0);
ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
"Next Available Mbuf: %p\n", (unsigned int) nextBufPtr,
0, 0, 0, 0, 0);
if (poolPtr->poolAllocType == IX_OSAL_MBUF_POOL_TYPE_USER_ALLOC)
{
ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE,
IX_OSAL_LOG_DEV_STDOUT,
"Mbuf Mem Area Start address: %p\n",
(unsigned int) poolPtr->mbufMemPtr, 0, 0, 0, 0, 0);
ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
"Data Mem Area Start address: %p\n",
(unsigned int) poolPtr->dataMemPtr, 0, 0, 0, 0, 0);
}
}
PUBLIC void
ixOsalMbufDataPtrReset (IX_OSAL_MBUF * bufPtr)
{
IX_OSAL_MBUF_POOL *poolPtr;
UINT8 *poolDataPtr;
if (bufPtr == NULL)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
"ixOsalBuffPoolBufDataPtrReset"
": ERROR - Invalid Parameter\n", 0, 0, 0, 0, 0, 0);
return;
}
poolPtr = (IX_OSAL_MBUF_POOL *) IX_OSAL_MBUF_NET_POOL (bufPtr);
poolDataPtr = poolPtr->dataMemPtr;
if (poolPtr->poolAllocType == IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC)
{
if (IX_OSAL_MBUF_GET_SYS_SIGNATURE(bufPtr) != IX_OSAL_MBUF_SYS_SIGNATURE)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
"ixOsalBuffPoolBufDataPtrReset"
": invalid mbuf, cannot reset mData pointer\n", 0, 0,
0, 0, 0, 0);
return;
}
IX_OSAL_MBUF_MDATA (bufPtr) = (UINT8*)IX_OSAL_MBUF_ALLOCATED_BUFF_DATA (bufPtr);
}
else
{
if (poolDataPtr)
{
unsigned int bufSize = poolPtr->bufDataSize;
unsigned int bufDataAddr =
(unsigned int) IX_OSAL_MBUF_MDATA (bufPtr);
unsigned int poolDataAddr = (unsigned int) poolDataPtr;
/*
* the pointer is still pointing somewhere in the mbuf payload.
* This operation moves the pointer to the beginning of the
* mbuf payload
*/
bufDataAddr = ((bufDataAddr - poolDataAddr) / bufSize) * bufSize;
IX_OSAL_MBUF_MDATA (bufPtr) = &poolDataPtr[bufDataAddr];
}
else
{
ixOsalLog (IX_OSAL_LOG_LVL_WARNING, IX_OSAL_LOG_DEV_STDOUT,
"ixOsalBuffPoolBufDataPtrReset"
": cannot be used if user supplied NULL pointer for pool data area "
"when pool was created\n", 0, 0, 0, 0, 0, 0);
return;
}
}
}
/*
* Function definition: ixOsalBuffPoolUninit
*/
PUBLIC IX_STATUS
ixOsalBuffPoolUninit (IX_OSAL_MBUF_POOL * pool)
{
if (!pool)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
"ixOsalBuffPoolUninit: NULL ptr \n", 0, 0, 0, 0, 0, 0);
return IX_FAIL;
}
if (pool->freeBufsInPool != pool->totalBufsInPool)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
"ixOsalBuffPoolUninit: need to return all ptrs to the pool first! \n",
0, 0, 0, 0, 0, 0);
return IX_FAIL;
}
if (pool->poolAllocType == IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC)
{
#ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY
UINT32 i;
IX_OSAL_MBUF* pBuf;
pBuf = pool->nextFreeBuf;
/* Freed the Buffer one by one till all the Memory is freed*/
for (i= pool->freeBufsInPool; i >0 && pBuf!=NULL ;i--){
IX_OSAL_MBUF* pBufTemp;
pBufTemp = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(pBuf);
/* Freed MBUF Data Memory area*/
IX_OSAL_CACHE_DMA_FREE( (void *) (IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(pBuf)) );
/* Freed MBUF Struct Memory area*/
IX_OSAL_CACHE_DMA_FREE(pBuf);
pBuf = pBufTemp;
}
#else
IX_OSAL_CACHE_DMA_FREE (pool->mbufMemPtr);
IX_OSAL_CACHE_DMA_FREE (pool->dataMemPtr);
#endif
}
ixOsalBuffFreePools[pool->poolIdx / IX_OSAL_BUFF_FREE_BITS] &=
~(1 << (pool->poolIdx % IX_OSAL_BUFF_FREE_BITS));
ixOsalBuffPoolsInUse--;
return IX_SUCCESS;
}
/*
* Function definition: ixOsalBuffPoolDataAreaSizeGet
*/
PUBLIC UINT32
ixOsalBuffPoolDataAreaSizeGet (int count, int size)
{
UINT32 memorySize;
memorySize = count * IX_OSAL_MBUF_POOL_SIZE_ALIGN (size);
return memorySize;
}
/*
* Function definition: ixOsalBuffPoolMbufAreaSizeGet
*/
PUBLIC UINT32
ixOsalBuffPoolMbufAreaSizeGet (int count)
{
UINT32 memorySize;
memorySize =
count * IX_OSAL_MBUF_POOL_SIZE_ALIGN (sizeof (IX_OSAL_MBUF));
return memorySize;
}
/*
* Function definition: ixOsalBuffPoolFreeCountGet
*/
PUBLIC UINT32 ixOsalBuffPoolFreeCountGet(IX_OSAL_MBUF_POOL * poolPtr)
{
return poolPtr->freeBufsInPool;
}
#endif /* IX_OSAL_USE_DEFAULT_BUFFER_MGT */

332
cpu/ixp/npe/IxOsalIoMem.c Normal file
View file

@ -0,0 +1,332 @@
/**
* @file IxOsalIoMem.c
*
* @brief OS-independent IO/Mem implementation
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
/* Access to the global mem map is only allowed in this file */
#define IxOsalIoMem_C
#include "IxOsal.h"
#define SEARCH_PHYSICAL_ADDRESS (1)
#define SEARCH_VIRTUAL_ADDRESS (2)
/*
* Searches for map using one of the following criteria:
*
* - enough room to include a zone starting with the physical "requestedAddress" of size "size" (for mapping)
* - includes the virtual "requestedAddress" in its virtual address space (already mapped, for unmapping)
* - correct coherency
*
* Returns a pointer to the map or NULL if a suitable map is not found.
*/
PRIVATE IxOsalMemoryMap *
ixOsalMemMapFind (UINT32 requestedAddress,
UINT32 size, UINT32 searchCriteria, UINT32 requestedEndianType)
{
UINT32 mapIndex;
UINT32 numMapElements =
sizeof (ixOsalGlobalMemoryMap) / sizeof (IxOsalMemoryMap);
for (mapIndex = 0; mapIndex < numMapElements; mapIndex++)
{
IxOsalMemoryMap *map = &ixOsalGlobalMemoryMap[mapIndex];
if (searchCriteria == SEARCH_PHYSICAL_ADDRESS
&& requestedAddress >= map->physicalAddress
&& (requestedAddress + size) <= (map->physicalAddress + map->size)
&& (map->mapEndianType & requestedEndianType) != 0)
{
return map;
}
else if (searchCriteria == SEARCH_VIRTUAL_ADDRESS
&& requestedAddress >= map->virtualAddress
&& requestedAddress <= (map->virtualAddress + map->size)
&& (map->mapEndianType & requestedEndianType) != 0)
{
return map;
}
else if (searchCriteria == SEARCH_PHYSICAL_ADDRESS)
{
ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
IX_OSAL_LOG_DEV_STDOUT,
"Osal: Checking [phys addr 0x%x:size 0x%x:endianType %d]\n",
map->physicalAddress, map->size, map->mapEndianType, 0, 0, 0);
}
}
/*
* not found
*/
return NULL;
}
/*
* This function maps an I/O mapped physical memory zone of the given size
* into a virtual memory zone accessible by the caller and returns a cookie -
* the start address of the virtual memory zone.
* IX_OSAL_MMAP_PHYS_TO_VIRT should NOT therefore be used on the returned
* virtual address.
* The memory zone is to be unmapped using ixOsalMemUnmap once the caller has
* finished using this zone (e.g. on driver unload) using the cookie as
* parameter.
* The IX_OSAL_READ/WRITE_LONG/SHORT macros should be used to read and write
* the mapped memory, adding the necessary offsets to the address cookie.
*
* Note: this function is not to be used directly. Use IX_OSAL_MEM_MAP
* instead.
*/
PUBLIC void *
ixOsalIoMemMap (UINT32 requestedAddress,
UINT32 size, IxOsalMapEndianessType requestedEndianType)
{
IxOsalMemoryMap *map;
ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
IX_OSAL_LOG_DEV_STDOUT,
"OSAL: Mapping [addr 0x%x:size 0x%x:endianType %d]\n",
requestedAddress, size, requestedEndianType, 0, 0, 0);
if (requestedEndianType == IX_OSAL_LE)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
IX_OSAL_LOG_DEV_STDOUT,
"ixOsalIoMemMap: Please specify component coherency mode to use MEM functions \n",
0, 0, 0, 0, 0, 0);
return (NULL);
}
map = ixOsalMemMapFind (requestedAddress,
size, SEARCH_PHYSICAL_ADDRESS, requestedEndianType);
if (map != NULL)
{
UINT32 offset = requestedAddress - map->physicalAddress;
ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
IX_OSAL_LOG_DEV_STDOUT, "OSAL: Found map [", 0, 0, 0, 0, 0, 0);
ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
IX_OSAL_LOG_DEV_STDOUT, map->name, 0, 0, 0, 0, 0, 0);
ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
IX_OSAL_LOG_DEV_STDOUT,
":addr 0x%x: virt 0x%x:size 0x%x:ref %d:endianType %d]\n",
map->physicalAddress, map->virtualAddress,
map->size, map->refCount, map->mapEndianType, 0);
if (map->type == IX_OSAL_DYNAMIC_MAP && map->virtualAddress == 0)
{
if (map->mapFunction != NULL)
{
map->mapFunction (map);
if (map->virtualAddress == 0)
{
/*
* failed
*/
ixOsalLog (IX_OSAL_LOG_LVL_FATAL,
IX_OSAL_LOG_DEV_STDERR,
"OSAL: Remap failed - [addr 0x%x:size 0x%x:endianType %d]\n",
requestedAddress, size, requestedEndianType, 0, 0, 0);
return NULL;
}
}
else
{
/*
* error, no map function for a dynamic map
*/
ixOsalLog (IX_OSAL_LOG_LVL_FATAL,
IX_OSAL_LOG_DEV_STDERR,
"OSAL: No map function for a dynamic map - "
"[addr 0x%x:size 0x%x:endianType %d]\n",
requestedAddress, size, requestedEndianType, 0, 0, 0);
return NULL;
}
}
/*
* increment reference count
*/
map->refCount++;
return (void *) (map->virtualAddress + offset);
}
/*
* requested address is not described in the global memory map
*/
ixOsalLog (IX_OSAL_LOG_LVL_FATAL,
IX_OSAL_LOG_DEV_STDERR,
"OSAL: No mapping found - [addr 0x%x:size 0x%x:endianType %d]\n",
requestedAddress, size, requestedEndianType, 0, 0, 0);
return NULL;
}
/*
* This function unmaps a previously mapped I/O memory zone using
* the cookie obtained in the mapping operation. The memory zone in question
* becomes unavailable to the caller once unmapped and the cookie should be
* discarded.
*
* This function cannot fail if the given parameter is correct and does not
* return a value.
*
* Note: this function is not to be used directly. Use IX_OSAL_MEM_UNMAP
* instead.
*/
PUBLIC void
ixOsalIoMemUnmap (UINT32 requestedAddress, UINT32 endianType)
{
IxOsalMemoryMap *map;
if (endianType == IX_OSAL_LE)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
IX_OSAL_LOG_DEV_STDOUT,
"ixOsalIoMemUnmap: Please specify component coherency mode to use MEM functions \n",
0, 0, 0, 0, 0, 0);
return;
}
if (requestedAddress == 0)
{
/*
* invalid virtual address
*/
return;
}
map =
ixOsalMemMapFind (requestedAddress, 0, SEARCH_VIRTUAL_ADDRESS,
endianType);
if (map != NULL)
{
if (map->refCount > 0)
{
/*
* decrement reference count
*/
map->refCount--;
if (map->refCount == 0)
{
/*
* no longer used, deallocate
*/
if (map->type == IX_OSAL_DYNAMIC_MAP
&& map->unmapFunction != NULL)
{
map->unmapFunction (map);
}
}
}
}
else
{
ixOsalLog (IX_OSAL_LOG_LVL_WARNING,
IX_OSAL_LOG_DEV_STDERR,
"OSAL: ixOsServMemUnmap didn't find the requested map "
"[virt addr 0x%x: endianType %d], ignoring call\n",
requestedAddress, endianType, 0, 0, 0, 0);
}
}
/*
* This function Converts a virtual address into a physical
* address, including the dynamically mapped memory.
*
* Parameters virtAddr - virtual address to convert
* Return value: corresponding physical address, or NULL
* if there is no physical address addressable
* by the given virtual address
* OS: VxWorks, Linux, WinCE, QNX, eCos
* Reentrant: Yes
* IRQ safe: Yes
*/
PUBLIC UINT32
ixOsalIoMemVirtToPhys (UINT32 virtualAddress, UINT32 requestedCoherency)
{
IxOsalMemoryMap *map =
ixOsalMemMapFind (virtualAddress, 0, SEARCH_VIRTUAL_ADDRESS,
requestedCoherency);
if (map != NULL)
{
return map->physicalAddress + virtualAddress - map->virtualAddress;
}
else
{
return (UINT32) IX_OSAL_MMU_VIRT_TO_PHYS (virtualAddress);
}
}
/*
* This function Converts a virtual address into a physical
* address, including the dynamically mapped memory.
*
* Parameters virtAddr - virtual address to convert
* Return value: corresponding physical address, or NULL
* if there is no physical address addressable
* by the given virtual address
* OS: VxWorks, Linux, WinCE, QNX, eCos
* Reentrant: Yes
* IRQ safe: Yes
*/
PUBLIC UINT32
ixOsalIoMemPhysToVirt (UINT32 physicalAddress, UINT32 requestedCoherency)
{
IxOsalMemoryMap *map =
ixOsalMemMapFind (physicalAddress, 0, SEARCH_PHYSICAL_ADDRESS,
requestedCoherency);
if (map != NULL)
{
return map->virtualAddress + physicalAddress - map->physicalAddress;
}
else
{
return (UINT32) IX_OSAL_MMU_PHYS_TO_VIRT (physicalAddress);
}
}

View file

@ -0,0 +1,67 @@
/**
* @file IxOsalOsCacheMMU.c (linux)
*
* @brief Cache MemAlloc and MemFree.
*
*
* @par
* IXP400 SW Release version 1.5
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#include "IxOsal.h"
#include <malloc.h>
/*
* Allocate on a cache line boundary (null pointers are
* not affected by this operation). This operation is NOT cache safe.
*/
void *
ixOsalCacheDmaMalloc (UINT32 n)
{
return malloc(n);
}
/*
*
*/
void
ixOsalCacheDmaFree (void *ptr)
{
free(ptr);
}

View file

@ -0,0 +1,79 @@
/**
* @file IxOsalOsMsgQ.c (eCos)
*
* @brief OS-specific Message Queue implementation.
*
*
* @par
* IXP400 SW Release version 1.5
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#include "IxOsal.h"
/*******************************
* Public functions
*******************************/
PUBLIC IX_STATUS
ixOsalMessageQueueCreate (IxOsalMessageQueue * queue,
UINT32 msgCount, UINT32 msgLen)
{
diag_printf("%s called\n", __FUNCTION__);
return IX_FAIL;
}
PUBLIC IX_STATUS
ixOsalMessageQueueDelete (IxOsalMessageQueue * queue)
{
diag_printf("%s called\n", __FUNCTION__);
return IX_FAIL;
}
PUBLIC IX_STATUS
ixOsalMessageQueueSend (IxOsalMessageQueue * queue, UINT8 * message)
{
diag_printf("%s called\n", __FUNCTION__);
return IX_FAIL;
}
PUBLIC IX_STATUS
ixOsalMessageQueueReceive (IxOsalMessageQueue * queue, UINT8 * message)
{
diag_printf("%s called\n", __FUNCTION__);
return IX_FAIL;
}

View file

@ -0,0 +1,233 @@
/**
* @file IxOsalOsSemaphore.c (eCos)
*
* @brief Implementation for semaphore and mutex.
*
*
* @par
* IXP400 SW Release version 1.5
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#include "IxOsal.h"
#include "IxNpeMhReceive_p.h"
/* Define a large number */
#define IX_OSAL_MAX_LONG (0x7FFFFFFF)
/* Max timeout in MS, used to guard against possible overflow */
#define IX_OSAL_MAX_TIMEOUT_MS (IX_OSAL_MAX_LONG/HZ)
PUBLIC IX_STATUS
ixOsalSemaphoreInit (IxOsalSemaphore * sid, UINT32 start_value)
{
diag_printf("%s called\n", __FUNCTION__);
return IX_SUCCESS;
}
/**
* DESCRIPTION: If the semaphore is 'empty', the calling thread is blocked.
* If the semaphore is 'full', it is taken and control is returned
* to the caller. If the time indicated in 'timeout' is reached,
* the thread will unblock and return an error indication. If the
* timeout is set to 'IX_OSAL_WAIT_NONE', the thread will never block;
* if it is set to 'IX_OSAL_WAIT_FOREVER', the thread will block until
* the semaphore is available.
*
*
*/
PUBLIC IX_STATUS
ixOsalSemaphoreWait (IxOsalOsSemaphore * sid, INT32 timeout)
{
diag_printf("%s called\n", __FUNCTION__);
return IX_SUCCESS;
}
/*
* Attempt to get semaphore, return immediately,
* no error info because users expect some failures
* when using this API.
*/
PUBLIC IX_STATUS
ixOsalSemaphoreTryWait (IxOsalSemaphore * sid)
{
diag_printf("%s called\n", __FUNCTION__);
return IX_FAIL;
}
/**
*
* DESCRIPTION: This function causes the next available thread in the pend queue
* to be unblocked. If no thread is pending on this semaphore, the
* semaphore becomes 'full'.
*/
PUBLIC IX_STATUS
ixOsalSemaphorePost (IxOsalSemaphore * sid)
{
diag_printf("%s called\n", __FUNCTION__);
return IX_SUCCESS;
}
PUBLIC IX_STATUS
ixOsalSemaphoreGetValue (IxOsalSemaphore * sid, UINT32 * value)
{
diag_printf("%s called\n", __FUNCTION__);
return IX_FAIL;
}
PUBLIC IX_STATUS
ixOsalSemaphoreDestroy (IxOsalSemaphore * sid)
{
diag_printf("%s called\n", __FUNCTION__);
return IX_FAIL;
}
/****************************
* Mutex
****************************/
static void drv_mutex_init(IxOsalMutex *mutex)
{
*mutex = 0;
}
static void drv_mutex_destroy(IxOsalMutex *mutex)
{
*mutex = -1;
}
static int drv_mutex_trylock(IxOsalMutex *mutex)
{
int result = TRUE;
if (*mutex == 1)
result = FALSE;
return result;
}
static void drv_mutex_unlock(IxOsalMutex *mutex)
{
if (*mutex == 1)
printf("Trying to unlock unlocked mutex!");
*mutex = 0;
}
PUBLIC IX_STATUS
ixOsalMutexInit (IxOsalMutex * mutex)
{
drv_mutex_init(mutex);
return IX_SUCCESS;
}
PUBLIC IX_STATUS
ixOsalMutexLock (IxOsalMutex * mutex, INT32 timeout)
{
int tries;
if (timeout == IX_OSAL_WAIT_NONE) {
if (drv_mutex_trylock(mutex))
return IX_SUCCESS;
else
return IX_FAIL;
}
tries = (timeout * 1000) / 50;
while (1) {
if (drv_mutex_trylock(mutex))
return IX_SUCCESS;
if (timeout != IX_OSAL_WAIT_FOREVER && tries-- <= 0)
break;
udelay(50);
}
return IX_FAIL;
}
PUBLIC IX_STATUS
ixOsalMutexUnlock (IxOsalMutex * mutex)
{
drv_mutex_unlock(mutex);
return IX_SUCCESS;
}
/*
* Attempt to get mutex, return immediately,
* no error info because users expect some failures
* when using this API.
*/
PUBLIC IX_STATUS
ixOsalMutexTryLock (IxOsalMutex * mutex)
{
if (drv_mutex_trylock(mutex))
return IX_SUCCESS;
return IX_FAIL;
}
PUBLIC IX_STATUS
ixOsalMutexDestroy (IxOsalMutex * mutex)
{
drv_mutex_destroy(mutex);
return IX_SUCCESS;
}
PUBLIC IX_STATUS
ixOsalFastMutexInit (IxOsalFastMutex * mutex)
{
return ixOsalMutexInit(mutex);
}
PUBLIC IX_STATUS ixOsalFastMutexTryLock(IxOsalFastMutex *mutex)
{
return ixOsalMutexTryLock(mutex);
}
PUBLIC IX_STATUS
ixOsalFastMutexUnlock (IxOsalFastMutex * mutex)
{
return ixOsalMutexUnlock(mutex);
}
PUBLIC IX_STATUS
ixOsalFastMutexDestroy (IxOsalFastMutex * mutex)
{
return ixOsalMutexDestroy(mutex);
}

View file

@ -0,0 +1,251 @@
/**
* @file IxOsalOsServices.c (linux)
*
* @brief Implementation for Irq, Mem, sleep.
*
*
* @par
* IXP400 SW Release version 1.5
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#include <config.h>
#include <common.h>
#include "IxOsal.h"
#include <IxEthAcc.h>
#include <IxEthDB.h>
#include <IxNpeDl.h>
#include <IxQMgr.h>
#include <IxNpeMh.h>
static char *traceHeaders[] = {
"",
"[fatal] ",
"[error] ",
"[warning] ",
"[message] ",
"[debug1] ",
"[debug2] ",
"[debug3] ",
"[all]"
};
/* by default trace all but debug message */
PRIVATE int ixOsalCurrLogLevel = IX_OSAL_LOG_LVL_MESSAGE;
/**************************************
* Irq services
*************************************/
PUBLIC IX_STATUS
ixOsalIrqBind (UINT32 vector, IxOsalVoidFnVoidPtr routine, void *parameter)
{
return IX_FAIL;
}
PUBLIC IX_STATUS
ixOsalIrqUnbind (UINT32 vector)
{
return IX_FAIL;
}
PUBLIC UINT32
ixOsalIrqLock ()
{
return 0;
}
/* Enable interrupts and task scheduling,
* input parameter: irqEnable status returned
* by ixOsalIrqLock().
*/
PUBLIC void
ixOsalIrqUnlock (UINT32 lockKey)
{
}
PUBLIC UINT32
ixOsalIrqLevelSet (UINT32 level)
{
return IX_FAIL;
}
PUBLIC void
ixOsalIrqEnable (UINT32 irqLevel)
{
}
PUBLIC void
ixOsalIrqDisable (UINT32 irqLevel)
{
}
/*********************
* Log function
*********************/
INT32
ixOsalLog (IxOsalLogLevel level,
IxOsalLogDevice device,
char *format, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6)
{
/*
* Return -1 for custom display devices
*/
if ((device != IX_OSAL_LOG_DEV_STDOUT)
&& (device != IX_OSAL_LOG_DEV_STDERR))
{
debug("ixOsalLog: only IX_OSAL_LOG_DEV_STDOUT and IX_OSAL_LOG_DEV_STDERR are supported \n");
return (IX_OSAL_LOG_ERROR);
}
if (level <= ixOsalCurrLogLevel && level != IX_OSAL_LOG_LVL_NONE)
{
#if 0 /* sr: U-Boots printf or debug doesn't return a length */
int headerByteCount = (level == IX_OSAL_LOG_LVL_USER) ? 0 : diag_printf(traceHeaders[level - 1]);
return headerByteCount + diag_printf (format, arg1, arg2, arg3, arg4, arg5, arg6);
#else
int headerByteCount = (level == IX_OSAL_LOG_LVL_USER) ? 0 : strlen(traceHeaders[level - 1]);
return headerByteCount + strlen(format);
#endif
}
else
{
/*
* Return error
*/
return (IX_OSAL_LOG_ERROR);
}
}
PUBLIC UINT32
ixOsalLogLevelSet (UINT32 level)
{
UINT32 oldLevel;
/*
* Check value first
*/
if ((level < IX_OSAL_LOG_LVL_NONE) || (level > IX_OSAL_LOG_LVL_ALL))
{
ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE,
IX_OSAL_LOG_DEV_STDOUT,
"ixOsalLogLevelSet: Log Level is between %d and%d \n",
IX_OSAL_LOG_LVL_NONE, IX_OSAL_LOG_LVL_ALL, 0, 0, 0, 0);
return IX_OSAL_LOG_LVL_NONE;
}
oldLevel = ixOsalCurrLogLevel;
ixOsalCurrLogLevel = level;
return oldLevel;
}
/**************************************
* Task services
*************************************/
PUBLIC void
ixOsalBusySleep (UINT32 microseconds)
{
udelay(microseconds);
}
PUBLIC void
ixOsalSleep (UINT32 milliseconds)
{
if (milliseconds != 0) {
#if 1
/*
* sr: We poll while we wait because interrupts are off in U-Boot
* and CSR expects messages, etc to be dispatched while sleeping.
*/
int i;
IxQMgrDispatcherFuncPtr qDispatcherFunc;
ixQMgrDispatcherLoopGet(&qDispatcherFunc);
while (milliseconds--) {
for (i = 1; i <= 2; i++)
ixNpeMhMessagesReceive(i);
(*qDispatcherFunc)(IX_QMGR_QUELOW_GROUP);
udelay(1000);
}
#endif
}
}
/**************************************
* Memory functions
*************************************/
void *
ixOsalMemAlloc (UINT32 size)
{
return (void *)0;
}
void
ixOsalMemFree (void *ptr)
{
}
/*
* Copy count bytes from src to dest ,
* returns pointer to the dest mem zone.
*/
void *
ixOsalMemCopy (void *dest, void *src, UINT32 count)
{
IX_OSAL_ASSERT (dest != NULL);
IX_OSAL_ASSERT (src != NULL);
return (memcpy (dest, src, count));
}
/*
* Fills a memory zone with a given constant byte,
* returns pointer to the memory zone.
*/
void *
ixOsalMemSet (void *ptr, UINT8 filler, UINT32 count)
{
IX_OSAL_ASSERT (ptr != NULL);
return (memset (ptr, filler, count));
}

View file

@ -0,0 +1,98 @@
/**
* @file IxOsalOsThread.c (eCos)
*
* @brief OS-specific thread implementation.
*
*
* @par
* IXP400 SW Release version 1.5
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#include "IxOsal.h"
/* Thread attribute is ignored */
PUBLIC IX_STATUS
ixOsalThreadCreate (IxOsalThread * ptrTid,
IxOsalThreadAttr * threadAttr, IxOsalVoidFnVoidPtr entryPoint, void *arg)
{
return IX_SUCCESS;
}
/*
* Start thread after given its thread handle
*/
PUBLIC IX_STATUS
ixOsalThreadStart (IxOsalThread * tId)
{
/* Thread already started upon creation */
return IX_SUCCESS;
}
/*
* In Linux threadKill does not actually destroy the thread,
* it will stop the signal handling.
*/
PUBLIC IX_STATUS
ixOsalThreadKill (IxOsalThread * tid)
{
return IX_SUCCESS;
}
PUBLIC void
ixOsalThreadExit (void)
{
}
PUBLIC IX_STATUS
ixOsalThreadPrioritySet (IxOsalOsThread * tid, UINT32 priority)
{
return IX_SUCCESS;
}
PUBLIC IX_STATUS
ixOsalThreadSuspend (IxOsalThread * tId)
{
return IX_SUCCESS;
}
PUBLIC IX_STATUS
ixOsalThreadResume (IxOsalThread * tId)
{
return IX_SUCCESS;
}

963
cpu/ixp/npe/IxQMgrAqmIf.c Normal file
View file

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

File diff suppressed because it is too large Load diff

233
cpu/ixp/npe/IxQMgrInit.c Normal file
View file

@ -0,0 +1,233 @@
/**
* @file IxQMgrInit.c
*
* @author Intel Corporation
* @date 30-Oct-2001
*
* @brief: Provided initialization of the QMgr component and its subcomponents.
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
/*
* System defined include files.
*/
/*
* User defined include files.
*/
#include "IxOsal.h"
#include "IxQMgr.h"
#include "IxQMgrQCfg_p.h"
#include "IxQMgrDispatcher_p.h"
#include "IxQMgrLog_p.h"
#include "IxQMgrQAccess_p.h"
#include "IxQMgrDefines_p.h"
#include "IxQMgrAqmIf_p.h"
/*
* Set to true if initialized
* N.B. global so integration/unit tests can reinitialize
*/
BOOL qMgrIsInitialized = FALSE;
/*
* Function definitions.
*/
IX_STATUS
ixQMgrInit (void)
{
if (qMgrIsInitialized)
{
IX_QMGR_LOG0("ixQMgrInit: IxQMgr already initialised\n");
return IX_FAIL;
}
/* Initialise the QCfg component */
ixQMgrQCfgInit ();
/* Initialise the Dispatcher component */
ixQMgrDispatcherInit ();
/* Initialise the Access component */
ixQMgrQAccessInit ();
/* Initialization complete */
qMgrIsInitialized = TRUE;
return IX_SUCCESS;
}
IX_STATUS
ixQMgrUnload (void)
{
if (!qMgrIsInitialized)
{
return IX_FAIL;
}
/* Uninitialise the QCfg component */
ixQMgrQCfgUninit ();
/* Uninitialization complete */
qMgrIsInitialized = FALSE;
return IX_SUCCESS;
}
void
ixQMgrShow (void)
{
IxQMgrQCfgStats *qCfgStats = NULL;
IxQMgrDispatcherStats *dispatcherStats = NULL;
int i;
UINT32 lowIntRegRead, upIntRegRead;
qCfgStats = ixQMgrQCfgStatsGet ();
dispatcherStats = ixQMgrDispatcherStatsGet ();
ixQMgrAqmIfQInterruptRegRead (IX_QMGR_QUELOW_GROUP, &lowIntRegRead);
ixQMgrAqmIfQInterruptRegRead (IX_QMGR_QUEUPP_GROUP, &upIntRegRead);
printf("Generic Stats........\n");
printf("=====================\n");
printf("Loop Run Count..........%u\n",dispatcherStats->loopRunCnt);
printf("Watermark set count.....%d\n", qCfgStats->wmSetCnt);
printf("===========================================\n");
printf("On the fly Interrupt Register Stats........\n");
printf("===========================================\n");
printf("Lower Interrupt Register............0x%08x\n",lowIntRegRead);
printf("Upper Interrupt Register............0x%08x\n",upIntRegRead);
printf("==============================================\n");
printf("Queue Specific Stats........\n");
printf("============================\n");
for (i=0; i<IX_QMGR_MAX_NUM_QUEUES; i++)
{
if (ixQMgrQIsConfigured(i))
{
ixQMgrQShow(i);
}
}
printf("============================\n");
}
IX_STATUS
ixQMgrQShow (IxQMgrQId qId)
{
IxQMgrQCfgStats *qCfgStats = NULL;
IxQMgrDispatcherStats *dispatcherStats = NULL;
if (!ixQMgrQIsConfigured(qId))
{
return IX_QMGR_Q_NOT_CONFIGURED;
}
dispatcherStats = ixQMgrDispatcherStatsGet ();
qCfgStats = ixQMgrQCfgQStatsGet (qId);
printf("QId %d\n", qId);
printf("======\n");
printf(" IxQMgrQCfg Stats\n");
printf(" Name..................... \"%s\"\n", qCfgStats->qStats[qId].qName);
printf(" Size in words............ %u\n", qCfgStats->qStats[qId].qSizeInWords);
printf(" Entry size in words...... %u\n", qCfgStats->qStats[qId].qEntrySizeInWords);
printf(" Nearly empty watermark... %u\n", qCfgStats->qStats[qId].ne);
printf(" Nearly full watermark.... %u\n", qCfgStats->qStats[qId].nf);
printf(" Number of full entries... %u\n", qCfgStats->qStats[qId].numEntries);
printf(" Sram base address........ 0x%X\n", qCfgStats->qStats[qId].baseAddress);
printf(" Read pointer............. 0x%X\n", qCfgStats->qStats[qId].readPtr);
printf(" Write pointer............ 0x%X\n", qCfgStats->qStats[qId].writePtr);
#ifndef NDEBUG
if (dispatcherStats->queueStats[qId].notificationEnabled)
{
char *localEvent = "none ????";
switch (dispatcherStats->queueStats[qId].srcSel)
{
case IX_QMGR_Q_SOURCE_ID_E:
localEvent = "Empty";
break;
case IX_QMGR_Q_SOURCE_ID_NE:
localEvent = "Nearly Empty";
break;
case IX_QMGR_Q_SOURCE_ID_NF:
localEvent = "Nearly Full";
break;
case IX_QMGR_Q_SOURCE_ID_F:
localEvent = "Full";
break;
case IX_QMGR_Q_SOURCE_ID_NOT_E:
localEvent = "Not Empty";
break;
case IX_QMGR_Q_SOURCE_ID_NOT_NE:
localEvent = "Not Nearly Empty";
break;
case IX_QMGR_Q_SOURCE_ID_NOT_NF:
localEvent = "Not Nearly Full";
break;
case IX_QMGR_Q_SOURCE_ID_NOT_F:
localEvent = "Not Full";
break;
default :
break;
}
printf(" Notifications localEvent...... %s\n", localEvent);
}
else
{
printf(" Notifications............ not enabled\n");
}
printf(" IxQMgrDispatcher Stats\n");
printf(" Callback count................%d\n",
dispatcherStats->queueStats[qId].callbackCnt);
printf(" Priority change count.........%d\n",
dispatcherStats->queueStats[qId].priorityChangeCnt);
printf(" Interrupt no callback count...%d\n",
dispatcherStats->queueStats[qId].intNoCallbackCnt);
printf(" Interrupt lost callback count...%d\n",
dispatcherStats->queueStats[qId].intLostCallbackCnt);
#endif
return IX_SUCCESS;
}

796
cpu/ixp/npe/IxQMgrQAccess.c Normal file
View file

@ -0,0 +1,796 @@
/**
* @file IxQMgrQAccess.c
*
* @author Intel Corporation
* @date 30-Oct-2001
*
* @brief This file contains functions for putting entries on a queue and
* removing entries from a queue.
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
/*
* Inlines are compiled as function when this is defined.
* N.B. Must be placed before #include of "IxQMgr.h"
*/
#ifndef IXQMGR_H
# define IXQMGRQACCESS_C
#else
# error
#endif
/*
* System defined include files.
*/
/*
* User defined include files.
*/
#include "IxQMgr.h"
#include "IxQMgrAqmIf_p.h"
#include "IxQMgrQAccess_p.h"
#include "IxQMgrQCfg_p.h"
#include "IxQMgrDefines_p.h"
/*
* Global variables and extern definitions
*/
extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
/*
* Function definitions.
*/
void
ixQMgrQAccessInit (void)
{
}
IX_STATUS
ixQMgrQReadWithChecks (IxQMgrQId qId,
UINT32 *entry)
{
IxQMgrQEntrySizeInWords entrySizeInWords;
IxQMgrQInlinedReadWriteInfo *infoPtr;
if (NULL == entry)
{
return IX_QMGR_PARAMETER_ERROR;
}
/* Check QId */
if (!ixQMgrQIsConfigured(qId))
{
return IX_QMGR_Q_NOT_CONFIGURED;
}
/* Get the q entry size in words */
entrySizeInWords = ixQMgrQEntrySizeInWordsGet (qId);
ixQMgrAqmIfQPop (qId, entrySizeInWords, entry);
/* reset the current read count if the counter wrapped around
* (unsigned arithmetic)
*/
infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
if (infoPtr->qReadCount-- > infoPtr->qSizeInEntries)
{
infoPtr->qReadCount = 0;
}
/* Check if underflow occurred on the read */
if (ixQMgrAqmIfUnderflowCheck (qId))
{
return IX_QMGR_Q_UNDERFLOW;
}
return IX_SUCCESS;
}
/* this function reads the remaining of the q entry
* for queues configured with many words.
* (the first word of the entry is already read
* in the inlined function and the entry pointer already
* incremented
*/
IX_STATUS
ixQMgrQReadMWordsMinus1 (IxQMgrQId qId,
UINT32 *entry)
{
IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
UINT32 entrySize = infoPtr->qEntrySizeInWords;
volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
while (--entrySize)
{
/* read the entry and accumulate the result */
*(++entry) = IX_OSAL_READ_LONG(++qAccRegAddr);
}
/* underflow is available for lower queues only */
if (qId < IX_QMGR_MIN_QUEUPP_QID)
{
/* get the queue status */
UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);
/* check the underflow status */
if (status & infoPtr->qUflowStatBitMask)
{
/* the queue is empty
* clear the underflow status bit if it was set
*/
IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
status & ~infoPtr->qUflowStatBitMask);
return IX_QMGR_Q_UNDERFLOW;
}
}
return IX_SUCCESS;
}
IX_STATUS
ixQMgrQWriteWithChecks (IxQMgrQId qId,
UINT32 *entry)
{
IxQMgrQEntrySizeInWords entrySizeInWords;
IxQMgrQInlinedReadWriteInfo *infoPtr;
if (NULL == entry)
{
return IX_QMGR_PARAMETER_ERROR;
}
/* Check QId */
if (!ixQMgrQIsConfigured(qId))
{
return IX_QMGR_Q_NOT_CONFIGURED;
}
/* Get the q entry size in words */
entrySizeInWords = ixQMgrQEntrySizeInWordsGet (qId);
ixQMgrAqmIfQPush (qId, entrySizeInWords, entry);
/* reset the current read count if the counter wrapped around
* (unsigned arithmetic)
*/
infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
if (infoPtr->qWriteCount++ >= infoPtr->qSizeInEntries)
{
infoPtr->qWriteCount = infoPtr->qSizeInEntries;
}
/* Check if overflow occurred on the write*/
if (ixQMgrAqmIfOverflowCheck (qId))
{
return IX_QMGR_Q_OVERFLOW;
}
return IX_SUCCESS;
}
IX_STATUS
ixQMgrQPeek (IxQMgrQId qId,
unsigned int entryIndex,
UINT32 *entry)
{
unsigned int numEntries;
#ifndef NDEBUG
if ((NULL == entry) || (entryIndex >= IX_QMGR_Q_SIZE_INVALID))
{
return IX_QMGR_PARAMETER_ERROR;
}
if (!ixQMgrQIsConfigured(qId))
{
return IX_QMGR_Q_NOT_CONFIGURED;
}
#endif
if (IX_SUCCESS != ixQMgrQNumEntriesGet (qId, &numEntries))
{
return IX_FAIL;
}
if (entryIndex >= numEntries) /* entryIndex starts at 0 */
{
return IX_QMGR_ENTRY_INDEX_OUT_OF_BOUNDS;
}
return ixQMgrAqmIfQPeek (qId, entryIndex, entry);
}
IX_STATUS
ixQMgrQPoke (IxQMgrQId qId,
unsigned entryIndex,
UINT32 *entry)
{
unsigned int numEntries;
#ifndef NDEBUG
if ((NULL == entry) || (entryIndex > 128))
{
return IX_QMGR_PARAMETER_ERROR;
}
if (!ixQMgrQIsConfigured(qId))
{
return IX_QMGR_Q_NOT_CONFIGURED;
}
#endif
if (IX_SUCCESS != ixQMgrQNumEntriesGet (qId, &numEntries))
{
return IX_FAIL;
}
if (numEntries < (entryIndex + 1)) /* entryIndex starts at 0 */
{
return IX_QMGR_ENTRY_INDEX_OUT_OF_BOUNDS;
}
return ixQMgrAqmIfQPoke (qId, entryIndex, entry);
}
IX_STATUS
ixQMgrQStatusGetWithChecks (IxQMgrQId qId,
IxQMgrQStatus *qStatus)
{
if (NULL == qStatus)
{
return IX_QMGR_PARAMETER_ERROR;
}
if (!ixQMgrQIsConfigured (qId))
{
return IX_QMGR_Q_NOT_CONFIGURED;
}
ixQMgrAqmIfQueStatRead (qId, qStatus);
return IX_SUCCESS;
}
IX_STATUS
ixQMgrQNumEntriesGet (IxQMgrQId qId,
unsigned *numEntriesPtr)
{
UINT32 qPtrs;
UINT32 qStatus;
unsigned numEntries;
IxQMgrQInlinedReadWriteInfo *infoPtr;
#ifndef NDEBUG
if (NULL == numEntriesPtr)
{
return IX_QMGR_PARAMETER_ERROR;
}
/* Check QId */
if (!ixQMgrQIsConfigured(qId))
{
return IX_QMGR_Q_NOT_CONFIGURED;
}
#endif
/* get fast access data */
infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
/* get snapshot */
qPtrs = IX_OSAL_READ_LONG(infoPtr->qConfigRegAddr);
/* Mod subtraction of pointers to get number of words in Q. */
numEntries = (qPtrs - (qPtrs >> 7)) & 0x7f;
if (numEntries == 0)
{
/*
* Could mean either full or empty queue
* so look at status
*/
ixQMgrAqmIfQueStatRead (qId, &qStatus);
if (qId < IX_QMGR_MIN_QUEUPP_QID)
{
if (qStatus & IX_QMGR_Q_STATUS_E_BIT_MASK)
{
/* Empty */
*numEntriesPtr = 0;
}
else if (qStatus & IX_QMGR_Q_STATUS_F_BIT_MASK)
{
/* Full */
*numEntriesPtr = infoPtr->qSizeInEntries;
}
else
{
/*
* Queue status and read/write pointers are volatile.
* The queue state has changed since we took the
* snapshot of the read and write pointers.
* Client can retry if they wish
*/
*numEntriesPtr = 0;
return IX_QMGR_WARNING;
}
}
else /* It is an upper queue which does not have an empty status bit maintained */
{
if (qStatus & IX_QMGR_Q_STATUS_F_BIT_MASK)
{
/* The queue is Full at the time of snapshot. */
*numEntriesPtr = infoPtr->qSizeInEntries;
}
else
{
/* The queue is either empty, either moving,
* Client can retry if they wish
*/
*numEntriesPtr = 0;
return IX_QMGR_WARNING;
}
}
}
else
{
*numEntriesPtr = (numEntries / infoPtr->qEntrySizeInWords) & (infoPtr->qSizeInEntries - 1);
}
return IX_SUCCESS;
}
#if defined(__wince) && defined(NO_INLINE_APIS)
PUBLIC IX_STATUS
ixQMgrQRead (IxQMgrQId qId,
UINT32 *entryPtr)
{
extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
UINT32 entry, entrySize;
/* get a new entry */
entrySize = infoPtr->qEntrySizeInWords;
entry = IX_OSAL_READ_LONG(infoPtr->qAccRegAddr);
if (entrySize != IX_QMGR_Q_ENTRY_SIZE1)
{
*entryPtr = entry;
/* process the remaining part of the entry */
return ixQMgrQReadMWordsMinus1(qId, entryPtr);
}
/* underflow is available for lower queues only */
if (qId < IX_QMGR_MIN_QUEUPP_QID)
{
/* the counter of queue entries is decremented. In happy
* day scenario there are many entries in the queue
* and the counter does not reach zero.
*/
if (infoPtr->qReadCount-- == 0)
{
/* There is maybe no entry in the queue
* qReadCount is now negative, but will be corrected before
* the function returns.
*/
UINT32 qPtrs; /* queue internal pointers */
/* when a queue is empty, the hw guarantees to return
* a null value. If the value is not null, the queue is
* not empty.
*/
if (entry == 0)
{
/* get the queue status */
UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);
/* check the underflow status */
if (status & infoPtr->qUflowStatBitMask)
{
/* the queue is empty
* clear the underflow status bit if it was set
*/
IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
status & ~infoPtr->qUflowStatBitMask);
*entryPtr = 0;
infoPtr->qReadCount = 0;
return IX_QMGR_Q_UNDERFLOW;
}
}
/* store the result */
*entryPtr = entry;
/* No underflow occured : someone is filling the queue
* or the queue contains null entries.
* The current counter needs to be
* updated from the current number of entries in the queue
*/
/* get snapshot of queue pointers */
qPtrs = IX_OSAL_READ_LONG(infoPtr->qConfigRegAddr);
/* Mod subtraction of pointers to get number of words in Q. */
qPtrs = (qPtrs - (qPtrs >> 7)) & 0x7f;
if (qPtrs == 0)
{
/* no entry in the queue */
infoPtr->qReadCount = 0;
}
else
{
/* convert the number of words inside the queue
* to a number of entries
*/
infoPtr->qReadCount = qPtrs & (infoPtr->qSizeInEntries - 1);
}
return IX_SUCCESS;
}
}
*entryPtr = entry;
return IX_SUCCESS;
}
PUBLIC IX_STATUS
ixQMgrQBurstRead (IxQMgrQId qId,
UINT32 numEntries,
UINT32 *entries)
{
extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
UINT32 nullCheckEntry;
if (infoPtr->qEntrySizeInWords == IX_QMGR_Q_ENTRY_SIZE1)
{
volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
/* the code is optimized to take care of data dependencies:
* Durig a read, there are a few cycles needed to get the
* read complete. During these cycles, it is poossible to
* do some CPU, e.g. increment pointers and decrement
* counters.
*/
/* fetch a queue entry */
nullCheckEntry = IX_OSAL_READ_LONG(infoPtr->qAccRegAddr);
/* iterate the specified number of queue entries */
while (--numEntries)
{
/* check the result of the previous read */
if (nullCheckEntry == 0)
{
/* if we read a NULL entry, stop. We have underflowed */
break;
}
else
{
/* write the entry */
*entries = nullCheckEntry;
/* fetch next entry */
nullCheckEntry = IX_OSAL_READ_LONG(qAccRegAddr);
/* increment the write address */
entries++;
}
}
/* write the pre-fetched entry */
*entries = nullCheckEntry;
}
else
{
IxQMgrQEntrySizeInWords entrySizeInWords = infoPtr->qEntrySizeInWords;
/* read the specified number of queue entries */
nullCheckEntry = 0;
while (numEntries--)
{
int i;
for (i = 0; i < entrySizeInWords; i++)
{
*entries = IX_OSAL_READ_LONG(infoPtr->qAccRegAddr + i);
nullCheckEntry |= *entries++;
}
/* if we read a NULL entry, stop. We have underflowed */
if (nullCheckEntry == 0)
{
break;
}
nullCheckEntry = 0;
}
}
/* reset the current read count : next access to the read function
* will force a underflow status check
*/
infoPtr->qWriteCount = 0;
/* Check if underflow occurred on the read */
if (nullCheckEntry == 0 && qId < IX_QMGR_MIN_QUEUPP_QID)
{
/* get the queue status */
UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);
if (status & infoPtr->qUflowStatBitMask)
{
/* clear the underflow status bit if it was set */
IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
status & ~infoPtr->qUflowStatBitMask);
return IX_QMGR_Q_UNDERFLOW;
}
}
return IX_SUCCESS;
}
PUBLIC IX_STATUS
ixQMgrQWrite (IxQMgrQId qId,
UINT32 *entry)
{
extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
UINT32 entrySize;
/* write the entry */
IX_OSAL_WRITE_LONG(infoPtr->qAccRegAddr, *entry);
entrySize = infoPtr->qEntrySizeInWords;
if (entrySize != IX_QMGR_Q_ENTRY_SIZE1)
{
/* process the remaining part of the entry */
volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
while (--entrySize)
{
++entry;
IX_OSAL_WRITE_LONG(++qAccRegAddr, *entry);
}
entrySize = infoPtr->qEntrySizeInWords;
}
/* overflow is available for lower queues only */
if (qId < IX_QMGR_MIN_QUEUPP_QID)
{
UINT32 qSize = infoPtr->qSizeInEntries;
/* increment the current number of entries in the queue
* and check for overflow
*/
if (infoPtr->qWriteCount++ == qSize)
{
/* the queue may have overflow */
UINT32 qPtrs; /* queue internal pointers */
/* get the queue status */
UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);
/* read the status twice because the status may
* not be immediately ready after the write operation
*/
if ((status & infoPtr->qOflowStatBitMask) ||
((status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr))
& infoPtr->qOflowStatBitMask))
{
/* the queue is full, clear the overflow status
* bit if it was set
*/
IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
status & ~infoPtr->qOflowStatBitMask);
infoPtr->qWriteCount = infoPtr->qSizeInEntries;
return IX_QMGR_Q_OVERFLOW;
}
/* No overflow occured : someone is draining the queue
* and the current counter needs to be
* updated from the current number of entries in the queue
*/
/* get q pointer snapshot */
qPtrs = IX_OSAL_READ_LONG(infoPtr->qConfigRegAddr);
/* Mod subtraction of pointers to get number of words in Q. */
qPtrs = (qPtrs - (qPtrs >> 7)) & 0x7f;
if (qPtrs == 0)
{
/* the queue may be full at the time of the
* snapshot. Next access will check
* the overflow status again.
*/
infoPtr->qWriteCount = qSize;
}
else
{
/* convert the number of words to a number of entries */
if (entrySize == IX_QMGR_Q_ENTRY_SIZE1)
{
infoPtr->qWriteCount = qPtrs & (qSize - 1);
}
else
{
infoPtr->qWriteCount = (qPtrs / entrySize) & (qSize - 1);
}
}
}
}
return IX_SUCCESS;
}
PUBLIC IX_STATUS
ixQMgrQBurstWrite (IxQMgrQId qId,
unsigned numEntries,
UINT32 *entries)
{
extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
UINT32 status;
/* update the current write count */
infoPtr->qWriteCount += numEntries;
if (infoPtr->qEntrySizeInWords == IX_QMGR_Q_ENTRY_SIZE1)
{
volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
while (numEntries--)
{
IX_OSAL_WRITE_LONG(qAccRegAddr, *entries);
entries++;
}
}
else
{
IxQMgrQEntrySizeInWords entrySizeInWords = infoPtr->qEntrySizeInWords;
int i;
/* write each queue entry */
while (numEntries--)
{
/* write the queueEntrySize number of words for each entry */
for (i = 0; i < entrySizeInWords; i++)
{
IX_OSAL_WRITE_LONG((infoPtr->qAccRegAddr + i), *entries);
entries++;
}
}
}
/* check if the write count overflows */
if (infoPtr->qWriteCount > infoPtr->qSizeInEntries)
{
/* reset the current write count */
infoPtr->qWriteCount = infoPtr->qSizeInEntries;
}
/* Check if overflow occurred on the write operation */
if (qId < IX_QMGR_MIN_QUEUPP_QID)
{
/* get the queue status */
status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);
/* read the status twice because the status may
* not be ready at the time of the write
*/
if ((status & infoPtr->qOflowStatBitMask) ||
((status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr))
& infoPtr->qOflowStatBitMask))
{
/* clear the underflow status bit if it was set */
IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
status & ~infoPtr->qOflowStatBitMask);
return IX_QMGR_Q_OVERFLOW;
}
}
return IX_SUCCESS;
}
PUBLIC IX_STATUS
ixQMgrQStatusGet (IxQMgrQId qId,
IxQMgrQStatus *qStatus)
{
/* read the status of a queue in the range 0-31 */
if (qId < IX_QMGR_MIN_QUEUPP_QID)
{
extern UINT32 ixQMgrAqmIfQueLowStatRegAddr[];
extern UINT32 ixQMgrAqmIfQueLowStatBitsOffset[];
extern UINT32 ixQMgrAqmIfQueLowStatBitsMask;
extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
volatile UINT32 *lowStatRegAddr = (UINT32*)ixQMgrAqmIfQueLowStatRegAddr[qId];
volatile UINT32 *qUOStatRegAddr = infoPtr->qUOStatRegAddr;
UINT32 lowStatBitsOffset = ixQMgrAqmIfQueLowStatBitsOffset[qId];
UINT32 lowStatBitsMask = ixQMgrAqmIfQueLowStatBitsMask;
UINT32 underflowBitMask = infoPtr->qUflowStatBitMask;
UINT32 overflowBitMask = infoPtr->qOflowStatBitMask;
/* read the status register for this queue */
*qStatus = IX_OSAL_READ_LONG(lowStatRegAddr);
/* mask out the status bits relevant only to this queue */
*qStatus = (*qStatus >> lowStatBitsOffset) & lowStatBitsMask;
/* Check if the queue has overflowed */
if (IX_OSAL_READ_LONG(qUOStatRegAddr) & overflowBitMask)
{
/* clear the overflow status bit if it was set */
IX_OSAL_WRITE_LONG(qUOStatRegAddr,
(IX_OSAL_READ_LONG(qUOStatRegAddr) &
~overflowBitMask));
*qStatus |= IX_QMGR_Q_STATUS_OF_BIT_MASK;
}
/* Check if the queue has underflowed */
if (IX_OSAL_READ_LONG(qUOStatRegAddr) & underflowBitMask)
{
/* clear the underflow status bit if it was set */
IX_OSAL_WRITE_LONG(qUOStatRegAddr,
(IX_OSAL_READ_LONG(qUOStatRegAddr) &
~underflowBitMask));
*qStatus |= IX_QMGR_Q_STATUS_UF_BIT_MASK;
}
}
else /* read status of a queue in the range 32-63 */
{
extern UINT32 ixQMgrAqmIfQueUppStat0RegAddr;
extern UINT32 ixQMgrAqmIfQueUppStat1RegAddr;
extern UINT32 ixQMgrAqmIfQueUppStat0BitMask[];
extern UINT32 ixQMgrAqmIfQueUppStat1BitMask[];
volatile UINT32 *qNearEmptyStatRegAddr = (UINT32*)ixQMgrAqmIfQueUppStat0RegAddr;
volatile UINT32 *qFullStatRegAddr = (UINT32*)ixQMgrAqmIfQueUppStat1RegAddr;
int maskIndex = qId - IX_QMGR_MIN_QUEUPP_QID;
UINT32 qNearEmptyStatBitMask = ixQMgrAqmIfQueUppStat0BitMask[maskIndex];
UINT32 qFullStatBitMask = ixQMgrAqmIfQueUppStat1BitMask[maskIndex];
/* Reset the status bits */
*qStatus = 0;
/* Check if the queue is nearly empty */
if (IX_OSAL_READ_LONG(qNearEmptyStatRegAddr) & qNearEmptyStatBitMask)
{
*qStatus |= IX_QMGR_Q_STATUS_NE_BIT_MASK;
}
/* Check if the queue is full */
if (IX_OSAL_READ_LONG(qFullStatRegAddr) & qFullStatBitMask)
{
*qStatus |= IX_QMGR_Q_STATUS_F_BIT_MASK;
}
}
return IX_SUCCESS;
}
#endif /* def NO_INLINE_APIS */

543
cpu/ixp/npe/IxQMgrQCfg.c Normal file
View file

@ -0,0 +1,543 @@
/**
* @file QMgrQCfg.c
*
* @author Intel Corporation
* @date 30-Oct-2001
*
* @brief This modules provides an interface for setting up the static
* configuration of AQM queues.This file contains the following
* functions:
*
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
/*
* System defined include files.
*/
/*
* User defined include files.
*/
#include "IxOsal.h"
#include "IxQMgr.h"
#include "IxQMgrAqmIf_p.h"
#include "IxQMgrQCfg_p.h"
#include "IxQMgrDefines_p.h"
/*
* #defines and macros used in this file.
*/
#define IX_QMGR_MIN_ENTRY_SIZE_IN_WORDS 16
/* Total size of SRAM */
#define IX_QMGR_AQM_SRAM_SIZE_IN_BYTES 0x4000
/*
* Check that qId is a valid queue identifier. This is provided to
* make the code easier to read.
*/
#define IX_QMGR_QID_IS_VALID(qId) \
(((qId) >= (IX_QMGR_MIN_QID)) && ((qId) <= (IX_QMGR_MAX_QID)))
/*
* Typedefs whose scope is limited to this file.
*/
/*
* This struct describes an AQM queue.
* N.b. bufferSizeInWords and qEntrySizeInWords are stored in the queue
* as these are requested by Access in the data path. sizeInEntries is
* not required by the data path so it can be calculated dynamically.
*
*/
typedef struct
{
char qName[IX_QMGR_MAX_QNAME_LEN+1]; /* Textual description of a queue*/
IxQMgrQSizeInWords qSizeInWords; /* The number of words in the queue */
IxQMgrQEntrySizeInWords qEntrySizeInWords; /* Number of words per queue entry*/
BOOL isConfigured; /* This flag is TRUE if the queue has
* been configured
*/
} IxQMgrCfgQ;
/*
* Variable declarations global to this file. Externs are followed by
* statics.
*/
extern UINT32 * ixQMgrAqmIfQueAccRegAddr[];
/* Store data required to inline read and write access
*/
IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[IX_QMGR_MAX_NUM_QUEUES];
static IxQMgrCfgQ cfgQueueInfo[IX_QMGR_MAX_NUM_QUEUES];
/* This pointer holds the starting address of AQM SRAM not used by
* the AQM queues.
*/
static UINT32 freeSramAddress=0;
/* 4 words of zeroed memory for inline access */
static UINT32 zeroedPlaceHolder[4] = { 0, 0, 0, 0 };
static BOOL cfgInitialized = FALSE;
static IxOsalMutex ixQMgrQCfgMutex;
/*
* Statistics
*/
static IxQMgrQCfgStats stats;
/*
* Function declarations
*/
PRIVATE BOOL
watermarkLevelIsOk (IxQMgrQId qId, IxQMgrWMLevel level);
PRIVATE BOOL
qSizeInWordsIsOk (IxQMgrQSizeInWords qSize);
PRIVATE BOOL
qEntrySizeInWordsIsOk (IxQMgrQEntrySizeInWords entrySize);
/*
* Function definitions.
*/
void
ixQMgrQCfgInit (void)
{
int loopIndex;
for (loopIndex=0; loopIndex < IX_QMGR_MAX_NUM_QUEUES;loopIndex++)
{
/* info for code inlining */
ixQMgrAqmIfQueAccRegAddr[loopIndex] = zeroedPlaceHolder;
/* info for code inlining */
ixQMgrQInlinedReadWriteInfo[loopIndex].qReadCount = 0;
ixQMgrQInlinedReadWriteInfo[loopIndex].qWriteCount = 0;
ixQMgrQInlinedReadWriteInfo[loopIndex].qAccRegAddr = zeroedPlaceHolder;
ixQMgrQInlinedReadWriteInfo[loopIndex].qUOStatRegAddr = zeroedPlaceHolder;
ixQMgrQInlinedReadWriteInfo[loopIndex].qUflowStatBitMask = 0;
ixQMgrQInlinedReadWriteInfo[loopIndex].qOflowStatBitMask = 0;
ixQMgrQInlinedReadWriteInfo[loopIndex].qEntrySizeInWords = 0;
ixQMgrQInlinedReadWriteInfo[loopIndex].qSizeInEntries = 0;
ixQMgrQInlinedReadWriteInfo[loopIndex].qConfigRegAddr = zeroedPlaceHolder;
}
/* Initialise the AqmIf component */
ixQMgrAqmIfInit ();
/* Reset all queues to have queue name = NULL, entry size = 0 and
* isConfigured = false
*/
for (loopIndex=0; loopIndex < IX_QMGR_MAX_NUM_QUEUES;loopIndex++)
{
strcpy (cfgQueueInfo[loopIndex].qName, "");
cfgQueueInfo[loopIndex].qSizeInWords = 0;
cfgQueueInfo[loopIndex].qEntrySizeInWords = 0;
cfgQueueInfo[loopIndex].isConfigured = FALSE;
/* Statistics */
stats.qStats[loopIndex].isConfigured = FALSE;
stats.qStats[loopIndex].qName = cfgQueueInfo[loopIndex].qName;
}
/* Statistics */
stats.wmSetCnt = 0;
ixQMgrAqmIfSramBaseAddressGet (&freeSramAddress);
ixOsalMutexInit(&ixQMgrQCfgMutex);
cfgInitialized = TRUE;
}
void
ixQMgrQCfgUninit (void)
{
cfgInitialized = FALSE;
/* Uninitialise the AqmIf component */
ixQMgrAqmIfUninit ();
}
IX_STATUS
ixQMgrQConfig (char *qName,
IxQMgrQId qId,
IxQMgrQSizeInWords qSizeInWords,
IxQMgrQEntrySizeInWords qEntrySizeInWords)
{
UINT32 aqmLocalBaseAddress;
if (!cfgInitialized)
{
return IX_FAIL;
}
if (!IX_QMGR_QID_IS_VALID(qId))
{
return IX_QMGR_INVALID_Q_ID;
}
else if (NULL == qName)
{
return IX_QMGR_PARAMETER_ERROR;
}
else if (strlen (qName) > IX_QMGR_MAX_QNAME_LEN)
{
return IX_QMGR_PARAMETER_ERROR;
}
else if (!qSizeInWordsIsOk (qSizeInWords))
{
return IX_QMGR_INVALID_QSIZE;
}
else if (!qEntrySizeInWordsIsOk (qEntrySizeInWords))
{
return IX_QMGR_INVALID_Q_ENTRY_SIZE;
}
else if (cfgQueueInfo[qId].isConfigured)
{
return IX_QMGR_Q_ALREADY_CONFIGURED;
}
ixOsalMutexLock(&ixQMgrQCfgMutex, IX_OSAL_WAIT_FOREVER);
/* Write the config register */
ixQMgrAqmIfQueCfgWrite (qId,
qSizeInWords,
qEntrySizeInWords,
freeSramAddress);
strcpy (cfgQueueInfo[qId].qName, qName);
cfgQueueInfo[qId].qSizeInWords = qSizeInWords;
cfgQueueInfo[qId].qEntrySizeInWords = qEntrySizeInWords;
/* store pre-computed information in the same cache line
* to facilitate inlining of QRead and QWrite functions
* in IxQMgr.h
*/
ixQMgrQInlinedReadWriteInfo[qId].qReadCount = 0;
ixQMgrQInlinedReadWriteInfo[qId].qWriteCount = 0;
ixQMgrQInlinedReadWriteInfo[qId].qEntrySizeInWords = qEntrySizeInWords;
ixQMgrQInlinedReadWriteInfo[qId].qSizeInEntries =
(UINT32)qSizeInWords / (UINT32)qEntrySizeInWords;
/* Calculate the new freeSramAddress from the size of the queue
* currently being configured.
*/
freeSramAddress += (qSizeInWords * IX_QMGR_NUM_BYTES_PER_WORD);
/* Get the virtual SRAM address */
ixQMgrAqmIfBaseAddressGet (&aqmLocalBaseAddress);
IX_OSAL_ASSERT((freeSramAddress - (aqmLocalBaseAddress + (IX_QMGR_QUEBUFFER_SPACE_OFFSET))) <=
IX_QMGR_QUE_BUFFER_SPACE_SIZE);
/* The queue is now configured */
cfgQueueInfo[qId].isConfigured = TRUE;
ixOsalMutexUnlock(&ixQMgrQCfgMutex);
#ifndef NDEBUG
/* Update statistics */
stats.qStats[qId].isConfigured = TRUE;
stats.qStats[qId].qName = cfgQueueInfo[qId].qName;
#endif
return IX_SUCCESS;
}
IxQMgrQSizeInWords
ixQMgrQSizeInWordsGet (IxQMgrQId qId)
{
/* No parameter checking as this is used on the data path */
return (cfgQueueInfo[qId].qSizeInWords);
}
IX_STATUS
ixQMgrQSizeInEntriesGet (IxQMgrQId qId,
unsigned *qSizeInEntries)
{
if (!ixQMgrQIsConfigured(qId))
{
return IX_QMGR_Q_NOT_CONFIGURED;
}
if(NULL == qSizeInEntries)
{
return IX_QMGR_PARAMETER_ERROR;
}
*qSizeInEntries = (UINT32)(cfgQueueInfo[qId].qSizeInWords) /
(UINT32)cfgQueueInfo[qId].qEntrySizeInWords;
return IX_SUCCESS;
}
IxQMgrQEntrySizeInWords
ixQMgrQEntrySizeInWordsGet (IxQMgrQId qId)
{
/* No parameter checking as this is used on the data path */
return (cfgQueueInfo[qId].qEntrySizeInWords);
}
IX_STATUS
ixQMgrWatermarkSet (IxQMgrQId qId,
IxQMgrWMLevel ne,
IxQMgrWMLevel nf)
{
IxQMgrQStatus qStatusOnEntry;/* The queue status on entry/exit */
IxQMgrQStatus qStatusOnExit; /* to this function */
if (!ixQMgrQIsConfigured(qId))
{
return IX_QMGR_Q_NOT_CONFIGURED;
}
if (!watermarkLevelIsOk (qId, ne))
{
return IX_QMGR_INVALID_Q_WM;
}
if (!watermarkLevelIsOk (qId, nf))
{
return IX_QMGR_INVALID_Q_WM;
}
/* Get the current queue status */
ixQMgrAqmIfQueStatRead (qId, &qStatusOnEntry);
#ifndef NDEBUG
/* Update statistics */
stats.wmSetCnt++;
#endif
ixQMgrAqmIfWatermarkSet (qId,
ne,
nf);
/* Get the current queue status */
ixQMgrAqmIfQueStatRead (qId, &qStatusOnExit);
/* If the status has changed return a warning */
if (qStatusOnEntry != qStatusOnExit)
{
return IX_QMGR_WARNING;
}
return IX_SUCCESS;
}
IX_STATUS
ixQMgrAvailableSramAddressGet (UINT32 *address,
unsigned *sizeOfFreeRam)
{
UINT32 aqmLocalBaseAddress;
if ((NULL == address)||(NULL == sizeOfFreeRam))
{
return IX_QMGR_PARAMETER_ERROR;
}
if (!cfgInitialized)
{
return IX_FAIL;
}
*address = freeSramAddress;
/* Get the virtual SRAM address */
ixQMgrAqmIfBaseAddressGet (&aqmLocalBaseAddress);
/*
* Calculate the size in bytes of free sram
* i.e. current free SRAM virtual pointer from
* (base + total size)
*/
*sizeOfFreeRam =
(aqmLocalBaseAddress +
IX_QMGR_AQM_SRAM_SIZE_IN_BYTES) -
freeSramAddress;
if (0 == *sizeOfFreeRam)
{
return IX_QMGR_NO_AVAILABLE_SRAM;
}
return IX_SUCCESS;
}
BOOL
ixQMgrQIsConfigured (IxQMgrQId qId)
{
if (!IX_QMGR_QID_IS_VALID(qId))
{
return FALSE;
}
return cfgQueueInfo[qId].isConfigured;
}
IxQMgrQCfgStats*
ixQMgrQCfgStatsGet (void)
{
return &stats;
}
IxQMgrQCfgStats*
ixQMgrQCfgQStatsGet (IxQMgrQId qId)
{
unsigned int ne;
unsigned int nf;
UINT32 baseAddress;
UINT32 readPtr;
UINT32 writePtr;
stats.qStats[qId].qSizeInWords = cfgQueueInfo[qId].qSizeInWords;
stats.qStats[qId].qEntrySizeInWords = cfgQueueInfo[qId].qEntrySizeInWords;
if (IX_SUCCESS != ixQMgrQNumEntriesGet (qId, &stats.qStats[qId].numEntries))
{
if (IX_QMGR_WARNING != ixQMgrQNumEntriesGet (qId, &stats.qStats[qId].numEntries))
{
IX_QMGR_LOG_WARNING1("Failed to get the number of entries in queue.... %d\n", qId);
}
}
ixQMgrAqmIfQueCfgRead (qId,
stats.qStats[qId].numEntries,
&baseAddress,
&ne,
&nf,
&readPtr,
&writePtr);
stats.qStats[qId].baseAddress = baseAddress;
stats.qStats[qId].ne = ne;
stats.qStats[qId].nf = nf;
stats.qStats[qId].readPtr = readPtr;
stats.qStats[qId].writePtr = writePtr;
return &stats;
}
/*
* Static function definitions
*/
PRIVATE BOOL
watermarkLevelIsOk (IxQMgrQId qId, IxQMgrWMLevel level)
{
unsigned qSizeInEntries;
switch (level)
{
case IX_QMGR_Q_WM_LEVEL0:
case IX_QMGR_Q_WM_LEVEL1:
case IX_QMGR_Q_WM_LEVEL2:
case IX_QMGR_Q_WM_LEVEL4:
case IX_QMGR_Q_WM_LEVEL8:
case IX_QMGR_Q_WM_LEVEL16:
case IX_QMGR_Q_WM_LEVEL32:
case IX_QMGR_Q_WM_LEVEL64:
break;
default:
return FALSE;
}
/* Check watermark is not bigger than the qSizeInEntries */
ixQMgrQSizeInEntriesGet(qId, &qSizeInEntries);
if ((unsigned)level > qSizeInEntries)
{
return FALSE;
}
return TRUE;
}
PRIVATE BOOL
qSizeInWordsIsOk (IxQMgrQSizeInWords qSize)
{
BOOL status;
switch (qSize)
{
case IX_QMGR_Q_SIZE16:
case IX_QMGR_Q_SIZE32:
case IX_QMGR_Q_SIZE64:
case IX_QMGR_Q_SIZE128:
status = TRUE;
break;
default:
status = FALSE;
break;
}
return status;
}
PRIVATE BOOL
qEntrySizeInWordsIsOk (IxQMgrQEntrySizeInWords entrySize)
{
BOOL status;
switch (entrySize)
{
case IX_QMGR_Q_ENTRY_SIZE1:
case IX_QMGR_Q_ENTRY_SIZE2:
case IX_QMGR_Q_ENTRY_SIZE4:
status = TRUE;
break;
default:
status = FALSE;
break;
}
return status;
}

91
cpu/ixp/npe/Makefile Normal file
View file

@ -0,0 +1,91 @@
#
# (C) Copyright 2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
include $(TOPDIR)/config.mk
LIB := libnpe.a
CFLAGS += -I$(TOPDIR)/cpu/ixp/npe/include -DCONFIG_IXP425_COMPONENT_ETHDB
OBJS := npe.o \
miiphy.o \
IxOsalBufferMgt.o \
IxOsalIoMem.o \
IxOsalOsCacheMMU.o \
IxOsalOsMsgQ.o \
IxOsalOsSemaphore.o \
IxOsalOsServices.o \
IxOsalOsThread.o \
IxEthAcc.o \
IxEthAccCommon.o \
IxEthAccControlInterface.o \
IxEthAccDataPlane.o \
IxEthAccMac.o \
IxEthAccMii.o \
IxEthDBAPI.o \
IxEthDBAPISupport.o \
IxEthDBCore.o \
IxEthDBEvents.o \
IxEthDBFeatures.o \
IxEthDBFirewall.o \
IxEthDBHashtable.o \
IxEthDBLearning.o \
IxEthDBMem.o \
IxEthDBNPEAdaptor.o \
IxEthDBPortUpdate.o \
IxEthDBReports.o \
IxEthDBSearch.o \
IxEthDBSpanningTree.o \
IxEthDBUtil.o \
IxEthDBVlan.o \
IxEthDBWiFi.o \
IxEthMii.o \
IxQMgrAqmIf.o \
IxQMgrDispatcher.o \
IxQMgrInit.o \
IxQMgrQAccess.o \
IxQMgrQCfg.o \
IxFeatureCtrl.o \
IxNpeDl.o \
IxNpeDlImageMgr.o \
IxNpeDlNpeMgr.o \
IxNpeDlNpeMgrUtils.o \
IxNpeMicrocode.o \
IxNpeMh.o \
IxNpeMhConfig.o \
IxNpeMhReceive.o \
IxNpeMhSend.o \
IxNpeMhSolicitedCbMgr.o \
IxNpeMhUnsolicitedCbMgr.o
all: $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
#########################################################################
.depend: Makefile $(OBJS:.o=.c)
$(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
sinclude .depend

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,71 @@
/**
* @file IxAssert.h
*
* @date 21-MAR-2002 (replaced by OSAL)
*
* @brief This file contains assert and ensure macros used by the IXP400 software
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
/**
* @defgroup IxAssert IXP400 Assertion Macros (IxAssert) API
*
* @brief Assertion support
*
* @{
*/
#ifndef IXASSERT_H
#ifndef __doxygen_HIDE
#define IXASSERT_H
#endif /* __doxygen_HIDE */
#include "IxOsalBackward.h"
#endif /* IXASSERT_H */
/**
* @} addtogroup IxAssert
*/

View file

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

View file

@ -0,0 +1,409 @@
/**
* @file IxAtmTypes.h
*
* @date 24-MAR-2002
*
* @brief This file contains Atm types common to a number of Atm components.
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
/* ------------------------------------------------------
Doxygen group definitions
------------------------------------------------------ */
/**
* @defgroup IxAtmTypes IXP400 ATM Types (IxAtmTypes)
*
* @brief The common set of types used in many Atm components
*
* @{ */
#ifndef IXATMTYPES_H
#define IXATMTYPES_H
#include "IxNpeA.h"
/**
* @enum IxAtmLogicalPort
*
* @brief Logical Port Definitions :
*
* Only 1 port is available in SPHY configuration
* 12 ports are enabled in MPHY configuration
*
*/
typedef enum
{
IX_UTOPIA_PORT_0 = 0, /**< Port 0 */
#ifdef IX_NPE_MPHYMULTIPORT
IX_UTOPIA_PORT_1, /**< Port 1 */
IX_UTOPIA_PORT_2, /**< Port 2 */
IX_UTOPIA_PORT_3, /**< Port 3 */
IX_UTOPIA_PORT_4, /**< Port 4 */
IX_UTOPIA_PORT_5, /**< Port 5 */
IX_UTOPIA_PORT_6, /**< Port 6 */
IX_UTOPIA_PORT_7, /**< Port 7 */
IX_UTOPIA_PORT_8, /**< Port 8 */
IX_UTOPIA_PORT_9, /**< Port 9 */
IX_UTOPIA_PORT_10, /**< Port 10 */
IX_UTOPIA_PORT_11, /**< Port 11 */
#endif /* IX_NPE_MPHY */
IX_UTOPIA_MAX_PORTS /**< Not a port - just a definition for the
* maximum possible ports
*/
} IxAtmLogicalPort;
/**
* @def IX_ATM_CELL_PAYLOAD_SIZE
* @brief Size of a ATM cell payload
*/
#define IX_ATM_CELL_PAYLOAD_SIZE (48)
/**
* @def IX_ATM_CELL_SIZE
* @brief Size of a ATM cell, including header
*/
#define IX_ATM_CELL_SIZE (53)
/**
* @def IX_ATM_CELL_SIZE_NO_HEC
* @brief Size of a ATM cell, excluding HEC byte
*/
#define IX_ATM_CELL_SIZE_NO_HEC (IX_ATM_CELL_SIZE - 1)
/**
* @def IX_ATM_OAM_CELL_SIZE_NO_HEC
* @brief Size of a OAM cell, excluding HEC byte
*/
#define IX_ATM_OAM_CELL_SIZE_NO_HEC IX_ATM_CELL_SIZE_NO_HEC
/**
* @def IX_ATM_AAL0_48_CELL_PAYLOAD_SIZE
* @brief Size of a AAL0 48 Cell payload
*/
#define IX_ATM_AAL0_48_CELL_PAYLOAD_SIZE IX_ATM_CELL_PAYLOAD_SIZE
/**
* @def IX_ATM_AAL5_CELL_PAYLOAD_SIZE
* @brief Size of a AAL5 Cell payload
*/
#define IX_ATM_AAL5_CELL_PAYLOAD_SIZE IX_ATM_CELL_PAYLOAD_SIZE
/**
* @def IX_ATM_AAL0_52_CELL_SIZE_NO_HEC
* @brief Size of a AAL0 52 Cell, excluding HEC byte
*/
#define IX_ATM_AAL0_52_CELL_SIZE_NO_HEC IX_ATM_CELL_SIZE_NO_HEC
/**
* @def IX_ATM_MAX_VPI
* @brief Maximum value of an ATM VPI
*/
#define IX_ATM_MAX_VPI 255
/**
* @def IX_ATM_MAX_VCI
* @brief Maximum value of an ATM VCI
*/
#define IX_ATM_MAX_VCI 65535
/**
* @def IX_ATM_MAX_NUM_AAL_VCS
* @brief Maximum number of active AAL5/AAL0 VCs in the system
*/
#define IX_ATM_MAX_NUM_AAL_VCS 32
/**
* @def IX_ATM_MAX_NUM_VC
* @brief Maximum number of active AAL5/AAL0 VCs in the system
* The use of this macro is depreciated, it is retained for
* backward compatiblity. For current software release
* and beyond the define IX_ATM_MAX_NUM_AAL_VC should be used.
*/
#define IX_ATM_MAX_NUM_VC IX_ATM_MAX_NUM_AAL_VCS
/**
* @def IX_ATM_MAX_NUM_OAM_TX_VCS
* @brief Maximum number of active OAM Tx VCs in the system,
* 1 OAM VC per port
*/
#define IX_ATM_MAX_NUM_OAM_TX_VCS IX_UTOPIA_MAX_PORTS
/**
* @def IX_ATM_MAX_NUM_OAM_RX_VCS
* @brief Maximum number of active OAM Rx VCs in the system,
* 1 OAM VC shared accross all ports
*/
#define IX_ATM_MAX_NUM_OAM_RX_VCS 1
/**
* @def IX_ATM_MAX_NUM_AAL_OAM_TX_VCS
* @brief Maximum number of active AAL5/AAL0/OAM Tx VCs in the system
*/
#define IX_ATM_MAX_NUM_AAL_OAM_TX_VCS (IX_ATM_MAX_NUM_AAL_VCS + IX_ATM_MAX_NUM_OAM_TX_VCS)
/**
* @def IX_ATM_MAX_NUM_AAL_OAM_RX_VCS
* @brief Maximum number of active AAL5/AAL0/OAM Rx VCs in the system
*/
#define IX_ATM_MAX_NUM_AAL_OAM_RX_VCS (IX_ATM_MAX_NUM_AAL_VCS + IX_ATM_MAX_NUM_OAM_RX_VCS)
/**
* @def IX_ATM_IDLE_CELLS_CONNID
* @brief VC Id used to indicate idle cells in the returned schedule table.
*/
#define IX_ATM_IDLE_CELLS_CONNID 0
/**
* @def IX_ATM_CELL_HEADER_VCI_GET
* @brief get the VCI field from a cell header
*/
#define IX_ATM_CELL_HEADER_VCI_GET(cellHeader) \
(((cellHeader) >> 4) & IX_OAM_VCI_BITS_MASK);
/**
* @def IX_ATM_CELL_HEADER_VPI_GET
* @brief get the VPI field from a cell header
*/
#define IX_ATM_CELL_HEADER_VPI_GET(cellHeader) \
(((cellHeader) >> 20) & IX_OAM_VPI_BITS_MASK);
/**
* @def IX_ATM_CELL_HEADER_PTI_GET
* @brief get the PTI field from a cell header
*/
#define IX_ATM_CELL_HEADER_PTI_GET(cellHeader) \
((cellHeader) >> 1) & IX_OAM_PTI_BITS_MASK;
/**
* @typedef IxAtmCellHeader
*
* @brief ATM Cell Header, does not contain 4 byte HEC, added by NPE-A
*/
typedef unsigned int IxAtmCellHeader;
/**
* @enum IxAtmServiceCategory
*
* @brief Enumerated type representing available ATM service categories.
* For more informatoin on these categories, see "Traffic Management
* Specification" v4.1, published by the ATM Forum -
* http://www.atmforum.com
*/
typedef enum
{
IX_ATM_CBR, /**< Constant Bit Rate */
IX_ATM_RTVBR, /**< Real Time Variable Bit Rate */
IX_ATM_VBR, /**< Variable Bit Rate */
IX_ATM_UBR, /**< Unspecified Bit Rate */
IX_ATM_ABR /**< Available Bit Rate (not supported) */
} IxAtmServiceCategory;
/**
*
* @enum IxAtmRxQueueId
*
* @brief Rx Queue Type for RX traffic
*
* IxAtmRxQueueId defines the queues involved for receiving data.
*
* There are two queues to facilitate prioritisation handling
* and processing the 2 queues with different algorithms and
* constraints
*
* e.g. : one queue can carry voice (or time-critical traffic), the
* other queue can carry non-voice traffic
*
*/
typedef enum
{
IX_ATM_RX_A = 0, /**< RX queue A */
IX_ATM_RX_B, /**< RX queue B */
IX_ATM_MAX_RX_STREAMS /**< Maximum number of RX streams */
} IxAtmRxQueueId;
/**
* @brief Structure describing an ATM traffic contract for a Virtual
* Connection (VC).
*
* Structure is used to specify the requested traffic contract for a
* VC to the IxAtmSch component using the @ref ixAtmSchVcModelSetup
* interface.
*
* These parameters are defined by the ATM forum working group
* (http://www.atmforum.com).
*
* @note Typical values for a voice channel 64 Kbit/s
* - atmService @a IX_ATM_RTVBR
* - pcr 400 (include IP overhead, and AAL5 trailer)
* - cdvt 5000000 (5 ms)
* - scr = pcr
*
* @note Typical values for a data channel 800 Kbit/s
* - atmService @a IX_ATM_UBR
* - pcr 1962 (include IP overhead, and AAL5 trailer)
* - cdvt 5000000 (5 ms)
*
*/
typedef struct
{
IxAtmServiceCategory atmService; /**< ATM service category */
unsigned pcr; /**< Peak Cell Rate - cells per second */
unsigned cdvt; /**< Cell Delay Variation Tolerance - in nanoseconds */
unsigned scr; /**< Sustained Cell Rate - cells per second */
unsigned mbs; /**< Max Burst Size - cells */
unsigned mcr; /**< Minimum Cell Rate - cells per second */
unsigned mfs; /**< Max Frame Size - cells */
} IxAtmTrafficDescriptor;
/**
* @typedef IxAtmConnId
*
* @brief ATM VC data connection identifier.
*
* This is is generated by IxAtmdAcc when a successful connection is
* made on a VC. The is the ID by which IxAtmdAcc knows an active
* VC and should be used in IxAtmdAcc API calls to reference a
* specific VC.
*/
typedef unsigned int IxAtmConnId;
/**
* @typedef IxAtmSchedulerVcId
*
* @brief ATM VC scheduling connection identifier.
*
* This id is generated and used by ATM Tx controller, generally
* the traffic shaper (e.g. IxAtmSch). The IxAtmdAcc component
* will request one of these Ids whenever a data connection on
* a Tx VC is requested. This ID will be used in callbacks to
* the ATM Transmission Ctrl s/w (e.g. IxAtmm) to reference a
* particular VC.
*/
typedef int IxAtmSchedulerVcId;
/**
* @typedef IxAtmNpeRxVcId
*
* @brief ATM Rx VC identifier used by the ATM Npe.
*
* This Id is generated by IxAtmdAcc when a successful data connection
* is made on a rx VC.
*/
typedef unsigned int IxAtmNpeRxVcId;
/**
* @brief ATM Schedule Table entry
*
* This IxAtmScheduleTableEntry is used by an ATM scheduler to inform
* IxAtmdAcc about the data to transmit (in term of cells per VC)
*
* This structure defines
* @li the number of cells to be transmitted (numberOfCells)
* @li the VC connection to be used for transmission (connId).
*
* @note - When the connection Id value is IX_ATM_IDLE_CELLS_CONNID, the
* corresponding number of idle cells will be transmitted to the hardware.
*
*/
typedef struct
{
IxAtmConnId connId; /**< connection Id
*
* Identifier of VC from which cells are to be transmitted.
* When this valus is IX_ATM_IDLE_CELLS_CONNID, this indicates
* that the system should transmit the specified number
* of idle cells. Unknown connIds result in the transmission
* idle cells.
*/
unsigned int numberOfCells; /**< number of cells to transmit
*
* The number of contiguous cells to schedule from this VC
* at this point. The valid range is from 1 to
* @a IX_ATM_SCHEDULETABLE_MAXCELLS_PER_ENTRY. This
* number can swap over mbufs and pdus. OverSchduling results
* in the transmission of idle cells.
*/
} IxAtmScheduleTableEntry;
/**
* @brief This structure defines a schedule table which gives details
* on which data (from which VCs) should be transmitted for a
* forthcoming period of time for a particular port and the
* order in which that data should be transmitted.
*
* The schedule table consists of a series of entries each of which
* will schedule one or more cells from a particular registered VC.
* The total number of cells scheduled and the total number of
* entries in the table are also indicated.
*
*/
typedef struct
{
unsigned tableSize; /**< Number of entries
*
* Indicates the total number of
* entries in the table.
*/
unsigned totalCellSlots; /**< Number of cells
*
* Indicates the total number of ATM
* cells which are scheduled by all the
* entries in the table.
*/
IxAtmScheduleTableEntry *table; /**< Pointer to schedule entries
*
* Pointer to an array
* containing tableSize entries
*/
} IxAtmScheduleTable;
#endif /* IXATMTYPES_H */
/**
* @} defgroup IxAtmTypes
*/

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

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

View file

@ -0,0 +1,260 @@
/**
* @file IxDmaAcc.h
*
* @date 15 October 2002
*
* @brief API of the IXP400 DMA Access Driver Component (IxDma)
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
/*---------------------------------------------------------------------
Doxygen group definitions
---------------------------------------------------------------------*/
#ifndef IXDMAACC_H
#define IXDMAACC_H
#include "IxOsal.h"
#include "IxNpeDl.h"
/**
* @defgroup IxDmaTypes IXP400 DMA Types (IxDmaTypes)
* @brief The common set of types used in the DMA component
* @{
*/
/**
* @ingroup IxDmaTypes
* @enum IxDmaReturnStatus
* @brief Dma return status definitions
*/
typedef enum
{
IX_DMA_SUCCESS = IX_SUCCESS, /**< DMA Transfer Success */
IX_DMA_FAIL = IX_FAIL, /**< DMA Transfer Fail */
IX_DMA_INVALID_TRANSFER_WIDTH, /**< Invalid transfer width */
IX_DMA_INVALID_TRANSFER_LENGTH, /**< Invalid transfer length */
IX_DMA_INVALID_TRANSFER_MODE, /**< Invalid transfer mode */
IX_DMA_INVALID_ADDRESS_MODE, /**< Invalid address mode */
IX_DMA_REQUEST_FIFO_FULL /**< DMA request queue is full */
} IxDmaReturnStatus;
/**
* @ingroup IxDmaTypes
* @enum IxDmaTransferMode
* @brief Dma transfer mode definitions
* @note Copy and byte swap, and copy and reverse modes only support multiples of word data length.
*/
typedef enum
{
IX_DMA_COPY_CLEAR = 0, /**< copy and clear source*/
IX_DMA_COPY, /**< copy */
IX_DMA_COPY_BYTE_SWAP, /**< copy and byte swap (endian) */
IX_DMA_COPY_REVERSE, /**< copy and reverse */
IX_DMA_TRANSFER_MODE_INVALID /**< Invalid transfer mode */
} IxDmaTransferMode;
/**
* @ingroup IxDmaTypes
* @enum IxDmaAddressingMode
* @brief Dma addressing mode definitions
* @note Fixed source address to fixed destination address addressing mode is not supported.
*/
typedef enum
{
IX_DMA_INC_SRC_INC_DST = 0, /**< Incremental source address to incremental destination address */
IX_DMA_INC_SRC_FIX_DST, /**< Incremental source address to incremental destination address */
IX_DMA_FIX_SRC_INC_DST, /**< Incremental source address to incremental destination address */
IX_DMA_FIX_SRC_FIX_DST, /**< Incremental source address to incremental destination address */
IX_DMA_ADDRESSING_MODE_INVALID /**< Invalid Addressing Mode */
} IxDmaAddressingMode;
/**
* @ingroup IxDmaTypes
* @enum IxDmaTransferWidth
* @brief Dma transfer width definitions
* @Note Fixed addresses (either source or destination) do not support burst transfer width.
*/
typedef enum
{
IX_DMA_32_SRC_32_DST = 0, /**< 32-bit src to 32-bit dst */
IX_DMA_32_SRC_16_DST, /**< 32-bit src to 16-bit dst */
IX_DMA_32_SRC_8_DST, /**< 32-bit src to 8-bit dst */
IX_DMA_16_SRC_32_DST, /**< 16-bit src to 32-bit dst */
IX_DMA_16_SRC_16_DST, /**< 16-bit src to 16-bit dst */
IX_DMA_16_SRC_8_DST, /**< 16-bit src to 8-bit dst */
IX_DMA_8_SRC_32_DST, /**< 8-bit src to 32-bit dst */
IX_DMA_8_SRC_16_DST, /**< 8-bit src to 16-bit dst */
IX_DMA_8_SRC_8_DST, /**< 8-bit src to 8-bit dst */
IX_DMA_8_SRC_BURST_DST, /**< 8-bit src to burst dst - Not supported for fixed destination address */
IX_DMA_16_SRC_BURST_DST, /**< 16-bit src to burst dst - Not supported for fixed destination address */
IX_DMA_32_SRC_BURST_DST, /**< 32-bit src to burst dst - Not supported for fixed destination address */
IX_DMA_BURST_SRC_8_DST, /**< burst src to 8-bit dst - Not supported for fixed source address */
IX_DMA_BURST_SRC_16_DST, /**< burst src to 16-bit dst - Not supported for fixed source address */
IX_DMA_BURST_SRC_32_DST, /**< burst src to 32-bit dst - Not supported for fixed source address*/
IX_DMA_BURST_SRC_BURST_DST, /**< burst src to burst dst - Not supported for fixed source and destination address
*/
IX_DMA_TRANSFER_WIDTH_INVALID /**< Invalid transfer width */
} IxDmaTransferWidth;
/**
* @ingroup IxDmaTypes
* @enum IxDmaNpeId
* @brief NpeId numbers to identify NPE A, B or C
*/
typedef enum
{
IX_DMA_NPEID_NPEA = 0, /**< Identifies NPE A */
IX_DMA_NPEID_NPEB, /**< Identifies NPE B */
IX_DMA_NPEID_NPEC, /**< Identifies NPE C */
IX_DMA_NPEID_MAX /**< Total Number of NPEs */
} IxDmaNpeId;
/* @} */
/**
* @defgroup IxDmaAcc IXP400 DMA Access Driver (IxDmaAcc) API
*
* @brief The public API for the IXP400 IxDmaAcc component
*
* @{
*/
/**
* @ingroup IxDmaAcc
* @brief DMA Request Id type
*/
typedef UINT32 IxDmaAccRequestId;
/**
* @ingroup IxDmaAcc
* @def IX_DMA_REQUEST_FULL
* @brief DMA request queue is full
* This constant is a return value used to tell the user that the IxDmaAcc
* queue is full.
*
*/
#define IX_DMA_REQUEST_FULL 16
/**
* @ingroup IxDmaAcc
* @brief DMA completion notification
* This function is called to notify a client that the DMA has been completed
* @param status @ref IxDmaReturnStatus [out] - reporting to client
*
*/
typedef void (*IxDmaAccDmaCompleteCallback) (IxDmaReturnStatus status);
/**
* @ingroup IxDmaAcc
*
* @fn ixDmaAccInit(IxNpeDlNpeId npeId)
*
* @brief Initialise the DMA Access component
* This function will initialise the DMA Access component internals
* @param npeId @ref IxNpeDlNpeId [in] - NPE to use for Dma Transfer
* @return @li IX_SUCCESS succesfully initialised the component
* @return @li IX_FAIL Initialisation failed for some unspecified
* internal reason.
*/
PUBLIC IX_STATUS
ixDmaAccInit(IxNpeDlNpeId npeId);
/**
* @ingroup IxDmaAcc
*
* @fn ixDmaAccDmaTransfer(
IxDmaAccDmaCompleteCallback callback,
UINT32 SourceAddr,
UINT32 DestinationAddr,
UINT16 TransferLength,
IxDmaTransferMode TransferMode,
IxDmaAddressingMode AddressingMode,
IxDmaTransferWidth TransferWidth)
*
* @brief Perform DMA transfer
* This function will perform DMA transfer between devices within the
* IXP400 memory map.
* @note The following are restrictions for IxDmaAccDmaTransfer:
* @li The function is non re-entrant.
* @li The function assumes host devices are operating in big-endian mode.
* @li Fixed address does not suport burst transfer width
* @li Fixed source address to fixed destinatiom address mode is not suported
* @li The incrementing source address for expansion bus will not support a burst transfer width and copy and clear mode
*
* @param callback @ref IxDmaAccDmaCompleteCallback [in] - function pointer to be stored and called when the DMA transfer is completed. This cannot be NULL.
* @param SourceAddr UINT32 [in] - Starting address of DMA source. Must be a valid IXP400 memory map address.
* @param DestinationAddr UINT32 [in] - Starting address of DMA destination. Must be a valid IXP400 memory map address.
* @param TransferLength UINT16 [in] - The size of DMA data transfer. The range must be from 1-64Kbyte
* @param TransferMode @ref IxDmaTransferMode [in] - The DMA transfer mode
* @param AddressingMode @ref IxDmaAddressingMode [in] - The DMA addressing mode
* @param TransferWidth @ref IxDmaTransferWidth [in] - The DMA transfer width
*
* @return @li IX_DMA_SUCCESS Notification that the DMA request is succesful
* @return @li IX_DMA_FAIL IxDmaAcc not yet initialised or some internal error has occured
* @return @li IX_DMA_INVALID_TRANSFER_WIDTH Transfer width is nit valid
* @return @li IX_DMA_INVALID_TRANSFER_LENGTH Transfer length outside of valid range
* @return @li IX_DMA_INVALID_TRANSFER_MODE Transfer Mode not valid
* @return @li IX_DMA_REQUEST_FIFO_FULL IxDmaAcc request queue is full
*/
PUBLIC IxDmaReturnStatus
ixDmaAccDmaTransfer(
IxDmaAccDmaCompleteCallback callback,
UINT32 SourceAddr,
UINT32 DestinationAddr,
UINT16 TransferLength,
IxDmaTransferMode TransferMode,
IxDmaAddressingMode AddressingMode,
IxDmaTransferWidth TransferWidth);
/**
* @ingroup IxDmaAcc
*
* @fn ixDmaAccShow(void)
*
* @brief Display some component information for debug purposes
* Show some internal operation information relating to the DMA service.
* At a minimum the following will show.
* - the number of the DMA pend (in queue)
* @param None
* @return @li None
*/
PUBLIC IX_STATUS
ixDmaAccShow(void);
#endif /* IXDMAACC_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,245 @@
/**
* @file IxEthAccDataPlane_p.h
*
* @author Intel Corporation
* @date 12-Feb-2002
*
* @brief Internal Header file for IXP425 Ethernet Access component.
*
* Design Notes:
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#ifndef IxEthAccDataPlane_p_H
#define IxEthAccDataPlane_p_H
#include <IxOsal.h>
#include <IxQMgr.h>
/**
* @addtogroup IxEthAccPri
*@{
*/
/* typedefs global to this file*/
typedef struct
{
IX_OSAL_MBUF *pHead;
IX_OSAL_MBUF *pTail;
}IxEthAccDataPlaneQList;
/**
* @struct IxEthAccDataPlaneStats
* @brief Statistics data structure associated with the data plane
*
*/
typedef struct
{
UINT32 addToSwQ;
UINT32 removeFromSwQ;
UINT32 unchainedTxMBufs;
UINT32 chainedTxMBufs;
UINT32 unchainedTxDoneMBufs;
UINT32 chainedTxDoneMBufs;
UINT32 unchainedRxMBufs;
UINT32 chainedRxMBufs;
UINT32 unchainedRxFreeMBufs;
UINT32 chainedRxFreeMBufs;
UINT32 rxCallbackCounter;
UINT32 rxCallbackBurstRead;
UINT32 txDoneCallbackCounter;
UINT32 unexpectedError;
} IxEthAccDataPlaneStats;
/**
* @fn ixEthAccMbufFromSwQ
* @brief used during disable steps to convert mbufs from
* swq format, ready to be pushed into hw queues for NPE,
* back into XScale format
*/
IX_OSAL_MBUF *ixEthAccMbufFromSwQ(IX_OSAL_MBUF *mbuf);
/**
* @fn ixEthAccDataPlaneShow
* @brief Show function (for data plane statistics
*/
void ixEthAccDataPlaneShow(void);
/*
* lock dataplane when atomic operation is required
*/
#define IX_ETH_ACC_DATA_PLANE_LOCK(arg) arg = ixOsalIrqLock();
#define IX_ETH_ACC_DATA_PLANE_UNLOCK(arg) ixOsalIrqUnlock(arg);
/*
* Use MBUF fields
*/
#define IX_ETHACC_NE_SHARED(mBufPtr) \
((IxEthAccNe *)&((mBufPtr)->ix_ne))
#if 1
#define IX_ETHACC_NE_NEXT(mBufPtr) (mBufPtr)->ix_ne.reserved[0]
/* tm - wrong!! len and pkt_len are in the second word - #define IX_ETHACC_NE_LEN(mBufPtr) (mBufPtr)->ix_ne.reserved[3] */
#define IX_ETHACC_NE_LEN(mBufPtr) (mBufPtr)->ix_ne.reserved[1]
#define IX_ETHACC_NE_DATA(mBufPtr)(mBufPtr)->ix_ne.reserved[2]
#else
#define IX_ETHACC_NE_NEXT(mBufPtr) \
IX_ETHACC_NE_SHARED(mBufPtr)->ixReserved_next
#define IX_ETHACC_NE_LEN(mBufPtr) \
IX_ETHACC_NE_SHARED(mBufPtr)->ixReserved_lengths
#define IX_ETHACC_NE_DATA(mBufPtr) \
IX_ETHACC_NE_SHARED(mBufPtr)->ixReserved_data
#endif
/*
* Use MBUF next pointer field to chain data.
*/
#define IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER(mbuf) (mbuf)->ix_ctrl.ix_chain
#define IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(mbuf_list) ((mbuf_list.pHead) == NULL)
#define IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD(mbuf_list,mbuf_to_add) \
do { \
int lockVal; \
IX_ETH_ACC_DATA_PLANE_LOCK(lockVal); \
IX_ETH_ACC_STATS_INC(ixEthAccDataStats.addToSwQ); \
if ( (mbuf_list.pHead) != NULL ) \
{ \
(IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_to_add))) = (mbuf_list.pHead);\
(mbuf_list.pHead) = (mbuf_to_add); \
} \
else { \
(mbuf_list.pTail) = (mbuf_list.pHead) = (mbuf_to_add); \
IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_to_add)) = NULL; \
} \
IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); \
} while(0)
#define IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_TAIL(mbuf_list,mbuf_to_add) \
do { \
int lockVal; \
IX_ETH_ACC_DATA_PLANE_LOCK(lockVal); \
IX_ETH_ACC_STATS_INC(ixEthAccDataStats.addToSwQ); \
if ( (mbuf_list.pHead) == NULL ) \
{ \
(mbuf_list.pHead) = mbuf_to_add; \
IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_to_add)) = NULL; \
} \
else { \
IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_list.pTail)) = (mbuf_to_add); \
IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_to_add)) = NULL; \
} \
(mbuf_list.pTail) = mbuf_to_add; \
IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); \
} while (0)
#define IX_ETH_ACC_DATAPLANE_REMOVE_MBUF_FROM_Q_HEAD(mbuf_list,mbuf_to_rem) \
do { \
int lockVal; \
IX_ETH_ACC_DATA_PLANE_LOCK(lockVal); \
if ( (mbuf_list.pHead) != NULL ) \
{ \
IX_ETH_ACC_STATS_INC(ixEthAccDataStats.removeFromSwQ); \
(mbuf_to_rem) = (mbuf_list.pHead) ; \
(mbuf_list.pHead) = (IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_to_rem)));\
} \
else { \
(mbuf_to_rem) = NULL; \
} \
IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); \
} while (0)
/**
* @brief message handler QManager entries for NPE id => port ID conversion (NPE_B => 0, NPE_C => 1)
*/
#define IX_ETH_ACC_PORT_TO_NPE_ID(port) \
ixEthAccPortData[(port)].npeId
#define IX_ETH_ACC_NPE_TO_PORT_ID(npe) ((npe == 0 ? 2 : (npe == 1 ? 0 : ( npe == 2 ? 1 : -1 ))))
#define IX_ETH_ACC_PORT_TO_TX_Q_ID(port) \
ixEthAccPortData[(port)].ixEthAccTxData.txQueue
#define IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(port) \
ixEthAccPortData[(port)].ixEthAccRxData.rxFreeQueue
#define IX_ETH_ACC_PORT_TO_TX_Q_SOURCE(port) (port == IX_ETH_PORT_1 ? IX_ETH_ACC_TX_FRAME_ENET0_Q_SOURCE : (port == IX_ETH_PORT_2 ? IX_ETH_ACC_TX_FRAME_ENET1_Q_SOURCE : IX_ETH_ACC_TX_FRAME_ENET2_Q_SOURCE))
#define IX_ETH_ACC_PORT_TO_RX_FREE_Q_SOURCE(port) (port == IX_ETH_PORT_1 ? IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q_SOURCE : (port == IX_ETH_PORT_2 ? IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q_SOURCE : IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q_SOURCE ))
/* Flush the mbufs chain and all data pointed to by the mbuf */
#ifndef NDEBUG
#define IX_ETH_ACC_STATS_INC(x) (x++)
#else
#define IX_ETH_ACC_STATS_INC(x)
#endif
#define IX_ETH_ACC_MAX_TX_FRAMES_TO_SUBMIT 128
void ixEthRxFrameQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId);
void ixEthRxMultiBufferQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId);
void ixEthTxFrameDoneQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId);
#endif /* IxEthAccDataPlane_p_H */
/**
*@}
*/

View file

@ -0,0 +1,248 @@
/*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#ifndef IxEthAccMac_p_H
#define IxEthAccMac_p_H
#include "IxOsal.h"
#define IX_ETH_ACC_MAX_MULTICAST_ADDRESSES 256
#define IX_ETH_ACC_NUM_PORTS 3
#define IX_ETH_ACC_MAX_FRAME_SIZE_DEFAULT 1536
#define IX_ETH_ACC_MAX_FRAME_SIZE_UPPER_RANGE (65536-64)
#define IX_ETH_ACC_MAX_FRAME_SIZE_LOWER_RANGE 64
/*
*
* MAC register definitions
*
*/
#define IX_ETH_ACC_MAC_0_BASE IX_OSAL_IXP400_ETHA_PHYS_BASE
#define IX_ETH_ACC_MAC_1_BASE IX_OSAL_IXP400_ETHB_PHYS_BASE
#define IX_ETH_ACC_MAC_2_BASE IX_OSAL_IXP400_ETH_NPEA_PHYS_BASE
#define IX_ETH_ACC_MAC_TX_CNTRL1 0x000
#define IX_ETH_ACC_MAC_TX_CNTRL2 0x004
#define IX_ETH_ACC_MAC_RX_CNTRL1 0x010
#define IX_ETH_ACC_MAC_RX_CNTRL2 0x014
#define IX_ETH_ACC_MAC_RANDOM_SEED 0x020
#define IX_ETH_ACC_MAC_THRESH_P_EMPTY 0x030
#define IX_ETH_ACC_MAC_THRESH_P_FULL 0x038
#define IX_ETH_ACC_MAC_BUF_SIZE_TX 0x040
#define IX_ETH_ACC_MAC_TX_DEFER 0x050
#define IX_ETH_ACC_MAC_RX_DEFER 0x054
#define IX_ETH_ACC_MAC_TX_TWO_DEFER_1 0x060
#define IX_ETH_ACC_MAC_TX_TWO_DEFER_2 0x064
#define IX_ETH_ACC_MAC_SLOT_TIME 0x070
#define IX_ETH_ACC_MAC_MDIO_CMD_1 0x080
#define IX_ETH_ACC_MAC_MDIO_CMD_2 0x084
#define IX_ETH_ACC_MAC_MDIO_CMD_3 0x088
#define IX_ETH_ACC_MAC_MDIO_CMD_4 0x08c
#define IX_ETH_ACC_MAC_MDIO_STS_1 0x090
#define IX_ETH_ACC_MAC_MDIO_STS_2 0x094
#define IX_ETH_ACC_MAC_MDIO_STS_3 0x098
#define IX_ETH_ACC_MAC_MDIO_STS_4 0x09c
#define IX_ETH_ACC_MAC_ADDR_MASK_1 0x0A0
#define IX_ETH_ACC_MAC_ADDR_MASK_2 0x0A4
#define IX_ETH_ACC_MAC_ADDR_MASK_3 0x0A8
#define IX_ETH_ACC_MAC_ADDR_MASK_4 0x0AC
#define IX_ETH_ACC_MAC_ADDR_MASK_5 0x0B0
#define IX_ETH_ACC_MAC_ADDR_MASK_6 0x0B4
#define IX_ETH_ACC_MAC_ADDR_1 0x0C0
#define IX_ETH_ACC_MAC_ADDR_2 0x0C4
#define IX_ETH_ACC_MAC_ADDR_3 0x0C8
#define IX_ETH_ACC_MAC_ADDR_4 0x0CC
#define IX_ETH_ACC_MAC_ADDR_5 0x0D0
#define IX_ETH_ACC_MAC_ADDR_6 0x0D4
#define IX_ETH_ACC_MAC_INT_CLK_THRESH 0x0E0
#define IX_ETH_ACC_MAC_UNI_ADDR_1 0x0F0
#define IX_ETH_ACC_MAC_UNI_ADDR_2 0x0F4
#define IX_ETH_ACC_MAC_UNI_ADDR_3 0x0F8
#define IX_ETH_ACC_MAC_UNI_ADDR_4 0x0FC
#define IX_ETH_ACC_MAC_UNI_ADDR_5 0x100
#define IX_ETH_ACC_MAC_UNI_ADDR_6 0x104
#define IX_ETH_ACC_MAC_CORE_CNTRL 0x1FC
/*
*
*Bit definitions
*
*/
/* TX Control Register 1*/
#define IX_ETH_ACC_TX_CNTRL1_TX_EN BIT(0)
#define IX_ETH_ACC_TX_CNTRL1_DUPLEX BIT(1)
#define IX_ETH_ACC_TX_CNTRL1_RETRY BIT(2)
#define IX_ETH_ACC_TX_CNTRL1_PAD_EN BIT(3)
#define IX_ETH_ACC_TX_CNTRL1_FCS_EN BIT(4)
#define IX_ETH_ACC_TX_CNTRL1_2DEFER BIT(5)
#define IX_ETH_ACC_TX_CNTRL1_RMII BIT(6)
/* TX Control Register 2 */
#define IX_ETH_ACC_TX_CNTRL2_RETRIES_MASK 0xf
/* RX Control Register 1 */
#define IX_ETH_ACC_RX_CNTRL1_RX_EN BIT(0)
#define IX_ETH_ACC_RX_CNTRL1_PADSTRIP_EN BIT(1)
#define IX_ETH_ACC_RX_CNTRL1_CRC_EN BIT(2)
#define IX_ETH_ACC_RX_CNTRL1_PAUSE_EN BIT(3)
#define IX_ETH_ACC_RX_CNTRL1_LOOP_EN BIT(4)
#define IX_ETH_ACC_RX_CNTRL1_ADDR_FLTR_EN BIT(5)
#define IX_ETH_ACC_RX_CNTRL1_RX_RUNT_EN BIT(6)
#define IX_ETH_ACC_RX_CNTRL1_BCAST_DIS BIT(7)
/* RX Control Register 2 */
#define IX_ETH_ACC_RX_CNTRL2_DEFER_EN BIT(0)
/* Core Control Register */
#define IX_ETH_ACC_CORE_RESET BIT(0)
#define IX_ETH_ACC_CORE_RX_FIFO_FLUSH BIT(1)
#define IX_ETH_ACC_CORE_TX_FIFO_FLUSH BIT(2)
#define IX_ETH_ACC_CORE_SEND_JAM BIT(3)
#define IX_ETH_ACC_CORE_MDC_EN BIT(4)
/* 1st bit of 1st MAC octet */
#define IX_ETH_ACC_ETH_MAC_BCAST_MCAST_BIT ( 1)
/*
*
* Default values
*
*/
#define IX_ETH_ACC_TX_CNTRL1_DEFAULT (IX_ETH_ACC_TX_CNTRL1_TX_EN | \
IX_ETH_ACC_TX_CNTRL1_RETRY | \
IX_ETH_ACC_TX_CNTRL1_FCS_EN | \
IX_ETH_ACC_TX_CNTRL1_2DEFER | \
IX_ETH_ACC_TX_CNTRL1_PAD_EN)
#define IX_ETH_ACC_TX_MAX_RETRIES_DEFAULT 0x0f
#define IX_ETH_ACC_RX_CNTRL1_DEFAULT (IX_ETH_ACC_RX_CNTRL1_CRC_EN \
| IX_ETH_ACC_RX_CNTRL1_RX_EN)
#define IX_ETH_ACC_RX_CNTRL2_DEFAULT 0x0
/* Thresholds determined by NPE firmware FS */
#define IX_ETH_ACC_MAC_THRESH_P_EMPTY_DEFAULT 0x12
#define IX_ETH_ACC_MAC_THRESH_P_FULL_DEFAULT 0x30
/* Number of bytes that must be in the tx fifo before
transmission commences*/
#define IX_ETH_ACC_MAC_BUF_SIZE_TX_DEFAULT 0x8
/* One-part deferral values */
#define IX_ETH_ACC_MAC_TX_DEFER_DEFAULT 0x15
#define IX_ETH_ACC_MAC_RX_DEFER_DEFAULT 0x16
/* Two-part deferral values... */
#define IX_ETH_ACC_MAC_TX_TWO_DEFER_1_DEFAULT 0x08
#define IX_ETH_ACC_MAC_TX_TWO_DEFER_2_DEFAULT 0x07
/* This value applies to MII */
#define IX_ETH_ACC_MAC_SLOT_TIME_DEFAULT 0x80
/* This value applies to RMII */
#define IX_ETH_ACC_MAC_SLOT_TIME_RMII_DEFAULT 0xFF
#define IX_ETH_ACC_MAC_ADDR_MASK_DEFAULT 0xFF
#define IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT 0x1
/*The following is a value chosen at random*/
#define IX_ETH_ACC_RANDOM_SEED_DEFAULT 0x8
/*By default we must configure the MAC to generate the
MDC clock*/
#define IX_ETH_ACC_CORE_DEFAULT (IX_ETH_ACC_CORE_MDC_EN)
#define IXP425_ETH_ACC_MAX_PHY 2
#define IXP425_ETH_ACC_MAX_AN_ENTRIES 20
#define IX_ETH_ACC_MAC_RESET_DELAY 1
#define IX_ETH_ACC_MAC_ALL_BITS_SET 0xFF
#define IX_ETH_ACC_MAC_MSGID_SHL 24
#define IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS 20
#define IX_ETH_ACC_PORT_DISABLE_DELAY_COUNT 200 /* 4 seconds timeout */
#define IX_ETH_ACC_PORT_DISABLE_RETRY_COUNT 3
#define IX_ETH_ACC_MIB_STATS_DELAY_MSECS 2000 /* 2 seconds delay for ethernet stats */
/*Register access macros*/
#if (CPU == SIMSPARCSOLARIS)
extern void registerWriteStub (UINT32 base, UINT32 offset, UINT32 val);
extern UINT32 registerReadStub (UINT32 base, UINT32 offset);
#define REG_WRITE(b,o,v) registerWriteStub(b, o, v)
#define REG_READ(b,o,v) do { v = registerReadStub(b, o); } while (0)
#else
#define REG_WRITE(b,o,v) IX_OSAL_WRITE_LONG((volatile UINT32 *)(b + o), v)
#define REG_READ(b,o,v) (v = IX_OSAL_READ_LONG((volatile UINT32 *)(b + o)))
#endif
void ixEthAccMacUnload(void);
IxEthAccStatus ixEthAccMacMemInit(void);
/* MAC core loopback */
IxEthAccStatus ixEthAccPortLoopbackEnable(IxEthAccPortId portId);
IxEthAccStatus ixEthAccPortLoopbackDisable(IxEthAccPortId portId);
/* MAC core traffic control */
IxEthAccStatus ixEthAccPortTxEnablePriv(IxEthAccPortId portId);
IxEthAccStatus ixEthAccPortTxDisablePriv(IxEthAccPortId portId);
IxEthAccStatus ixEthAccPortRxEnablePriv(IxEthAccPortId portId);
IxEthAccStatus ixEthAccPortRxDisablePriv(IxEthAccPortId portId);
IxEthAccStatus ixEthAccPortMacResetPriv(IxEthAccPortId portId);
/* NPE software loopback */
IxEthAccStatus ixEthAccNpeLoopbackDisablePriv(IxEthAccPortId portId);
IxEthAccStatus ixEthAccNpeLoopbackEnablePriv(IxEthAccPortId portId);
#endif /*IxEthAccMac_p_H*/

View file

@ -0,0 +1,97 @@
/**
* @file IxEthAccMii_p.h
*
* @author Intel Corporation
* @date
*
* @brief MII Header file
*
* Design Notes:
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#ifndef IxEthAccMii_p_H
#define IxEthAccMii_p_H
/* MII definitions - these have been verified against the LXT971 and LXT972 PHYs*/
#define IXP425_ETH_ACC_MII_MAX_REG 32 /* max register per phy */
#define IX_ETH_ACC_MII_REG_SHL 16
#define IX_ETH_ACC_MII_ADDR_SHL 21
/* Definitions for MII access routines*/
#define IX_ETH_ACC_MII_GO BIT(31)
#define IX_ETH_ACC_MII_WRITE BIT(26)
#define IX_ETH_ACC_MII_TIMEOUT_10TH_SECS 5
#define IX_ETH_ACC_MII_10TH_SEC_IN_MILLIS 100
#define IX_ETH_ACC_MII_READ_FAIL BIT(31)
#define IX_ETH_ACC_MII_PHY_DEF_DELAY 300 /* max delay before link up, etc. */
#define IX_ETH_ACC_MII_PHY_NO_DELAY 0x0 /* do not delay */
#define IX_ETH_ACC_MII_PHY_NULL 0xff /* PHY is not present */
#define IX_ETH_ACC_MII_PHY_DEF_ADDR 0x0 /* default PHY's logical address */
#ifndef IX_ETH_ACC_MII_MONITOR_DELAY
# define IX_ETH_ACC_MII_MONITOR_DELAY 0x5 /* in seconds */
#endif
/* Register definition */
#define IX_ETH_ACC_MII_CTRL_REG 0x0 /* Control Register */
#define IX_ETH_ACC_MII_STAT_REG 0x1 /* Status Register */
#define IX_ETH_ACC_MII_PHY_ID1_REG 0x2 /* PHY identifier 1 Register */
#define IX_ETH_ACC_MII_PHY_ID2_REG 0x3 /* PHY identifier 2 Register */
#define IX_ETH_ACC_MII_AN_ADS_REG 0x4 /* Auto-Negotiation */
/* Advertisement Register */
#define IX_ETH_ACC_MII_AN_PRTN_REG 0x5 /* Auto-Negotiation */
/* partner ability Register */
#define IX_ETH_ACC_MII_AN_EXP_REG 0x6 /* Auto-Negotiation */
/* Expansion Register */
#define IX_ETH_ACC_MII_AN_NEXT_REG 0x7 /* Auto-Negotiation */
/* next-page transmit Register */
IxEthAccStatus ixEthAccMdioShow (void);
IxEthAccStatus ixEthAccMiiInit(void);
void ixEthAccMiiUnload(void);
#endif /*IxEthAccMii_p_H*/

View file

@ -0,0 +1,137 @@
/**
* @file IxEthAccQueueAssign_p.h
*
* @author Intel Corporation
* @date 06-Mar-2002
*
* @brief Mapping from QMgr Q's to internal assignment
*
* Design Notes:
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
/**
* @addtogroup IxEthAccPri
*@{
*/
/*
* Os/System dependancies.
*/
#include "IxOsal.h"
/*
* Intermodule dependancies
*/
#include "IxQMgr.h"
#include "IxQueueAssignments.h"
/* Check range of Q's assigned to this component. */
#if IX_ETH_ACC_RX_FRAME_ETH_Q >= (IX_QMGR_MIN_QUEUPP_QID ) | \
IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q >= (IX_QMGR_MIN_QUEUPP_QID) | \
IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q >= (IX_QMGR_MIN_QUEUPP_QID) | \
IX_ETH_ACC_TX_FRAME_ENET0_Q >= (IX_QMGR_MIN_QUEUPP_QID) | \
IX_ETH_ACC_TX_FRAME_ENET1_Q >= (IX_QMGR_MIN_QUEUPP_QID) | \
IX_ETH_ACC_TX_FRAME_DONE_ETH_Q >= (IX_QMGR_MIN_QUEUPP_QID)
#error "Not all Ethernet Access Queues are betweem 1-31, requires full functionalty Q's unless otherwise validated "
#endif
/**
*
* @typedef IxEthAccQregInfo
*
* @brief
*
*/
typedef struct
{
IxQMgrQId qId;
char *qName;
IxQMgrCallback qCallback;
IxQMgrCallbackId callbackTag;
IxQMgrQSizeInWords qSize;
IxQMgrQEntrySizeInWords qWords;
BOOL qNotificationEnableAtStartup;
IxQMgrSourceId qConditionSource;
IxQMgrWMLevel AlmostEmptyThreshold;
IxQMgrWMLevel AlmostFullThreshold;
} IxEthAccQregInfo;
/*
* Prototypes for all QM callbacks.
*/
/*
* Rx Callbacks
*/
IX_ETH_ACC_PUBLIC
void ixEthRxFrameQMCallback(IxQMgrQId, IxQMgrCallbackId);
IX_ETH_ACC_PUBLIC
void ixEthRxMultiBufferQMCallback(IxQMgrQId, IxQMgrCallbackId);
IX_ETH_ACC_PUBLIC
void ixEthRxFreeQMCallback(IxQMgrQId, IxQMgrCallbackId);
/*
* Tx Callback.
*/
IX_ETH_ACC_PUBLIC
void ixEthTxFrameQMCallback(IxQMgrQId, IxQMgrCallbackId);
IX_ETH_ACC_PUBLIC
void ixEthTxFrameDoneQMCallback(IxQMgrQId, IxQMgrCallbackId );
#define IX_ETH_ACC_QM_QUEUE_DISPATCH_PRIORITY (IX_QMGR_Q_PRIORITY_0) /* Highest priority */
/*
* Queue watermarks
*/
#define IX_ETH_ACC_RX_FRAME_ETH_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_NOT_E )
#define IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_E )
#define IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_E )
#define IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_E )
#define IX_ETH_ACC_TX_FRAME_ENET0_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_E )
#define IX_ETH_ACC_TX_FRAME_ENET1_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_E )
#define IX_ETH_ACC_TX_FRAME_ENET2_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_E )
#define IX_ETH_ACC_TX_FRAME_DONE_ETH_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_NOT_E )

View file

@ -0,0 +1,325 @@
/**
* @file IxEthAcc_p.h
*
* @author Intel Corporation
* @date 12-Feb-2002
*
* @brief Internal Header file for IXP425 Ethernet Access component.
*
* Design Notes:
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
/**
* @addtogroup IxEthAccPri
*@{
*/
#ifndef IxEthAcc_p_H
#define IxEthAcc_p_H
/*
* Os/System dependancies.
*/
#include "IxOsal.h"
/*
* Intermodule dependancies
*/
#include "IxNpeDl.h"
#include "IxQMgr.h"
#include "IxEthNpe.h"
/*
* Intra module dependancies
*/
#include "IxEthAccDataPlane_p.h"
#include "IxEthAccMac_p.h"
#define INLINE __inline__
#ifdef NDEBUG
#define IX_ETH_ACC_PRIVATE static
#else
#define IX_ETH_ACC_PRIVATE
#endif /* ndef NDEBUG */
#define IX_ETH_ACC_PUBLIC
#define IX_ETH_ACC_IS_PORT_VALID(port) ((port) < IX_ETH_ACC_NUMBER_OF_PORTS ? TRUE : FALSE )
#ifndef NDEBUG
#define IX_ETH_ACC_FATAL_LOG(a,b,c,d,e,f,g) { ixOsalLog ( IX_OSAL_LOG_LVL_FATAL,IX_OSAL_LOG_DEV_STDOUT,a,b,c,d,e,f,g);}
#define IX_ETH_ACC_WARNING_LOG(a,b,c,d,e,f,g) { ixOsalLog ( IX_OSAL_LOG_LVL_WARNING,IX_OSAL_LOG_DEV_STDOUT,a,b,c,d,e,f,g);}
#define IX_ETH_ACC_DEBUG_LOG(a,b,c,d,e,f,g) { ixOsalLog ( IX_OSAL_LOG_LVL_FATAL,IX_OSAL_LOG_DEV_STDOUT,a,b,c,d,e,f,g);}
#else
#define IX_ETH_ACC_FATAL_LOG(a,b,c,d,e,f,g) { ixOsalLog ( IX_OSAL_LOG_LVL_FATAL,IX_OSAL_LOG_DEV_STDOUT,a,b,c,d,e,f,g);}
#define IX_ETH_ACC_WARNING_LOG(a,b,c,d,e,f,g) { ixOsalLog ( IX_OSAL_LOG_LVL_WARNING,IX_OSAL_LOG_DEV_STDOUT,a,b,c,d,e,f,g);}
#define IX_ETH_ACC_DEBUG_LOG(a,b,c,d,e,f,g) {}
#endif
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccInitDataPlane(void);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccQMgrQueuesConfig(void);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccQMgrRxCallbacksRegister(IxQMgrCallback ixQMgrCallback);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccSingleEthNpeCheck(IxEthAccPortId portId);
IX_ETH_ACC_PUBLIC void ixEthAccQMgrRxQEntryGet(UINT32 *numRxQueueEntries);
/* prototypes for the private control plane functions (used by the control interface wrapper) */
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortEnablePriv(IxEthAccPortId portId);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortDisablePriv(IxEthAccPortId portId);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortEnabledQueryPriv(IxEthAccPortId portId, BOOL *enabled);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortPromiscuousModeClearPriv(IxEthAccPortId portId);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortPromiscuousModeSetPriv(IxEthAccPortId portId);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortUnicastMacAddressSetPriv(IxEthAccPortId portId, IxEthAccMacAddr *macAddr);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortUnicastMacAddressGetPriv(IxEthAccPortId portId, IxEthAccMacAddr *macAddr);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortMulticastAddressJoinPriv(IxEthAccPortId portId, IxEthAccMacAddr *macAddr);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortMulticastAddressJoinAllPriv(IxEthAccPortId portId);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortMulticastAddressLeavePriv(IxEthAccPortId portId, IxEthAccMacAddr *macAddr);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortMulticastAddressLeaveAllPriv(IxEthAccPortId portId);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortUnicastAddressShowPriv(IxEthAccPortId portId);
IX_ETH_ACC_PUBLIC void ixEthAccPortMulticastAddressShowPriv(IxEthAccPortId portId);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortDuplexModeSetPriv(IxEthAccPortId portId, IxEthAccDuplexMode mode);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortDuplexModeGetPriv(IxEthAccPortId portId, IxEthAccDuplexMode *mode);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortTxFrameAppendPaddingEnablePriv(IxEthAccPortId portId);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortTxFrameAppendPaddingDisablePriv(IxEthAccPortId portId);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortTxFrameAppendFCSEnablePriv(IxEthAccPortId portId);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortTxFrameAppendFCSDisablePriv(IxEthAccPortId portId);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortRxFrameAppendFCSEnablePriv(IxEthAccPortId portId);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortRxFrameAppendFCSDisablePriv(IxEthAccPortId portId);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccTxSchedulingDisciplineSetPriv(IxEthAccPortId portId, IxEthAccSchedulerDiscipline sched);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccRxSchedulingDisciplineSetPriv(IxEthAccSchedulerDiscipline sched);
/**
* @struct ixEthAccRxDataStats
* @brief Stats data structures for data path. - Not obtained from h/w
*
*/
typedef struct
{
UINT32 rxFrameClientCallback;
UINT32 rxFreeRepOK;
UINT32 rxFreeRepDelayed;
UINT32 rxFreeRepFromSwQOK;
UINT32 rxFreeRepFromSwQDelayed;
UINT32 rxFreeLateNotificationEnabled;
UINT32 rxFreeLowCallback;
UINT32 rxFreeOverflow;
UINT32 rxFreeLock;
UINT32 rxDuringDisable;
UINT32 rxSwQDuringDisable;
UINT32 rxUnlearnedMacAddress;
UINT32 rxPriority[IX_ETH_ACC_TX_PRIORITY_7 + 1];
UINT32 rxUnexpectedError;
UINT32 rxFiltered;
} IxEthAccRxDataStats;
/**
* @struct IxEthAccTxDataStats
* @brief Stats data structures for data path. - Not obtained from h/w
*
*/
typedef struct
{
UINT32 txQOK;
UINT32 txQDelayed;
UINT32 txFromSwQOK;
UINT32 txFromSwQDelayed;
UINT32 txLowThreshCallback;
UINT32 txDoneClientCallback;
UINT32 txDoneClientCallbackDisable;
UINT32 txOverflow;
UINT32 txLock;
UINT32 txPriority[IX_ETH_ACC_TX_PRIORITY_7 + 1];
UINT32 txLateNotificationEnabled;
UINT32 txDoneDuringDisable;
UINT32 txDoneSwQDuringDisable;
UINT32 txUnexpectedError;
} IxEthAccTxDataStats;
/* port Disable state machine : list of states */
typedef enum
{
/* general port states */
DISABLED = 0,
ACTIVE,
/* particular Tx/Rx states */
REPLENISH,
RECEIVE,
TRANSMIT,
TRANSMIT_DONE
} IxEthAccPortDisableState;
typedef struct
{
BOOL fullDuplex;
BOOL rxFCSAppend;
BOOL txFCSAppend;
BOOL txPADAppend;
BOOL enabled;
BOOL promiscuous;
BOOL joinAll;
IxOsalMutex ackMIBStatsLock;
IxOsalMutex ackMIBStatsResetLock;
IxOsalMutex MIBStatsGetAccessLock;
IxOsalMutex MIBStatsGetResetAccessLock;
IxOsalMutex npeLoopbackMessageLock;
IxEthAccMacAddr mcastAddrsTable[IX_ETH_ACC_MAX_MULTICAST_ADDRESSES];
UINT32 mcastAddrIndex;
IX_OSAL_MBUF *portDisableTxMbufPtr;
IX_OSAL_MBUF *portDisableRxMbufPtr;
volatile IxEthAccPortDisableState portDisableState;
volatile IxEthAccPortDisableState rxState;
volatile IxEthAccPortDisableState txState;
BOOL initDone;
BOOL macInitialised;
} IxEthAccMacState;
/**
* @struct IxEthAccRxInfo
* @brief System-wide data structures associated with the data plane.
*
*/
typedef struct
{
IxQMgrQId higherPriorityQueue[IX_QMGR_MAX_NUM_QUEUES]; /**< higher priority queue list */
IxEthAccSchedulerDiscipline schDiscipline; /**< Receive Xscale QoS type */
} IxEthAccInfo;
/**
* @struct IxEthAccRxDataInfo
* @brief Per Port data structures associated with the receive data plane.
*
*/
typedef struct
{
IxQMgrQId rxFreeQueue; /**< rxFree Queue for this port */
IxEthAccPortRxCallback rxCallbackFn;
UINT32 rxCallbackTag;
IxEthAccDataPlaneQList freeBufferList;
IxEthAccPortMultiBufferRxCallback rxMultiBufferCallbackFn;
UINT32 rxMultiBufferCallbackTag;
BOOL rxMultiBufferCallbackInUse;
IxEthAccRxDataStats stats; /**< Receive s/w stats */
} IxEthAccRxDataInfo;
/**
* @struct IxEthAccTxDataInfo
* @brief Per Port data structures associated with the transmit data plane.
*
*/
typedef struct
{
IxEthAccPortTxDoneCallback txBufferDoneCallbackFn;
UINT32 txCallbackTag;
IxEthAccDataPlaneQList txQ[IX_ETH_ACC_NUM_TX_PRIORITIES]; /**< Transmit Q */
IxEthAccSchedulerDiscipline schDiscipline; /**< Transmit Xscale QoS */
IxQMgrQId txQueue; /**< txQueue for this port */
IxEthAccTxDataStats stats; /**< Transmit s/w stats */
} IxEthAccTxDataInfo;
/**
* @struct IxEthAccPortDataInfo
* @brief Per Port data structures associated with the port data plane.
*
*/
typedef struct
{
BOOL portInitialized;
UINT32 npeId; /**< NpeId for this port */
IxEthAccTxDataInfo ixEthAccTxData; /**< Transmit data control structures */
IxEthAccRxDataInfo ixEthAccRxData; /**< Recieve data control structures */
} IxEthAccPortDataInfo;
extern IxEthAccPortDataInfo ixEthAccPortData[];
#define IX_ETH_IS_PORT_INITIALIZED(port) (ixEthAccPortData[port].portInitialized)
extern BOOL ixEthAccServiceInit;
#define IX_ETH_ACC_IS_SERVICE_INITIALIZED() (ixEthAccServiceInit == TRUE )
/*
* Maximum number of frames to consume from the Rx Frame Q.
*/
#define IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK (128)
/*
* Max number of times to load the Rx Free Q from callback.
*/
#define IX_ETH_ACC_MAX_RX_FREE_BUFFERS_LOAD (256) /* Set greater than depth of h/w Q + drain time at line rate */
/*
* Max number of times to read from the Tx Done Q in one sitting.
*/
#define IX_ETH_ACC_MAX_TX_FRAME_DONE_CONSUME_PER_CALLBACK (256)
/*
* Max number of times to take buffers from S/w queues and write them to the H/w Tx
* queues on receipt of a Tx low threshold callback
*/
#define IX_ETH_ACC_MAX_TX_FRAME_TX_CONSUME_PER_CALLBACK (16)
#define IX_ETH_ACC_FLUSH_CACHE(addr,size) IX_OSAL_CACHE_FLUSH((addr),(size))
#define IX_ETH_ACC_INVALIDATE_CACHE(addr,size) IX_OSAL_CACHE_INVALIDATE((addr),(size))
#define IX_ETH_ACC_MEMSET(start,value,size) memset(start,value,size)
#endif /* ndef IxEthAcc_p_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,122 @@
/**
* @file IxEthAccDBLocks_p.h
*
* @brief Definition of transaction lock stacks and lock utility macros
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#ifndef IxEthAccDBLocks_p_H
#define IxEthAccDBLocks_p_H
#include "IxOsPrintf.h"
/* Lock and lock stacks */
typedef struct
{
IxOsalFastMutex* locks[MAX_LOCKS];
UINT32 stackPointer, basePointer;
} LockStack;
#define TRY_LOCK(mutex) \
{ \
if (ixOsalFastMutexTryLock(mutex) != IX_SUCCESS) \
{ \
return IX_ETH_DB_BUSY; \
} \
}
#define UNLOCK(mutex) { ixOsalFastMutexUnlock(mutex); }
#define INIT_STACK(stack) \
{ \
(stack)->basePointer = 0; \
(stack)->stackPointer = 0; \
}
#define PUSH_LOCK(stack, lock) \
{ \
if ((stack)->stackPointer == MAX_LOCKS) \
{ \
ERROR_LOG("Ethernet DB: maximum number of elements in a lock stack has been exceeded on push, heavy chaining?\n"); \
UNROLL_STACK(stack); \
\
return IX_ETH_DB_NOMEM; \
} \
\
if (ixOsalFastMutexTryLock(lock) == IX_SUCCESS) \
{ \
(stack)->locks[(stack)->stackPointer++] = (lock); \
} \
else \
{ \
UNROLL_STACK(stack); \
\
return IX_ETH_DB_BUSY; \
} \
}
#define POP_LOCK(stack) \
{ \
ixOsalFastMutexUnlock((stack)->locks[--(stack)->stackPointer]); \
}
#define UNROLL_STACK(stack) \
{ \
while ((stack)->stackPointer > (stack)->basePointer) \
{ \
POP_LOCK(stack); \
} \
}
#define SHIFT_STACK(stack) \
{ \
if ((stack)->basePointer == MAX_LOCKS - 1) \
{ \
ERROR_LOG("Ethernet DB: maximum number of elements in a lock stack has been exceeded on shift, heavy chaining?\n"); \
UNROLL_STACK(stack); \
\
return IX_ETH_DB_BUSY; \
} \
\
ixOsalFastMutexUnlock((stack)->locks[(stack)->basePointer++]); \
}
#endif /* IxEthAccDBLocks_p_H */

View file

@ -0,0 +1,227 @@
/**
* @file IxEthDBLog_p.h
*
* @brief definitions of log macros and log configuration
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#include <IxOsal.h>
#ifdef IX_UNIT_TEST
#define NULL_PRINT_ROUTINE(format, arg...) /* nothing */
#else
#define NULL_PRINT_ROUTINE if(0) printf
#endif
/***************************************************
* Globals *
***************************************************/
/* safe to permanently leave these on */
#define HAS_ERROR_LOG
#define HAS_ERROR_IRQ_LOG
#define HAS_WARNING_LOG
/***************************************************
* Log Configuration *
***************************************************/
/* debug output can be turned on unless specifically
declared as a non-debug build */
#ifndef NDEBUG
#undef HAS_EVENTS_TRACE
#undef HAS_EVENTS_VERBOSE_TRACE
#undef HAS_SUPPORT_TRACE
#undef HAS_SUPPORT_VERBOSE_TRACE
#undef HAS_NPE_TRACE
#undef HAS_NPE_VERBOSE_TRACE
#undef HAS_DUMP_NPE_TREE
#undef HAS_UPDATE_TRACE
#undef HAS_UPDATE_VERBOSE_TRACE
#endif /* NDEBUG */
/***************************************************
* Log Macros *
***************************************************/
/************** Globals ******************/
#ifdef HAS_ERROR_LOG
#define ERROR_LOG printf
#else
#define ERROR_LOG NULL_PRINT_ROUTINE
#endif
#ifdef HAS_ERROR_IRQ_LOG
#define ERROR_IRQ_LOG(format, arg1, arg2, arg3, arg4, arg5, arg6) ixOsalLog(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, format, arg1, arg2, arg3, arg4, arg5, arg6)
#else
#define ERROR_IRQ_LOG(format, arg1, arg2, arg3, arg4, arg5, arg6) /* nothing */
#endif
#ifdef HAS_WARNING_LOG
#define WARNING_LOG printf
#else
#define WARNING_LOG NULL_PRINT_ROUTINE
#endif
/************** Events *******************/
#ifdef HAS_EVENTS_TRACE
#define IX_ETH_DB_EVENTS_TRACE printf
#define IX_ETH_DB_IRQ_EVENTS_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, format, arg1, arg2, arg3, arg4, arg5, arg6)
#ifdef HAS_EVENTS_VERBOSE_TRACE
#define IX_ETH_DB_EVENTS_VERBOSE_TRACE printf
#else
#define IX_ETH_DB_EVENTS_VERBOSE_TRACE NULL_PRINT_ROUTINE
#endif /* HAS_EVENTS_VERBOSE_TRACE */
#else
#define IX_ETH_DB_EVENTS_TRACE NULL_PRINT_ROUTINE
#define IX_ETH_DB_EVENTS_VERBOSE_TRACE NULL_PRINT_ROUTINE
#define IX_ETH_DB_IRQ_EVENTS_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) /* nothing */
#endif /* HAS_EVENTS_TRACE */
/************** Support *******************/
#ifdef HAS_SUPPORT_TRACE
#define IX_ETH_DB_SUPPORT_TRACE printf
#define IX_ETH_DB_SUPPORT_IRQ_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, format, arg1, arg2, arg3, arg4, arg5, arg6)
#ifdef HAS_SUPPORT_VERBOSE_TRACE
#define IX_ETH_DB_SUPPORT_VERBOSE_TRACE printf
#else
#define IX_ETH_DB_SUPPORT_VERBOSE_TRACE NULL_PRINT_ROUTINE
#endif /* HAS_SUPPORT_VERBOSE_TRACE */
#else
#define IX_ETH_DB_SUPPORT_TRACE NULL_PRINT_ROUTINE
#define IX_ETH_DB_SUPPORT_VERBOSE_TRACE NULL_PRINT_ROUTINE
#define IX_ETH_DB_SUPPORT_IRQ_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) /* nothing */
#endif /* HAS_SUPPORT_TRACE */
/************** NPE Adaptor *******************/
#ifdef HAS_NPE_TRACE
#define IX_ETH_DB_NPE_TRACE printf
#define IX_ETH_DB_NPE_IRQ_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, format, arg1, arg2, arg3, arg4, arg5, arg6)
#ifdef HAS_NPE_VERBOSE_TRACE
#define IX_ETH_DB_NPE_VERBOSE_TRACE printf
#else
#define IX_ETH_DB_NPE_VERBOSE_TRACE NULL_PRINT_ROUTINE
#endif /* HAS_NPE_VERBOSE_TRACE */
#else
#define IX_ETH_DB_NPE_TRACE NULL_PRINT_ROUTINE
#define IX_ETH_DB_NPE_VERBOSE_TRACE NULL_PRINT_ROUTINE
#define IX_ETH_DB_NPE_IRQ_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) /* nothing */
#endif /* HAS_NPE_TRACE */
#ifdef HAS_DUMP_NPE_TREE
#define IX_ETH_DB_NPE_DUMP_ELT(eltBaseAddress, eltSize) ixEthELTDumpTree(eltBaseAddress, eltSize)
#else
#define IX_ETH_DB_NPE_DUMP_ELT(eltBaseAddress, eltSize) /* nothing */
#endif /* HAS_DUMP_NPE_TREE */
/************** Port Update *******************/
#ifdef HAS_UPDATE_TRACE
#define IX_ETH_DB_UPDATE_TRACE printf
#ifdef HAS_UPDATE_VERBOSE_TRACE
#define IX_ETH_DB_UPDATE_VERBOSE_TRACE printf
#else
#define IX_ETH_DB_UPDATE_VERBOSE_TRACE NULL_PRINT_ROUTINE
#endif
#else /* HAS_UPDATE_VERBOSE_TRACE */
#define IX_ETH_DB_UPDATE_TRACE NULL_PRINT_ROUTINE
#define IX_ETH_DB_UPDATE_VERBOSE_TRACE NULL_PRINT_ROUTINE
#endif /* HAS_UPDATE_TRACE */

View file

@ -0,0 +1,258 @@
/**
* @file IxEthDBMessages_p.h
*
* @brief Definitions of NPE messages
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#ifndef IxEthDBMessages_p_H
#define IxEthDBMessages_p_H
#include <IxEthNpe.h>
#include <IxOsCacheMMU.h>
#include "IxEthDB_p.h"
/* events watched by the Eth event processor */
#define IX_ETH_DB_MIN_EVENT_ID (IX_ETHNPE_EDB_GETMACADDRESSDATABASE)
#define IX_ETH_DB_MAX_EVENT_ID (IX_ETHNPE_PC_SETAPMACTABLE)
/* macros to fill and extract data from NPE messages - place any endian conversions here */
#define RESET_ELT_MESSAGE(message) { memset((void *) &(message), 0, sizeof((message))); }
#define NPE_MSG_ID(msg) ((msg).data[0] >> 24)
#define FILL_SETPORTVLANTABLEENTRY_MSG(message, portID, setOffset, vlanMembershipSet, ttiSet) \
do { \
message.data[0] = (IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY << 24) | (portID << 16) | (setOffset * 2); \
message.data[1] = (vlanMembershipSet << 8) | ttiSet; \
} while (0);
#define FILL_SETPORTVLANTABLERANGE_MSG(message, portID, offset, length, zone) \
do { \
message.data[0] = IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE << 24 | portID << 16 | offset << 9 | length << 1; \
message.data[1] = (UINT32) zone; \
} while (0);
#define FILL_SETDEFAULTRXVID_MSG(message, portID, tpid, vlanTag) \
do { \
message.data[0] = (IX_ETHNPE_VLAN_SETDEFAULTRXVID << 24) \
| (portID << 16); \
\
message.data[1] = (tpid << 16) | vlanTag; \
} while (0);
#define FILL_SETRXTAGMODE_MSG(message, portID, filterMode, tagMode) \
do { \
message.data[0] = IX_ETHNPE_VLAN_SETRXTAGMODE << 24 \
| portID << 16 \
| filterMode << 2 \
| tagMode; \
\
message.data[1] = 0; \
} while (0);
#define FILL_SETRXQOSENTRY(message, portID, classIndex, trafficClass, aqmQueue) \
do { \
message.data[0] = IX_ETHNPE_VLAN_SETRXQOSENTRY << 24 \
| portID << 16 \
| classIndex; \
\
message.data[1] = trafficClass << 24 \
| 0x1 << 23 \
| aqmQueue << 16 \
| aqmQueue << 4; \
} while (0);
#define FILL_SETPORTIDEXTRACTIONMODE(message, portID, enable) \
do { \
message.data[0] = IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE << 24 \
| portID << 16 \
| (enable ? 0x1 : 0x0); \
\
message.data[1] = 0; \
} while (0);
#define FILL_SETBLOCKINGSTATE_MSG(message, portID, blocked) \
do { \
message.data[0] = IX_ETHNPE_STP_SETBLOCKINGSTATE << 24 \
| portID << 16 \
| (blocked ? 0x1 : 0x0); \
\
message.data[1] = 0; \
} while (0);
#define FILL_SETBBSID_MSG(message, portID, bbsid) \
do { \
message.data[0] = IX_ETHNPE_PC_SETBBSID << 24 \
| portID << 16 \
| bbsid->macAddress[0] << 8 \
| bbsid->macAddress[1]; \
\
message.data[1] = bbsid->macAddress[2] << 24 \
| bbsid->macAddress[3] << 16 \
| bbsid->macAddress[4] << 8 \
| bbsid->macAddress[5]; \
} while (0);
#define FILL_SETFRAMECONTROLDURATIONID(message, portID, frameControlDurationID) \
do { \
message.data[0] = (IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID << 24) | (portID << 16); \
message.data[1] = frameControlDurationID; \
} while (0);
#define FILL_SETAPMACTABLE_MSG(message, zone) \
do { \
message.data[0] = IX_ETHNPE_PC_SETAPMACTABLE << 24 \
| 0 << 8 /* always use index 0 */ \
| 64; /* 32 entries, 8 bytes each, 4 bytes in a word */ \
message.data[1] = (UINT32) zone; \
} while (0);
#define FILL_SETFIREWALLMODE_MSG(message, portID, epDelta, mode, address) \
do { \
message.data[0] = IX_ETHNPE_FW_SETFIREWALLMODE << 24 \
| portID << 16 \
| (epDelta & 0xFF) << 8 \
| mode; \
\
message.data[1] = (UINT32) address; \
} while (0);
#define FILL_SETMACADDRESSDATABASE_MSG(message, portID, epDelta, blockCount, address) \
do { \
message.data[0] = IX_ETHNPE_EDB_SETMACADDRESSSDATABASE << 24 \
| (epDelta & 0xFF) << 8 \
| (blockCount & 0xFF); \
\
message.data[1] = (UINT32) address; \
} while (0);
#define FILL_GETMACADDRESSDATABASE(message, npeId, zone) \
do { \
message.data[0] = IX_ETHNPE_EDB_GETMACADDRESSDATABASE << 24; \
message.data[1] = (UINT32) zone; \
} while (0);
#define FILL_SETMAXFRAMELENGTHS_MSG(message, portID, maxRxFrameSize, maxTxFrameSize) \
do { \
message.data[0] = IX_ETHNPE_SETMAXFRAMELENGTHS << 24 \
| portID << 16 \
| ((maxRxFrameSize + 63) / 64) << 8 /* max Rx 64-byte blocks */ \
| (maxTxFrameSize + 63) / 64; /* max Tx 64-byte blocks */ \
\
message.data[1] = maxRxFrameSize << 16 | maxTxFrameSize; \
} while (0);
#define FILL_SETPORTADDRESS_MSG(message, portID, macAddress) \
do { \
message.data[0] = IX_ETHNPE_EDB_SETPORTADDRESS << 24 \
| portID << 16 \
| macAddress[0] << 8 \
| macAddress[1]; \
\
message.data[1] = macAddress[2] << 24 \
| macAddress[3] << 16 \
| macAddress[4] << 8 \
| macAddress[5]; \
} while (0);
/* access to a MAC node in the NPE tree */
#define NPE_NODE_BYTE(eltNodeAddr, offset) (((UINT8 *) (eltNodeAddr))[offset])
/* browsing of the implicit linear binary tree structure of the NPE tree */
#define LEFT_CHILD_OFFSET(offset) ((offset) << 1)
#define RIGHT_CHILD_OFFSET(offset) (((offset) << 1) + 1)
#define IX_EDB_FLAGS_ACTIVE (0x2)
#define IX_EDB_FLAGS_VALID (0x1)
#define IX_EDB_FLAGS_RESERVED (0xfc)
#define IX_EDB_FLAGS_INACTIVE_VALID (0x1)
#define IX_EDB_NPE_NODE_ELT_PORT_ID_OFFSET (6)
#define IX_EDB_NPE_NODE_ELT_FLAGS_OFFSET (7)
#define IX_EDB_NPE_NODE_WIFI_INDEX_OFFSET (6)
#define IX_EDB_NPE_NODE_WIFI_FLAGS_OFFSET (7)
#define IX_EDB_NPE_NODE_FW_FLAGS_OFFSET (1)
#define IX_EDB_NPE_NODE_FW_RESERVED_OFFSET (6)
#define IX_EDB_NPE_NODE_FW_ADDR_OFFSET (2)
#define IX_EDB_NPE_NODE_VALID(address) ((NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_FLAGS_OFFSET) & IX_EDB_FLAGS_VALID) != 0)
#define IX_EDB_NPE_NODE_ACTIVE(address) ((NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_FLAGS_OFFSET) & IX_EDB_FLAGS_ACTIVE) != 0)
#define IX_EDB_NPE_NODE_PORT_ID(address) (NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_PORT_ID_OFFSET))
/* macros to send messages to the NPEs */
#define IX_ETHDB_ASYNC_SEND_NPE_MSG(npeId, msg, result) \
do { \
result = ixNpeMhMessageSend(npeId, msg, IX_NPEMH_SEND_RETRIES_DEFAULT); \
\
if (result != IX_SUCCESS) \
{ \
ERROR_LOG("DB: Failed to send NPE message\n"); \
} \
} while (0);
#define IX_ETHDB_SYNC_SEND_NPE_MSG(npeId, msg, result) \
do { \
result = ixNpeMhMessageWithResponseSend(npeId, msg, msg.data[0] >> 24, ixEthDBNpeMsgAck, IX_NPEMH_SEND_RETRIES_DEFAULT); \
\
if (result == IX_SUCCESS) \
{ \
result = ixOsalMutexLock(&ixEthDBPortInfo[IX_ETH_DB_NPE_TO_PORT_ID(npeId)].npeAckLock, IX_ETH_DB_NPE_TIMEOUT); \
\
if (result != IX_SUCCESS) \
{ \
ERROR_LOG("DB: NPE failed to respond within %dms\n", IX_ETH_DB_NPE_TIMEOUT); \
} \
} \
else \
{ \
ERROR_LOG("DB: Failed to send NPE message\n"); \
} \
} while (0);
#ifndef IX_NDEBUG
#define IX_ETH_DB_NPE_MSG_HISTORY_DEPTH (100)
extern IX_ETH_DB_PUBLIC UINT32 npeMsgHistory[IX_ETH_DB_NPE_MSG_HISTORY_DEPTH][2];
extern IX_ETH_DB_PUBLIC UINT32 npeMsgHistoryLen;
#endif
#define IX_ETHDB_SEND_NPE_MSG(npeId, msg, result) { LOG_NPE_MSG(msg); IX_ETHDB_SYNC_SEND_NPE_MSG(npeId, msg, result); }
#endif /* IxEthDBMessages_p_H */

View file

@ -0,0 +1,163 @@
/**
* @file IxEthDBPortDefs.h
*
* @brief Public definition of the ports and port capabilities
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
/**
* @defgroup IxEthDBPortDefs IXP400 Ethernet Database Port Definitions (IxEthDBPortDefs)
*
* @brief IXP400 Public definition of the ports and port capabilities
*
* @{
*/
#ifndef IxEthDBPortDefs_H
#define IxEthDBPortDefs_H
/**
* @brief Port types - currently only Ethernet NPEs are recognized as specific types
* All other (user-defined) ports must be specified as IX_ETH_GENERIC
*/
typedef enum
{
IX_ETH_GENERIC = 0, /**< generic ethernet port */
IX_ETH_NPE /**< specific Ethernet NPE */
} IxEthDBPortType;
/**
* @brief Port capabilities - used by ixEthAccDatabaseMaintenance to decide whether it
* should manually age entries or not depending on the port capabilities.
*
* Ethernet NPEs have aging capabilities, meaning that they will age the entries
* automatically (by themselves).*/
typedef enum
{
IX_ETH_NO_CAPABILITIES = 0, /**< no aging capabilities */
IX_ETH_ENTRY_AGING = 0x1 /**< aging capabilities present */
} IxEthDBPortCapability;
/**
* @brief Port Definition - a structure contains the Port type and capabilities
*/
typedef struct
{
IxEthDBPortType type;
IxEthDBPortCapability capabilities;
} IxEthDBPortDefinition;
/**
* @brief Port definitions structure, indexed on the port ID
* @warning Ports 0 and 1 are used by the Ethernet access component therefore
* it is essential to be left untouched. Port 2 here (WAN) is given as
* an example port. The NPE firmware also assumes the NPE B to be
* the port 0 and NPE C to be the port 1.
*
* @note that only 32 ports (0..31) are supported by EthDB
*/
static const IxEthDBPortDefinition ixEthDBPortDefinitions[] =
{
/* id type capabilities */
{ /* 0 */ IX_ETH_NPE, IX_ETH_NO_CAPABILITIES }, /* Ethernet NPE B */
{ /* 1 */ IX_ETH_NPE, IX_ETH_NO_CAPABILITIES }, /* Ethernet NPE C */
{ /* 2 */ IX_ETH_NPE, IX_ETH_NO_CAPABILITIES }, /* Ethernet NPE A */
{ /* 3 */ IX_ETH_GENERIC, IX_ETH_NO_CAPABILITIES }, /* WAN port */
};
/**
* @def IX_ETH_DB_NUMBER_OF_PORTS
* @brief number of supported ports
*/
#define IX_ETH_DB_NUMBER_OF_PORTS (sizeof (ixEthDBPortDefinitions) / sizeof (ixEthDBPortDefinitions[0]))
/**
* @def IX_ETH_DB_UNKNOWN_PORT
* @brief definition of an unknown port
*/
#define IX_ETH_DB_UNKNOWN_PORT (0xff)
/**
* @def IX_ETH_DB_ALL_PORTS
* @brief Special port ID indicating all the ports
* @note This port ID can be used only by a subset of the EthDB API; each
* function specifically mentions whether this is a valid parameter as the port ID
*/
#define IX_ETH_DB_ALL_PORTS (IX_ETH_DB_NUMBER_OF_PORTS + 1)
/**
* @def IX_ETH_DB_PORTS_ASSERTION
* @brief catch invalid port definitions (<2) with a
* compile-time assertion resulting in a duplicate case error.
*/
#define IX_ETH_DB_PORTS_ASSERTION { switch(0) { case 0 : ; case 1 : ; case IX_ETH_DB_NUMBER_OF_PORTS : ; }}
/**
* @def IX_ETH_DB_CHECK_PORT(portID)
* @brief safety checks to verify whether the port is invalid or uninitialized
*/
#define IX_ETH_DB_CHECK_PORT(portID) \
{ \
if ((portID) >= IX_ETH_DB_NUMBER_OF_PORTS) \
{ \
return IX_ETH_DB_INVALID_PORT; \
} \
\
if (!ixEthDBPortInfo[(portID)].enabled) \
{ \
return IX_ETH_DB_PORT_UNINITIALIZED; \
} \
}
/**
* @def IX_ETH_DB_CHECK_PORT_ALL(portID)
* @brief safety checks to verify whether the port is invalid or uninitialized;
* tolerates the use of IX_ETH_DB_ALL_PORTS
*/
#define IX_ETH_DB_CHECK_PORT_ALL(portID) \
{ \
if ((portID) != IX_ETH_DB_ALL_PORTS) \
IX_ETH_DB_CHECK_PORT(portID) \
}
#endif /* IxEthDBPortDefs_H */
/**
*@}
*/

View file

@ -0,0 +1,154 @@
/**
* @file IxEthDBQoS.h
*
* @brief Public definitions for QoS traffic classes
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
/**
* @defgroup IxEthDBPortDefs IXP400 Ethernet QoS definitions
*
* @brief IXP00 Public definitions for QoS traffic classes
*
* @{
*/
#ifndef IxEthDBQoS_H
#define IxEthDBQoS_H
/**
* @def IX_ETH_DB_QUEUE_UNAVAILABLE
* @brief alias to indicate a queue (traffic class) is not available
*/
#define IX_ETH_DB_QUEUE_UNAVAILABLE (0)
#ifndef IX_IEEE802_1Q_QOS_PRIORITY_COUNT
/**
* @def IX_IEEE802_1Q_QOS_PRIORITY_COUNT
* @brief number of QoS priorities, according to IEEE 802.1Q
*/
#define IX_IEEE802_1Q_QOS_PRIORITY_COUNT (8)
#endif
/**
* @brief array containing all the supported traffic class configurations
*/
static const
UINT8 ixEthDBQueueAssignments[][IX_IEEE802_1Q_QOS_PRIORITY_COUNT] =
{
{ 4, 5, 6, 7, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE },
{ 15, 16, 17, 18, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE },
{ 11, 23, 26, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE },
{ 4, 5, 6, 7, 8, 9, 10, 11 }
/* add here all other cases of queue configuration structures and update ixEthDBTrafficClassDefinitions to use them */
};
/**
* @brief value used to index the NPE A functionality ID in the traffic class definition table
*/
#define IX_ETH_DB_NPE_A_FUNCTIONALITY_ID_INDEX (0)
/**
* @brief value used to index the traffic class count in the traffic class definition table
*/
#define IX_ETH_DB_TRAFFIC_CLASS_COUNT_INDEX (1)
/**
* @brief value used to index the queue assignment index in the traffic class definition table
*/
#define IX_ETH_DB_QUEUE_ASSIGNMENT_INDEX (2)
/**
* @brief traffic class definitions
*
* This array contains the default traffic class definition configuration,
* as well as any special cases dictated by the functionality ID of NPE A.
*
* The default case should not be removed (otherwise the Ethernet
* components will assert a fatal failure on initialization).
*/
static const
UINT8 ixEthDBTrafficClassDefinitions[][3] =
{
/* NPE A functionality ID | traffic class count | queue assignment index (points to the queue enumeration in ixEthDBQueueAssignments) */
{ 0x00, 4, 0 }, /* default case - DO NOT REMOVE */
{ 0x04, 4, 1 }, /* NPE A image ID 0.4.0.0 */
{ 0x09, 3, 2 }, /* NPE A image ID 0.9.0.0 */
{ 0x80, 8, 3 }, /* NPE A image ID 10.80.02.0 */
{ 0x81, 8, 3 }, /* NPE A image ID 10.81.02.0 */
{ 0x82, 8, 3 } /* NPE A image ID 10.82.02.0 */
};
/**
* @brief IEEE 802.1Q recommended QoS Priority => traffic class maps
*
* @verbatim
Number of available traffic classes
1 2 3 4 5 6 7 8
QoS Priority
0 0 0 0 1 1 1 1 2
1 0 0 0 0 0 0 0 0
2 0 0 0 0 0 0 0 1
3 0 0 0 1 1 2 2 3
4 0 1 1 2 2 3 3 4
5 0 1 1 2 3 4 4 5
6 0 1 2 3 4 5 5 6
7 0 1 2 3 4 5 6 7
@endverbatim
*/
static const
UINT8 ixEthIEEE802_1QUserPriorityToTrafficClassMapping[IX_IEEE802_1Q_QOS_PRIORITY_COUNT][IX_IEEE802_1Q_QOS_PRIORITY_COUNT] =
{
{ 0, 0, 0, 0, 0, 0, 0, 0 }, /* 1 traffic class available */
{ 0, 0, 0, 0, 1, 1, 1, 1 }, /* 2 traffic classes available */
{ 0, 0, 0, 0, 1, 1, 2, 2 }, /* 3 traffic classes available */
{ 1, 0, 0, 1, 2, 2, 3, 3 }, /* 4 traffic classes available */
{ 1, 0, 0, 1, 2, 3, 4, 4 }, /* 5 traffic classes available */
{ 1, 0, 0, 2, 3, 4, 5, 5 }, /* 6 traffic classes available */
{ 1, 0, 0, 2, 3, 4, 5, 6 }, /* 7 traffic classes available */
{ 2, 0, 1, 3, 4, 5, 6, 7 } /* 8 traffic classes available */
};
#endif /* IxEthDBQoS_H */
/**
*@}
*/

View file

@ -0,0 +1,712 @@
/**
* @file IxEthDB_p.h
*
* @brief Private MAC learning API
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#ifndef IxEthDB_p_H
#define IxEthDB_p_H
#include <IxTypes.h>
#include <IxOsal.h>
#include <IxEthDB.h>
#include <IxNpeMh.h>
#include <IxEthDBPortDefs.h>
#include "IxEthDBMessages_p.h"
#include "IxEthDBLog_p.h"
#if (CPU==SIMSPARCSOLARIS)
/* when running unit tests intLock() won't protect the event queue so we lock it manually */
#define TEST_FIXTURE_LOCK_EVENT_QUEUE { ixOsalMutexLock(&eventQueueLock, IX_OSAL_WAIT_FOREVER); }
#define TEST_FIXTURE_UNLOCK_EVENT_QUEUE { ixOsalMutexUnlock(&eventQueueLock); }
#else
#define TEST_FIXTURE_LOCK_EVENT_QUEUE /* nothing */
#define TEST_FIXTURE_UNLOCK_EVENT_QUEUE /* nothing */
#endif /* #if(CPU==SIMSPARCSOLARIS) */
#ifndef IX_UNIT_TEST
#define TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER /* nothing */
#define TEST_FIXTURE_MARK_OVERFLOW_EVENT /* nothing */
#else
extern int dbAccessCounter;
extern int overflowEvent;
#define TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER { dbAccessCounter++; }
#define TEST_FIXTURE_MARK_OVERFLOW_EVENT { overflowEvent = 1; }
#endif
/* code readability markers */
#define __mempool__ /* memory pool marker */
#define __lock__ /* hash write locking marker */
#define __smartpointer__ /* smart pointer marker - warning: use only clone() when duplicating! */
#define __alignment__ /* marker for data used only as alignment zones */
/* constants */
#define IX_ETH_DB_NPE_TIMEOUT (100) /* NPE response timeout, in ms */
/**
* number of hash table buckets
* it should be at least 8x the predicted number of entries for performance
* each bucket needs 8 bytes
*/
#define NUM_BUCKETS (8192)
/**
* number of hash table buckets to preload when incrementing bucket iterator
* = two cache lines
*/
#define IX_ETHDB_CACHE_LINE_AHEAD (2)
#define IX_ETHDB_BUCKETPTR_AHEAD ((IX_ETHDB_CACHE_LINE_AHEAD * IX_OSAL_CACHE_LINE_SIZE)/sizeof(void *))
#define IX_ETHDB_BUCKET_INDEX_MASK (((IX_OSAL_CACHE_LINE_SIZE)/sizeof(void *)) - 1)
/* locks */
#define MAX_LOCKS (20) /**< maximum number of locks used simultaneously, do not tamper with */
/* learning tree constants */
#define INITIAL_ELT_SIZE (8) /**< initial byte size of tree (empty unused root size) */
#define MAX_ELT_SIZE (512) /**< maximum number of entries (includes unused root) */
#define MAX_GW_SIZE (32) /**< maximum number of gateway entries (including unused root) */
#define MAX_FW_SIZE (32) /**< maximum number of firewall entries (including unused root) */
#define ELT_ENTRY_SIZE (8) /**< entry size, in bytes */
#define ELT_ROOT_OFFSET (ELT_ENTRY_SIZE) /**< tree root offset, in bytes - node preceeding root is unused */
#define FULL_ELT_BYTE_SIZE (MAX_ELT_SIZE * ELT_ENTRY_SIZE) /**< full size of tree, in bytes, including unused root */
#define FULL_GW_BYTE_SIZE (MAX_GW_SIZE * ELT_ENTRY_SIZE) /**< full size of gateway list, in bytes, including unused root */
#define FULL_FW_BYTE_SIZE (MAX_FW_SIZE * ELT_ENTRY_SIZE) /**< full size of firewall table, in bytes, including unused root */
/* maximum size of the VLAN table:
* 4096 bits (one per VLAN)
* 8 bits in one byte
* interleaved VLAN membership and VLAN TTI (*2) */
#define FULL_VLAN_BYTE_SIZE (4096 / 8 * 2)
/* upper 9 bits used as set index, lower 3 bits as byte index */
#define VLAN_SET_OFFSET(vlanID) ((vlanID) >> 3)
#define VLAN_SET_MASK(vlanID) (0x7 - ((vlanID) & 0x7))
/* Update zone definitions */
#define NPE_TREE_MEM_SIZE (4096) /* ((511 entries + 1 unused root) * 8 bytes/entry) */
/* check the above value, we rely on 4k */
#if NPE_TREE_MEM_SIZE != 4096
#error NPE_TREE_MEM_SIZE is not defined to 4096 bytes!
#endif
/* Size Filtering limits (Jumbo frame filtering) */
#define IX_ETHDB_MAX_FRAME_SIZE 65535 /* other ports than NPE ports */
#define IX_ETHDB_MIN_FRAME_SIZE 1 /* other ports than NPE ports */
#define IX_ETHDB_MAX_NPE_FRAME_SIZE 16320 /* NPE ports firmware limit */
#define IX_ETHDB_MIN_NPE_FRAME_SIZE 1 /* NPE ports firmware limit */
#define IX_ETHDB_DEFAULT_FRAME_SIZE 1522
/* memory management pool sizes */
/*
* Note:
*
* NODE_POOL_SIZE controls the maximum number of elements in the database at any one time.
* It should be large enough to cover all the search trees of all the ports simultaneously.
*
* MAC_POOL_SIZE should be higher than NODE_POOL_SIZE by at least the total number of MAC addresses
* possible to be held at any time in all the ports.
*
* TREE_POOL_SIZE should follow the same guideline as for MAC_POOL_SIZE.
*
* The database structure described here (2000/4000/4000) is enough for two NPEs holding at most 511
* entries each plus one PCI NIC holding at most 900 entries.
*/
#define NODE_POOL_SIZE (2000) /**< number of HashNode objects - also master number of elements in the database; each entry has 16 bytes */
#define MAC_POOL_SIZE (4000) /**< number of MacDescriptor objects; each entry has 28 bytes */
#define TREE_POOL_SIZE (4000) /**< number of MacTreeNode objects; each entry has 16 bytes */
/* retry policies */
#define BUSY_RETRY_ENABLED (TRUE) /**< if set to TRUE the API will retry automatically calls returning BUSY */
#define FOREVER_RETRY (TRUE) /**< if set to TRUE the API will retry forever BUSY calls */
#define MAX_RETRIES (400) /**< upper retry limit - used only when FOREVER_RETRY is FALSE */
#define BUSY_RETRY_YIELD (5) /**< ticks to yield for every failed retry */
/* event management */
#define EVENT_QUEUE_SIZE (500) /**< size of the sink collecting events from the Message Handler FIFO */
#define EVENT_PROCESSING_LIMIT (100) /**< batch processing control size (how many events are extracted from the queue at once) */
/* MAC descriptors */
#define STATIC_ENTRY (TRUE)
#define DYNAMIC_ENTRY (FALSE)
/* age reset on next maintenance - incrementing by 1 will reset to 0 */
#define AGE_RESET (0xFFFFFFFF)
/* dependency maps */
#define EMPTY_DEPENDENCY_MAP (0)
/* trees */
#define RIGHT (1)
#define LEFT (-1)
/* macros */
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define IX_ETH_DB_CHECK_PORT_EXISTS(portID) \
{ \
if ((portID) >= IX_ETH_DB_NUMBER_OF_PORTS) \
{ \
return IX_ETH_DB_INVALID_PORT; \
} \
}
#define IX_ETH_DB_CHECK_PORT_INITIALIZED(portID) \
{ \
if ((portID) >= IX_ETH_DB_NUMBER_OF_PORTS) \
{ \
return IX_ETH_DB_INVALID_PORT; \
} \
else \
{ \
if (!ixEthDBPortInfo[portID].initialized) \
{ \
return IX_ETH_DB_PORT_UNINITIALIZED; \
} \
} \
}
/* single NPE check */
#define IX_ETH_DB_CHECK_SINGLE_NPE(portID) \
if (ixEthDBSingleEthNpeCheck(portID) != IX_ETH_DB_SUCCESS) \
{ \
WARNING_LOG("EthDB: port ID %d is unavailable\n",(UINT32) portID); \
\
return IX_ETH_DB_INVALID_PORT; \
}
/* feature check */
#define IX_ETH_DB_CHECK_FEATURE(portID, feature) \
if ((ixEthDBPortInfo[portID].featureStatus & feature) == 0) \
{ \
return IX_ETH_DB_FEATURE_UNAVAILABLE; \
}
/* busy retrying */
#define BUSY_RETRY(functionCall) \
{ \
UINT32 retries = 0; \
IxEthDBStatus br_result; \
\
while ((br_result = functionCall) == IX_ETH_DB_BUSY \
&& BUSY_RETRY_ENABLED && (FOREVER_RETRY || ++retries < MAX_RETRIES)) { ixOsalSleep(BUSY_RETRY_YIELD); }; \
\
if ((!FOREVER_RETRY && retries == MAX_RETRIES) || (br_result == IX_ETH_DB_FAIL)) \
{\
ERROR_LOG("Ethernet Learning Database Error: BUSY_RETRY failed at %s:%d\n", __FILE__, __LINE__); \
}\
}
#define BUSY_RETRY_WITH_RESULT(functionCall, brwr_result) \
{ \
UINT32 retries = 0; \
\
while ((brwr_result = functionCall) == IX_ETH_DB_BUSY \
&& BUSY_RETRY_ENABLED && (FOREVER_RETRY || ++retries < MAX_RETRIES)) { ixOsalSleep(BUSY_RETRY_YIELD); }; \
\
if ((!FOREVER_RETRY && retries == MAX_RETRIES) || (brwr_result == IX_ETH_DB_FAIL)) \
{\
ERROR_LOG("Ethernet Learning Database Error: BUSY_RETRY_WITH_RESULT failed at %s:%d\n", __FILE__, __LINE__); \
}\
}
/* iterators */
#define IS_ITERATOR_VALID(iteratorPtr) ((iteratorPtr)->node != NULL)
/* dependency port maps */
/* Warning: if port indexing starts from 1 replace (portID) with (portID - 1) in DEPENDENCY_MAP (and make sure IX_ETH_DB_NUMBER_OF_PORTS is big enough) */
/* gives an empty dependency map */
#define SET_EMPTY_DEPENDENCY_MAP(map) { int i = 0; for (; i < 32 ; i++) map[i] = 0; }
#define IS_EMPTY_DEPENDENCY_MAP(result, map) { int i = 0 ; result = TRUE; for (; i < 32 ; i++) if (map[i] != 0) { result = FALSE; break; }}
/**
* gives a map consisting only of 'portID'
*/
#define SET_DEPENDENCY_MAP(map, portID) {SET_EMPTY_DEPENDENCY_MAP(map); map[portID >> 3] = 1 << (portID & 0x7);}
/**
* gives a map resulting from joining map1 and map2
*/
#define JOIN_MAPS(map, map1, map2) { int i = 0; for (; i < 32 ; i++) map[i] = map1[i] | map2[i]; }
/**
* gives the map resulting from joining portID and map
*/
#define JOIN_PORT_TO_MAP(map, portID) { map[portID >> 3] |= 1 << (portID & 0x7); }
/**
* gives the map resulting from excluding portID from map
*/
#define EXCLUDE_PORT_FROM_MAP(map, portID) { map[portID >> 3] &= ~(1 << (portID & 0x7); }
/**
* returns TRUE if map1 is a subset of map2 and FALSE otherwise
*/
#define IS_MAP_SUBSET(result, map1, map2) { int i = 0; result = TRUE; for (; i < 32 ; i++) if ((map1[i] | map2[i]) != map2[i]) result = FALSE; }
/**
* returns TRUE is portID is part of map and FALSE otherwise
*/
#define IS_PORT_INCLUDED(portID, map) ((map[portID >> 3] & (1 << (portID & 0x7))) != 0)
/**
* returns the difference between map1 and map2 (ports included in map1 and not included in map2)
*/
#define DIFF_MAPS(map, map1, map2) { int i = 0; for (; i < 32 ; i++) map[i] = map1[i] ^ (map1[i] & map2[i]); }
/**
* returns TRUE if the maps collide (have at least one port in common) and FALSE otherwise
*/
#define MAPS_COLLIDE(result, map1, map2) { int i = 0; result = FALSE; for (; i < 32 ; i++) if ((map1[i] & map2[i]) != 0) result = TRUE; }
/* size (number of ports) of a dependency map */
#define GET_MAP_SIZE(map, size) { int i = 0, b = 0; size = 0; for (; i < 32 ; i++) { char y = map[i]; for (; b < 8 && (y >>= 1); b++) size += (y & 1); }}
/* copy map2 into map1 */
#define COPY_DEPENDENCY_MAP(map1, map2) { memcpy (map1, map2, sizeof (map1)); }
/* definition of a port map size/port number which cannot be reached (we support at most 32 ports) */
#define MAX_PORT_SIZE (0xFF)
#define MAX_PORT_NUMBER (0xFF)
#define IX_ETH_DB_CHECK_REFERENCE(ptr) { if ((ptr) == NULL) { return IX_ETH_DB_INVALID_ARG; } }
#define IX_ETH_DB_CHECK_MAP(portID, map) { if (!IS_PORT_INCLUDED(portID, map)) { return IX_ETH_DB_INVALID_ARG; } }
/* event queue macros */
#define EVENT_QUEUE_WRAP(offset) ((offset) >= EVENT_QUEUE_SIZE ? (offset) - EVENT_QUEUE_SIZE : (offset))
#define CAN_ENQUEUE(eventQueuePtr) ((eventQueuePtr)->length < EVENT_QUEUE_SIZE)
#define QUEUE_HEAD(eventQueuePtr) (&(eventQueuePtr)->queue[EVENT_QUEUE_WRAP((eventQueuePtr)->base + (eventQueuePtr)->length)])
#define QUEUE_TAIL(eventQueuePtr) (&(eventQueuePtr)->queue[(eventQueuePtr)->base])
#define PUSH_UPDATE_QUEUE(eventQueuePtr) { (eventQueuePtr)->length++; }
#define SHIFT_UPDATE_QUEUE(eventQueuePtr) \
{ \
(eventQueuePtr)->base = EVENT_QUEUE_WRAP((eventQueuePtr)->base + 1); \
(eventQueuePtr)->length--; \
}
#define RESET_QUEUE(eventQueuePtr) \
{ \
(eventQueuePtr)->base = 0; \
(eventQueuePtr)->length = 0; \
}
/* node stack macros - used to browse a tree without using a recursive function */
#define NODE_STACK_INIT(stack) { (stack)->nodeCount = 0; }
#define NODE_STACK_PUSH(stack, node, offset) { (stack)->nodes[(stack)->nodeCount] = (node); (stack)->offsets[(stack)->nodeCount++] = (offset); }
#define NODE_STACK_POP(stack, node, offset) { (node) = (stack)->nodes[--(stack)->nodeCount]; offset = (stack)->offsets[(stack)->nodeCount]; }
#define NODE_STACK_NONEMPTY(stack) ((stack)->nodeCount != 0)
#ifndef IX_NDEBUG
#define IX_ETH_DB_NPE_MSG_HISTORY_DEPTH (100)
#define LOG_NPE_MSG(msg) \
do { \
UINT32 npeMsgHistoryIndex = (npeMsgHistoryLen++) % IX_ETH_DB_NPE_MSG_HISTORY_DEPTH; \
npeMsgHistory[npeMsgHistoryIndex][0] = msg.data[0]; \
npeMsgHistory[npeMsgHistoryIndex][1] = msg.data[1]; \
} while (0);
#else
#define LOG_NPE_MSG() /* nothing */
#endif
/* ----------- Data -------------- */
/* typedefs */
typedef UINT32 (*HashFunction)(void *entity);
typedef BOOL (*MatchFunction)(void *reference, void *entry);
typedef void (*FreeFunction)(void *entry);
/**
* basic component of a hash table
*/
typedef struct HashNode_t
{
void *data; /**< specific data */
struct HashNode_t *next; /**< used for bucket chaining */
__mempool__ struct HashNode_t *nextFree; /**< memory pool management */
__lock__ IxOsalFastMutex lock; /**< node lock */
} HashNode;
/**
* @brief hash table iterator definition
*
* an iterator is an object which can be used
* to browse a hash table
*/
typedef struct
{
UINT32 bucketIndex; /**< index of the currently iterated bucket */
HashNode *previousNode; /**< reference to the previously iterated node within the current bucket */
HashNode *node; /**< reference to the currently iterated node */
} HashIterator;
/**
* definition of a MAC descriptor (a database record)
*/
typedef enum
{
IX_ETH_DB_WIFI_AP_TO_STA = 0x0,
IX_ETH_DB_WIFI_AP_TO_AP = 0x1
} IxEthDBWiFiRecordType;
typedef union
{
struct
{
UINT32 age;
BOOL staticEntry; /**< TRUE if this address is static (doesn't age) */
} filteringData;
struct
{
UINT32 age;
BOOL staticEntry;
UINT32 ieee802_1qTag;
} filteringVlanData;
struct
{
IxEthDBWiFiRecordType type; /**< AP_TO_AP (0x1) or AP_TO_STA (0x0) */
UINT32 gwAddressIndex; /**< used only when linearizing the entries for NPE usage */
UINT8 gwMacAddress[IX_IEEE803_MAC_ADDRESS_SIZE];
__alignment__ UINT8 reserved2[2];
} wifiData;
} IxEthDBRecordData;
typedef struct MacDescriptor_t
{
UINT8 macAddress[IX_IEEE803_MAC_ADDRESS_SIZE];
__alignment__ UINT8 reserved1[2];
UINT32 portID;
IxEthDBRecordType type;
IxEthDBRecordData recordData;
/* used for internal operations, such as NPE linearization */
void *internal;
/* custom user data */
void *user;
__mempool__ struct MacDescriptor_t *nextFree; /**< memory pool management */
__smartpointer__ UINT32 refCount; /**< smart pointer reference counter */
} MacDescriptor;
/**
* hash table definition
*/
typedef struct
{
HashNode *hashBuckets[NUM_BUCKETS];
UINT32 numBuckets;
__lock__ IxOsalFastMutex bucketLocks[NUM_BUCKETS];
HashFunction entryHashFunction;
MatchFunction *matchFunctions;
FreeFunction freeFunction;
} HashTable;
typedef enum
{
IX_ETH_DB_MAC_KEY = 1,
IX_ETH_DB_MAC_PORT_KEY = 2,
IX_ETH_DB_MAC_VLAN_KEY = 3,
IX_ETH_DB_MAX_KEY_INDEX = 3
} IxEthDBSearchKeyType;
typedef struct MacTreeNode_t
{
__smartpointer__ MacDescriptor *descriptor;
struct MacTreeNode_t *left, *right;
__mempool__ struct MacTreeNode_t *nextFree;
} MacTreeNode;
typedef IxEthDBStatus (*IxEthDBPortUpdateHandler)(IxEthDBPortId portID, IxEthDBRecordType type);
typedef void (*IxEthDBNoteWriteFn)(void *address, MacTreeNode *node);
typedef struct
{
BOOL updateEnabled; /**< TRUE if updates are enabled for port */
BOOL userControlled; /**< TRUE if the user has manually used ixEthDBPortUpdateEnableSet */
BOOL treeInitialized; /**< TRUE if the NPE has received an initial tree */
IxEthDBPortUpdateHandler updateHandler; /**< port update handler routine */
void *npeUpdateZone; /**< port update memory zone */
void *npeGwUpdateZone; /**< port update memory zone for gateways */
void *vlanUpdateZone; /**< port update memory zone for VLAN tables */
MacTreeNode *searchTree; /**< internal search tree, in MacTreeNode representation */
BOOL searchTreePendingWrite; /**< TRUE if searchTree holds a tree pending write to the port */
} PortUpdateMethod;
typedef struct
{
IxEthDBPortId portID; /**< port ID */
BOOL enabled; /**< TRUE if the port is enabled */
BOOL agingEnabled; /**< TRUE if aging on this port is enabled */
BOOL initialized;
IxEthDBPortMap dependencyPortMap; /**< dependency port map for this port */
PortUpdateMethod updateMethod; /**< update method structure */
BOOL macAddressUploaded; /**< TRUE if the MAC address was uploaded into the port */
UINT32 maxRxFrameSize; /**< maximum Rx frame size for this port */
UINT32 maxTxFrameSize; /**< maximum Rx frame size for this port */
UINT8 bbsid[6];
__alignment__ UINT8 reserved[2];
UINT32 frameControlDurationID; /**< Frame Control - Duration/ID WiFi control */
IxEthDBVlanTag vlanTag; /**< default VLAN tag for port */
IxEthDBPriorityTable priorityTable; /**< QoS <=> internal priority mapping */
IxEthDBVlanSet vlanMembership;
IxEthDBVlanSet transmitTaggingInfo;
IxEthDBFrameFilter frameFilter;
IxEthDBTaggingAction taggingAction;
UINT32 npeFrameFilter;
UINT32 npeTaggingAction;
IxEthDBFirewallMode firewallMode;
BOOL srcAddressFilterEnabled;
BOOL stpBlocked;
IxEthDBFeature featureCapability;
IxEthDBFeature featureStatus;
UINT32 ixEthDBTrafficClassAQMAssignments[IX_IEEE802_1Q_QOS_PRIORITY_COUNT];
UINT32 ixEthDBTrafficClassCount;
UINT32 ixEthDBTrafficClassAvailable;
__lock__ IxOsalMutex npeAckLock;
} PortInfo;
/* list of port information structures indexed on port Ids */
extern IX_ETH_DB_PUBLIC PortInfo ixEthDBPortInfo[IX_ETH_DB_NUMBER_OF_PORTS];
typedef enum
{
IX_ETH_DB_ADD_FILTERING_RECORD = 0xFF0001,
IX_ETH_DB_REMOVE_FILTERING_RECORD = 0xFF0002
} PortEventType;
typedef struct
{
UINT32 eventType;
IxEthDBPortId portID;
IxEthDBMacAddr macAddr;
BOOL staticEntry;
} PortEvent;
typedef struct
{
PortEvent queue[EVENT_QUEUE_SIZE];
UINT32 base;
UINT32 length;
} PortEventQueue;
typedef struct
{
IxEthDBPortId portID; /**< originating port */
MacDescriptor *macDescriptors[MAX_ELT_SIZE]; /**< addresses to be synced into db */
UINT32 addressCount; /**< number of addresses */
} TreeSyncInfo;
typedef struct
{
MacTreeNode *nodes[MAX_ELT_SIZE];
UINT32 offsets[MAX_ELT_SIZE];
UINT32 nodeCount;
} MacTreeNodeStack;
/* Prototypes */
/* ----------- Memory management -------------- */
IX_ETH_DB_PUBLIC void ixEthDBInitMemoryPools(void);
IX_ETH_DB_PUBLIC HashNode* ixEthDBAllocHashNode(void);
IX_ETH_DB_PUBLIC void ixEthDBFreeHashNode(HashNode *);
IX_ETH_DB_PUBLIC __smartpointer__ MacDescriptor* ixEthDBAllocMacDescriptor(void);
IX_ETH_DB_PUBLIC __smartpointer__ MacDescriptor* ixEthDBCloneMacDescriptor(MacDescriptor *macDescriptor);
IX_ETH_DB_PUBLIC __smartpointer__ void ixEthDBFreeMacDescriptor(MacDescriptor *);
IX_ETH_DB_PUBLIC __smartpointer__ MacTreeNode* ixEthDBAllocMacTreeNode(void);
IX_ETH_DB_PUBLIC __smartpointer__ MacTreeNode* ixEthDBCloneMacTreeNode(MacTreeNode *);
IX_ETH_DB_PUBLIC __smartpointer__ void ixEthDBFreeMacTreeNode(MacTreeNode *);
IX_ETH_DB_PUBLIC void ixEthDBPoolFreeMacTreeNode(MacTreeNode *);
IX_ETH_DB_PUBLIC UINT32 ixEthDBSearchTreeUsageGet(MacTreeNode *tree);
IX_ETH_DB_PUBLIC int ixEthDBShowMemoryStatus(void);
/* Hash Table */
IX_ETH_DB_PUBLIC void ixEthDBInitHash(HashTable *hashTable, UINT32 numBuckets, HashFunction entryHashFunction, MatchFunction *matchFunctions, FreeFunction freeFunction);
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBAddHashEntry(HashTable *hashTable, void *entry);
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBRemoveHashEntry(HashTable *hashTable, int keyType, void *reference);
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBSearchHashEntry(HashTable *hashTable, int keyType, void *reference, HashNode **searchResult);
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPeekHashEntry(HashTable *hashTable, int keyType, void *reference);
IX_ETH_DB_PUBLIC void ixEthDBReleaseHashNode(HashNode *node);
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBInitHashIterator(HashTable *hashTable, HashIterator *iterator);
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBIncrementHashIterator(HashTable *hashTable, HashIterator *iterator);
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBRemoveEntryAtHashIterator(HashTable *hashTable, HashIterator *iterator);
IX_ETH_DB_PUBLIC void ixEthDBReleaseHashIterator(HashIterator *iterator);
/* API Support */
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortAddressSet(IxEthDBPortId portID, IxEthDBMacAddr *macAddr);
IX_ETH_DB_PUBLIC void ixEthDBMaximumFrameSizeAckCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg);
/* DB Core functions */
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBInit(void);
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBAdd(MacDescriptor *newRecordTemplate, IxEthDBPortMap updateTrigger);
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBRemove(MacDescriptor *templateRecord, IxEthDBPortMap updateTrigger);
IX_ETH_DB_PUBLIC HashNode* ixEthDBSearch(IxEthDBMacAddr *macAddress, IxEthDBRecordType typeFilter);
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPeek(IxEthDBMacAddr *macAddress, IxEthDBRecordType typeFilter);
/* Learning support */
IX_ETH_DB_PUBLIC UINT32 ixEthDBAddressCompare(UINT8 *mac1, UINT8 *mac2);
IX_ETH_DB_PUBLIC BOOL ixEthDBAddressMatch(void *reference, void *entry);
IX_ETH_DB_PUBLIC UINT32 ixEthDBEntryXORHash(void *macDescriptor);
IX_ETH_DB_PUBLIC UINT32 ixEthDBKeyXORHash(void *macAddress);
/* Port updates */
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBNPEUpdateHandler(IxEthDBPortId portID, IxEthDBRecordType type);
IX_ETH_DB_PUBLIC void ixEthDBUpdatePortLearningTrees(IxEthDBPortMap triggerPorts);
IX_ETH_DB_PUBLIC void ixEthDBNPEAccessRequest(IxEthDBPortId portID);
IX_ETH_DB_PUBLIC void ixEthDBUpdateLock(void);
IX_ETH_DB_PUBLIC void ixEthDBUpdateUnlock(void);
IX_ETH_DB_PUBLIC MacTreeNode* ixEthDBQuery(MacTreeNode *searchTree, IxEthDBPortMap query, IxEthDBRecordType recordFilter, UINT32 maximumEntries);
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBFirewallUpdate(IxEthDBPortId portID, void *address, UINT32 epDelta);
/* Init/unload */
IX_ETH_DB_PUBLIC void ixEthDBPortSetAckCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg);
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBEventProcessorInit(void);
IX_ETH_DB_PUBLIC void ixEthDBPortInit(IxEthDBPortId portID);
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortEnable(IxEthDBPortId portID);
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortDisable(IxEthDBPortId portID);
IX_ETH_DB_PUBLIC void ixEthDBNPEUpdateAreasInit(void);
IX_ETH_DB_PUBLIC UINT32 ixEthDBMatchMethodsRegister(MatchFunction *matchFunctions);
IX_ETH_DB_PUBLIC UINT32 ixEthDBRecordSerializeMethodsRegister(void);
IX_ETH_DB_PUBLIC UINT32 ixEthDBUpdateTypeRegister(BOOL *typeArray);
IX_ETH_DB_PUBLIC void ixEthDBNPEUpdateAreasUnload(void);
IX_ETH_DB_PUBLIC void ixEthDBFeatureCapabilityScan(void);
IX_ETH_DB_PUBLIC UINT32 ixEthDBKeyTypeRegister(UINT32 *keyType);
/* Event processing */
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBDefaultEventCallbackEnable(IxEthDBPortId portID, BOOL enable);
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBTriggerAddPortUpdate(IxEthDBMacAddr *macAddr, IxEthDBPortId portID, BOOL staticEntry);
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBTriggerRemovePortUpdate(IxEthDBMacAddr *macAddr, IxEthDBPortId portID);
IX_ETH_DB_PUBLIC void ixEthDBNPEEventCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg);
/* NPE adaptor */
IX_ETH_DB_PUBLIC void ixEthDBGetMacDatabaseCbk(IxNpeMhNpeId npeID, IxNpeMhMessage msg);
IX_ETH_DB_PUBLIC void ixEthDBNpeMsgAck(IxNpeMhNpeId npeID, IxNpeMhMessage msg);
IX_ETH_DB_PUBLIC void ixEthDBNPESyncScan(IxEthDBPortId portID, void *eltBaseAddress, UINT32 eltSize);
IX_ETH_DB_PUBLIC void ixEthDBNPETreeWrite(IxEthDBRecordType type, UINT32 totalSize, void *baseAddress, MacTreeNode *tree, UINT32 *blocks, UINT32 *startIndex);
IX_ETH_DB_PUBLIC void ixEthDBNPEGatewayNodeWrite(void *address, MacTreeNode *node);
/* Other public API functions */
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBStartLearningFunction(void);
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBStopLearningFunction(void);
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortUpdateEnableSet(IxEthDBPortId portID, BOOL enableUpdate);
/* Maximum Tx/Rx public functions */
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBFilteringPortMaximumRxFrameSizeSet(IxEthDBPortId portID, UINT32 maximumRxFrameSize);
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBFilteringPortMaximumTxFrameSizeSet(IxEthDBPortId portID, UINT32 maximumTxFrameSize);
/* VLAN-related */
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortVlanTableSet(IxEthDBPortId portID, IxEthDBVlanSet portVlanTable, IxEthDBVlanSet vlanSet);
/* Record search */
IX_ETH_DB_PUBLIC BOOL ixEthDBAddressRecordMatch(void *untypedReference, void *untypedEntry);
IX_ETH_DB_PUBLIC BOOL ixEthDBVlanRecordMatch(void *untypedReference, void *untypedEntry);
IX_ETH_DB_PUBLIC BOOL ixEthDBPortRecordMatch(void *untypedReference, void *untypedEntry);
IX_ETH_DB_PUBLIC BOOL ixEthDBNullMatch(void *reference, void *entry);
IX_ETH_DB_PUBLIC HashNode* ixEthDBPortSearch(IxEthDBMacAddr *macAddress, IxEthDBPortId portID, IxEthDBRecordType typeFilter);
IX_ETH_DB_PUBLIC HashNode* ixEthDBVlanSearch(IxEthDBMacAddr *macAddress, IxEthDBVlanId vlanID, IxEthDBRecordType typeFilter);
/* Utilities */
IX_ETH_DB_PUBLIC const char* mac2string(const unsigned char *mac);
IX_ETH_DB_PUBLIC void showHashInfo(void);
IX_ETH_DB_PUBLIC int ixEthDBAnalyzeHash(void);
IX_ETH_DB_PUBLIC const char* errorString(IxEthDBStatus error);
IX_ETH_DB_PUBLIC int numHashElements(void);
IX_ETH_DB_PUBLIC void zapHashtable(void);
IX_ETH_DB_PUBLIC BOOL ixEthDBCheckSingleBitValue(UINT32 value);
/* Single Eth NPE Check */
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBSingleEthNpeCheck(IxEthDBPortId portId);
#endif /* IxEthDB_p_H */

View file

@ -0,0 +1,270 @@
/**
* @file IxEthMii.h
*
* @brief this file contains the public API of @ref IxEthMii component
*
* Design notes :
* The main intent of this API is to inplement MII high level fonctionalitoes
* to support the codelets provided with the IXP400 software releases. It
* superceedes previous interfaces provided with @ref IxEThAcc component.
*
* This API has been tested with the PHYs provided with the
* IXP400 development platforms. It may not work for specific Ethernet PHYs
* used on specific boards.
*
* This source code detects and interface the LXT972, LXT973 and KS6995
* Ethernet PHYs.
*
* This source code should be considered as an example which may need
* to be adapted for different hardware implementations.
*
* It is strongly recommended to use public domain and GPL utilities
* like libmii, mii-diag for MII interface support.
*
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#ifndef IxEthMii_H
#define IxEthMii_H
#include <IxTypes.h>
/**
* @defgroup IxEthMii IXP400 Ethernet Phy Access (IxEthMii) API
*
* @brief ethMii is a library that does provides access to the
* Ethernet PHYs
*
*@{
*/
/**
* @ingroup IxEthMii
*
* @fn ixEthMiiPhyScan(BOOL phyPresent[], UINT32 maxPhyCount)
*
* @brief Scan the MDIO bus for PHYs
* This function scans PHY addresses 0 through 31, and sets phyPresent[n] to
* TRUE if a phy is discovered at address n.
*
* - Reentrant - no
* - ISR Callable - no
*
* @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock.
*
* @param phyPresent BOOL [in] - boolean array of IXP425_ETH_ACC_MII_MAX_ADDR entries
* @param maxPhyCount UINT32 [in] - number of PHYs to search for (the scan will stop when
* the indicated number of PHYs is found).
*
* @return IX_STATUS
* - IX_ETH_ACC_SUCCESS
* - IX_ETH_ACC_FAIL : invalid arguments.
*
* <hr>
*/
PUBLIC IX_STATUS ixEthMiiPhyScan(BOOL phyPresent[], UINT32 maxPhyCount);
/**
* @ingroup IxEthMii
*
* @fn ixEthMiiPhyConfig(UINT32 phyAddr,
BOOL speed100,
BOOL fullDuplex,
BOOL autonegotiate)
*
*
* @brief Configure a PHY
* Configure a PHY's speed, duplex and autonegotiation status
*
* - Reentrant - no
* - ISR Callable - no
*
* @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock.
*
* @param phyAddr UINT32 [in]
* @param speed100 BOOL [in] - set to TRUE for 100Mbit/s operation, FALSE for 10Mbit/s
* @param fullDuplex BOOL [in] - set to TRUE for Full Duplex, FALSE for Half Duplex
* @param autonegotiate BOOL [in] - set to TRUE to enable autonegotiation
*
* @return IX_STATUS
* - IX_SUCCESS
* - IX_FAIL : invalid arguments.
*
* <hr>
*/
PUBLIC IX_STATUS ixEthMiiPhyConfig(UINT32 phyAddr,
BOOL speed100,
BOOL fullDuplex,
BOOL autonegotiate);
/**
* @ingroup IxEthMii
*
* @fn ixEthMiiPhyLoopbackEnable(UINT32 phyAddr)
*
*
* @brief Enable PHY Loopback in a specific Eth MII port
*
* @note When PHY Loopback is enabled, frames sent out to the PHY from the
* IXP400 will be looped back to the IXP400. They will not be transmitted out
* on the wire.
*
* - Reentrant - no
* - ISR Callable - no
*
* @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31)
*
* @return IX_STATUS
* - IX_SUCCESS
* - IX_FAIL : invalid arguments.
* <hr>
*/
PUBLIC IX_STATUS
ixEthMiiPhyLoopbackEnable (UINT32 phyAddr);
/**
* @ingroup IxEthMii
*
* @fn ixEthMiiPhyLoopbackDisable(UINT32 phyAddr)
*
*
* @brief Disable PHY Loopback in a specific Eth MII port
*
* - Reentrant - no
* - ISR Callable - no
*
* @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31)
*
* @return IX_STATUS
* - IX_SUCCESS
* - IX_FAIL : invalid arguments.
* <hr>
*/
PUBLIC IX_STATUS
ixEthMiiPhyLoopbackDisable (UINT32 phyAddr);
/**
* @ingroup IxEthMii
*
* @fn ixEthMiiPhyReset(UINT32 phyAddr)
*
* @brief Reset a PHY
* Reset a PHY
*
* - Reentrant - no
* - ISR Callable - no
*
* @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock.
*
* @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31)
*
* @return IX_STATUS
* - IX_SUCCESS
* - IX_FAIL : invalid arguments.
*
* <hr>
*/
PUBLIC IX_STATUS ixEthMiiPhyReset(UINT32 phyAddr);
/**
* @ingroup IxEthMii
*
* @fn ixEthMiiLinkStatus(UINT32 phyAddr,
BOOL *linkUp,
BOOL *speed100,
BOOL *fullDuplex,
BOOL *autoneg)
*
* @brief Retrieve the current status of a PHY
* Retrieve the link, speed, duplex and autonegotiation status of a PHY
*
* - Reentrant - no
* - ISR Callable - no
*
* @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock.
*
* @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31)
* @param linkUp BOOL [out] - set to TRUE if the link is up
* @param speed100 BOOL [out] - set to TRUE indicates 100Mbit/s, FALSE indicates 10Mbit/s
* @param fullDuplex BOOL [out] - set to TRUE indicates Full Duplex, FALSE indicates Half Duplex
* @param autoneg BOOL [out] - set to TRUE indicates autonegotiation is enabled, FALSE indicates autonegotiation is disabled
*
* @return IX_STATUS
* - IX_SUCCESS
* - IX_FAIL : invalid arguments.
*
* <hr>
*/
PUBLIC IX_STATUS ixEthMiiLinkStatus(UINT32 phyAddr,
BOOL *linkUp,
BOOL *speed100,
BOOL *fullDuplex,
BOOL *autoneg);
/**
* @ingroup IxEthMii
*
* @fn ixEthMiiPhyShow (UINT32 phyAddr)
*
*
* @brief Display information on a specified PHY
* Display link status, speed, duplex and Auto Negotiation status
*
* - Reentrant - no
* - ISR Callable - no
*
* @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock.
*
* @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31)
*
* @return IX_STATUS
* - IX_SUCCESS
* - IX_FAIL : invalid arguments.
*
* <hr>
*/
PUBLIC IX_STATUS ixEthMiiPhyShow (UINT32 phyAddr);
#endif /* ndef IxEthMii_H */
/**
*@}
*/

View file

@ -0,0 +1,185 @@
/**
* @file IxEthMii_p.h
*
* @author Intel Corporation
* @date
*
* @brief MII Header file
*
* Design Notes:
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#ifndef IxEthMii_p_H
#define IxEthMii_p_H
/* MII definitions - these have been verified against the LXT971 and
LXT972 PHYs*/
#define IX_ETH_MII_MAX_REG_NUM 0x20 /* max number of registers */
#define IX_ETH_MII_CTRL_REG 0x0 /* Control Register */
#define IX_ETH_MII_STAT_REG 0x1 /* Status Register */
#define IX_ETH_MII_PHY_ID1_REG 0x2 /* PHY identifier 1 Register */
#define IX_ETH_MII_PHY_ID2_REG 0x3 /* PHY identifier 2 Register */
#define IX_ETH_MII_AN_ADS_REG 0x4 /* Auto-Negotiation */
/* Advertisement Register */
#define IX_ETH_MII_AN_PRTN_REG 0x5 /* Auto-Negotiation */
/* partner ability Register */
#define IX_ETH_MII_AN_EXP_REG 0x6 /* Auto-Negotiation */
/* Expansion Register */
#define IX_ETH_MII_AN_NEXT_REG 0x7 /* Auto-Negotiation */
/* next-page transmit Register */
#define IX_ETH_MII_STAT2_REG 0x11 /* Status Register 2*/
/* MII control register bit */
#define IX_ETH_MII_CR_COLL_TEST 0x0080 /* collision test */
#define IX_ETH_MII_CR_FDX 0x0100 /* FDX =1, half duplex =0 */
#define IX_ETH_MII_CR_RESTART 0x0200 /* restart auto negotiation */
#define IX_ETH_MII_CR_ISOLATE 0x0400 /* isolate PHY from MII */
#define IX_ETH_MII_CR_POWER_DOWN 0x0800 /* power down */
#define IX_ETH_MII_CR_AUTO_EN 0x1000 /* auto-negotiation enable */
#define IX_ETH_MII_CR_100 0x2000 /* 0 = 10mb, 1 = 100mb */
#define IX_ETH_MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */
#define IX_ETH_MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */
#define IX_ETH_MII_CR_NORM_EN 0x0000 /* just enable the PHY */
#define IX_ETH_MII_CR_DEF_0_MASK 0xca7f /* they must return zero */
#define IX_ETH_MII_CR_RES_MASK 0x007f /* reserved bits, return zero */
/* MII Status register bit definitions */
#define IX_ETH_MII_SR_LINK_STATUS 0x0004 /* link Status -- 1 = link */
#define IX_ETH_MII_SR_AUTO_SEL 0x0008 /* auto speed select capable */
#define IX_ETH_MII_SR_REMOTE_FAULT 0x0010 /* Remote fault detect */
#define IX_ETH_MII_SR_AUTO_NEG 0x0020 /* auto negotiation complete */
#define IX_ETH_MII_SR_10T_HALF_DPX 0x0800 /* 10BaseT HD capable */
#define IX_ETH_MII_SR_10T_FULL_DPX 0x1000 /* 10BaseT FD capable */
#define IX_ETH_MII_SR_TX_HALF_DPX 0x2000 /* TX HD capable */
#define IX_ETH_MII_SR_TX_FULL_DPX 0x4000 /* TX FD capable */
#define IX_ETH_MII_SR_T4 0x8000 /* T4 capable */
#define IX_ETH_MII_SR_ABIL_MASK 0xff80 /* abilities mask */
#define IX_ETH_MII_SR_EXT_CAP 0x0001 /* extended capabilities */
/* LXT971/2 Status 2 register bit definitions */
#define IX_ETH_MII_SR2_100 0x4000
#define IX_ETH_MII_SR2_TX 0x2000
#define IX_ETH_MII_SR2_RX 0x1000
#define IX_ETH_MII_SR2_COL 0x0800
#define IX_ETH_MII_SR2_LINK 0x0400
#define IX_ETH_MII_SR2_FD 0x0200
#define IX_ETH_MII_SR2_AUTO 0x0100
#define IX_ETH_MII_SR2_AUTO_CMPLT 0x0080
#define IX_ETH_MII_SR2_POLARITY 0x0020
#define IX_ETH_MII_SR2_PAUSE 0x0010
#define IX_ETH_MII_SR2_ERROR 0x0008
/* MII Link Code word bit definitions */
#define IX_ETH_MII_BP_FAULT 0x2000 /* remote fault */
#define IX_ETH_MII_BP_ACK 0x4000 /* acknowledge */
#define IX_ETH_MII_BP_NP 0x8000 /* nexp page is supported */
/* MII Next Page bit definitions */
#define IX_ETH_MII_NP_TOGGLE 0x0800 /* toggle bit */
#define IX_ETH_MII_NP_ACK2 0x1000 /* acknowledge two */
#define IX_ETH_MII_NP_MSG 0x2000 /* message page */
#define IX_ETH_MII_NP_ACK1 0x4000 /* acknowledge one */
#define IX_ETH_MII_NP_NP 0x8000 /* nexp page will follow */
/* MII Expansion Register bit definitions */
#define IX_ETH_MII_EXP_FAULT 0x0010 /* parallel detection fault */
#define IX_ETH_MII_EXP_PRTN_NP 0x0008 /* link partner next-page able */
#define IX_ETH_MII_EXP_LOC_NP 0x0004 /* local PHY next-page able */
#define IX_ETH_MII_EXP_PR 0x0002 /* full page received */
#define IX_ETH_MII_EXP_PRT_AN 0x0001 /* link partner auto neg able */
/* technology ability field bit definitions */
#define IX_ETH_MII_TECH_10BASE_T 0x0020 /* 10Base-T */
#define IX_ETH_MII_TECH_10BASE_FD 0x0040 /* 10Base-T Full Duplex */
#define IX_ETH_MII_TECH_100BASE_TX 0x0080 /* 100Base-TX */
#define IX_ETH_MII_TECH_100BASE_TX_FD 0x0100 /* 100Base-TX Full Duplex */
#define IX_ETH_MII_TECH_100BASE_T4 0x0200 /* 100Base-T4 */
#define IX_ETH_MII_ADS_TECH_MASK 0x1fe0 /* technology abilities mask */
#define IX_ETH_MII_TECH_MASK IX_ETH_MII_ADS_TECH_MASK
#define IX_ETH_MII_ADS_SEL_MASK 0x001f /* selector field mask */
#define IX_ETH_MII_AN_FAIL 0x10 /* auto-negotiation fail */
#define IX_ETH_MII_STAT_FAIL 0x20 /* errors in the status register */
#define IX_ETH_MII_PHY_NO_ABLE 0x40 /* the PHY lacks some abilities */
/* Definitions for MII access routines*/
#define IX_ETH_MII_GO BIT(31)
#define IX_ETH_MII_WRITE BIT(26)
#define IX_ETH_MII_TIMEOUT_10TH_SECS (5)
#define IX_ETH_MII_10TH_SEC_IN_MILLIS (100)
#define IX_ETH_MII_READ_FAIL BIT(31)
/* When we reset the PHY we delay for 2 seconds to allow the reset to
complete*/
#define IX_ETH_MII_RESET_DELAY_MS (2000)
#define IX_ETH_MII_RESET_POLL_MS (50)
#define IX_ETH_MII_REG_SHL 16
#define IX_ETH_MII_ADDR_SHL 21
/* supported PHYs */
#define IX_ETH_MII_LXT971_PHY_ID 0x001378E0
#define IX_ETH_MII_LXT972_PHY_ID 0x001378E2
#define IX_ETH_MII_LXT973_PHY_ID 0x00137A10
#define IX_ETH_MII_LXT973A3_PHY_ID 0x00137A11
#define IX_ETH_MII_KS8995_PHY_ID 0x00221450
#define IX_ETH_MII_LXT9785_PHY_ID 0x001378FF
#define IX_ETH_MII_INVALID_PHY_ID 0x00000000
#define IX_ETH_MII_UNKNOWN_PHY_ID 0xffffffff
#endif /*IxEthAccMii_p_H*/

View file

@ -0,0 +1,695 @@
#ifndef __doxygen_HIDE /* This file is not part of the API */
/**
* @file IxEthNpe.h
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
/**
* @defgroup IxEthNpe IXP400 Ethernet NPE (IxEthNpe) API
*
* @brief Contains the API for Ethernet NPE.
*
* All messages given to NPE, get back an acknowledgment. The acknowledgment
* is identical to the message sent to the NPE (except for NPE_GETSTATUS message).
*
* @{
*/
/*--------------------------------------------------------------------------
* APB Message IDs - XScale->NPE
*------------------------------------------------------------------------*/
/**
* @def IX_ETHNPE_NPE_GETSTATUS
*
* @brief Request from the XScale client for the NPE to return the firmware
* version of the currently executing image.
*
* Acknowledgment message id is same as the request message id.
* NPE returns the firmware version ID to XScale.
*/
#define IX_ETHNPE_NPE_GETSTATUS 0x00
/**
* @def IX_ETHNPE_EDB_SETPORTADDRESS
*
* @brief Request from the XScale client for the NPE to set the Ethernet
* port's port ID and MAC address.
*/
#define IX_ETHNPE_EDB_SETPORTADDRESS 0x01
/**
* @def IX_ETHNPE_EDB_GETMACADDRESSDATABASE
*
* @brief Request from XScale client to the NPE requesting upload of
* Ethernet Filtering Database or Header Conversion Database from NPE's
* data memory to XScale accessible SDRAM.
*/
#define IX_ETHNPE_EDB_GETMACADDRESSDATABASE 0x02
/**
* @def IX_ETHNPE_EDB_SETMACADDRESSSDATABASE
*
* @brief Request from XScale client to the NPE requesting download of
* Ethernet Filtering Database or Header Conversion Database from SDRAM
* to the NPE's datamemory.
*/
#define IX_ETHNPE_EDB_SETMACADDRESSSDATABASE 0x03
/**
* @def IX_ETHNPE_GETSTATS
*
* @brief Request from the XScale client for the current MAC port statistics
* data to be written to the (empty) statistics structure and the specified
* location in externa memory.
*/
#define IX_ETHNPE_GETSTATS 0x04
/**
* @def IX_ETHNPE_RESETSTATS
*
* @brief Request from the XScale client to the NPE to reset all of its internal
* MAC port statistics state variables.
*
* As a side effect, this message entails an implicit request that the NPE
* write the current MAC port statistics into the MAC statistics structure
* at the specified location in external memory.
*/
#define IX_ETHNPE_RESETSTATS 0x05
/**
* @def IX_ETHNPE_SETMAXFRAMELENGTHS
*
* @brief Request from the XScale client to the NPE to configure maximum framelengths
* and block sizes in receive and transmit direction.
*/
#define IX_ETHNPE_SETMAXFRAMELENGTHS 0x06
/**
* @def IX_ETHNPE_VLAN_SETRXTAGMODE
*
* @brief Request from the XScale client to the NPE to configure VLAN frame type
* filtering and VLAN the tagging mode for the receiver.
*/
#define IX_ETHNPE_VLAN_SETRXTAGMODE 0x07
/**
* @def IX_ETHNPE_VLAN_SETDEFAULTRXVID
*
* @brief Request from the XScale client to the NPE to set receiver's default
* VLAN tag (PVID)and internal traffic class.
*/
#define IX_ETHNPE_VLAN_SETDEFAULTRXVID 0x08
/**
* @def IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY
*
* @brief Request from the XScale client to the NPE to configure VLAN Port
* membership and Tx tagging for 8 consecutive VLANID's.
*/
#define IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY 0x09
/**
* @def IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE
*
* @brief Request from the XScale client to the NPE to configure VLAN Port
* membership and Tx tagging for a range of VLANID's.
*/
#define IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE 0x0A
/**
* @def IX_ETHNPE_VLAN_SETRXQOSENTRY
*
* @brief Request from the XScale client to the NPE to map a user priority
* to QoS class and an AQM queue number.
*/
#define IX_ETHNPE_VLAN_SETRXQOSENTRY 0x0B
/**
* @def IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE
*
* @brief Request from the XScale client to the NPE to enable or disable
* portID extraction from VLAN-tagged frames for the specified port.
*/
#define IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE 0x0C
/**
* @def IX_ETHNPE_STP_SETBLOCKINGSTATE
*
* @brief Request from the XScale client to the NPE to block or unblock
* forwarding for spanning tree BPDUs.
*/
#define IX_ETHNPE_STP_SETBLOCKINGSTATE 0x0D
/**
* @def IX_ETHNPE_FW_SETFIREWALLMODE
*
* @brief Request from the XScale client to the NPE to configure firewall
* services modes of operation and/or download Ethernet Firewall Database from
* SDRAM to NPE.
*/
#define IX_ETHNPE_FW_SETFIREWALLMODE 0x0E
/**
* @def IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID
*
* @brief Request from the XScale client to the NPE to set global frame control
* and duration/ID field for the 802.3 to 802.11 protocol header conversion
* service.
*/
#define IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID 0x0F
/**
* @def IX_ETHNPE_PC_SETBBSID
*
* @brief Request from the XScale client to the NPE to set global BBSID field
* value for the 802.3 to 802.11 protocol header conversion service.
*/
#define IX_ETHNPE_PC_SETBBSID 0x10
/**
* @def IX_ETHNPE_PC_SETAPMACTABLE
*
* @brief Request from the XScale client to the NPE to update a block/section/
* range of the AP MAC Address Table.
*/
#define IX_ETHNPE_PC_SETAPMACTABLE 0x11
/**
* @def IX_ETHNPE_SETLOOPBACK_MODE
*
* @brief Turn on or off the NPE frame loopback.
*/
#define IX_ETHNPE_SETLOOPBACK_MODE (0x12)
/*--------------------------------------------------------------------------
* APB Message IDs - NPE->XScale
*------------------------------------------------------------------------*/
/**
* @def IX_ETHNPE_NPE_GETSTATUS_ACK
*
* @brief Acknowledgment to IX_ETHNPE_NPE_GETSTATUS message. NPE firmware version
* id is returned in the message.
*/
#define IX_ETHNPE_NPE_GETSTATUS_ACK 0x00
/**
* @def IX_ETHNPE_EDB_SETPORTADDRESS_ACK
*
* @brief Acknowledgment to IX_ETHNPE_EDB_SETPORTADDRESS message.
*/
#define IX_ETHNPE_EDB_SETPORTADDRESS_ACK 0x01
/**
* @def IX_ETHNPE_EDB_GETMACADDRESSDATABASE_ACK
*
* @brief Acknowledgment to IX_ETHNPE_EDB_GETMACADDRESSDATABASE message
*/
#define IX_ETHNPE_EDB_GETMACADDRESSDATABASE_ACK 0x02
/**
* @def IX_ETHNPE_EDB_SETMACADDRESSSDATABASE_ACK
*
* @brief Acknowledgment to IX_ETHNPE_EDB_SETMACADDRESSSDATABASE message.
*/
#define IX_ETHNPE_EDB_SETMACADDRESSSDATABASE_ACK 0x03
/**
* @def IX_ETHNPE_GETSTATS_ACK
*
* @brief Acknowledgment to IX_ETHNPE_GETSTATS message.
*/
#define IX_ETHNPE_GETSTATS_ACK 0x04
/**
* @def IX_ETHNPE_RESETSTATS_ACK
*
* @brief Acknowledgment to IX_ETHNPE_RESETSTATS message.
*/
#define IX_ETHNPE_RESETSTATS_ACK 0x05
/**
* @def IX_ETHNPE_SETMAXFRAMELENGTHS_ACK
*
* @brief Acknowledgment to IX_ETHNPE_SETMAXFRAMELENGTHS message.
*/
#define IX_ETHNPE_SETMAXFRAMELENGTHS_ACK 0x06
/**
* @def IX_ETHNPE_VLAN_SETRXTAGMODE_ACK
*
* @brief Acknowledgment to IX_ETHNPE_VLAN_SETRXTAGMODE message.
*/
#define IX_ETHNPE_VLAN_SETRXTAGMODE_ACK 0x07
/**
* @def IX_ETHNPE_VLAN_SETDEFAULTRXVID_ACK
*
* @brief Acknowledgment to IX_ETHNPE_VLAN_SETDEFAULTRXVID message.
*/
#define IX_ETHNPE_VLAN_SETDEFAULTRXVID_ACK 0x08
/**
* @def IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY_ACK
*
* @brief Acknowledgment to IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY message.
*/
#define IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY_ACK 0x09
/**
* @def IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE_ACK
*
* @brief Acknowledgment to IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE message.
*/
#define IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE_ACK 0x0A
/**
* @def IX_ETHNPE_VLAN_SETRXQOSENTRY_ACK
*
* @brief Acknowledgment to IX_ETHNPE_VLAN_SETRXQOSENTRY message.
*/
#define IX_ETHNPE_VLAN_SETRXQOSENTRY_ACK 0x0B
/**
* @def IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE_ACK
*
* @brief Acknowledgment to IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE message.
*/
#define IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE_ACK 0x0C
/**
* @def IX_ETHNPE_STP_SETBLOCKINGSTATE_ACK
*
* @brief Acknowledgment to IX_ETHNPE_STP_SETBLOCKINGSTATE message.
*/
#define IX_ETHNPE_STP_SETBLOCKINGSTATE_ACK 0x0D
/**
* @def IX_ETHNPE_FW_SETFIREWALLMODE_ACK
*
* @brief Acknowledgment to IX_ETHNPE_FW_SETFIREWALLMODE message.
*/
#define IX_ETHNPE_FW_SETFIREWALLMODE_ACK 0x0E
/**
* @def IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID_ACK
*
* @brief Acknowledgment to IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID message.
*/
#define IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID_ACK 0x0F
/**
* @def IX_ETHNPE_PC_SETBBSID_ACK
*
* @brief Acknowledgment to IX_ETHNPE_PC_SETBBSID message.
*/
#define IX_ETHNPE_PC_SETBBSID_ACK 0x10
/**
* @def IX_ETHNPE_PC_SETAPMACTABLE_ACK
*
* @brief Acknowledgment to IX_ETHNPE_PC_SETAPMACTABLE message.
*/
#define IX_ETHNPE_PC_SETAPMACTABLE_ACK 0x11
/**
* @def IX_ETHNPE_SETLOOPBACK_MODE_ACK
*
* @brief Acknowledgment to IX_ETHNPE_SETLOOPBACK_MODE message.
*/
#define IX_ETHNPE_SETLOOPBACK_MODE_ACK (0x12)
/*--------------------------------------------------------------------------
* Queue Manager Queue entry bit field boundary definitions
*------------------------------------------------------------------------*/
/**
* @def MASK(hi,lo)
*
* @brief Macro for mask
*/
#define MASK(hi,lo) (((1 << (1 + ((hi) - (lo)))) - 1) << (lo))
/**
* @def BITS(x,hi,lo)
*
* @brief Macro for bits
*/
#define BITS(x,hi,lo) (((x) & MASK(hi,lo)) >> (lo))
/**
* @def IX_ETHNPE_QM_Q_RXENET_LENGTH_MASK
*
* @brief QMgr Queue LENGTH field mask
*/
#define IX_ETHNPE_QM_Q_RXENET_LENGTH_MASK 0x3fff
/**
* @def IX_ETHNPE_QM_Q_FIELD_FLAG_R
*
* @brief QMgr Queue FLAG field right boundary
*/
#define IX_ETHNPE_QM_Q_FIELD_FLAG_R 20
/**
* @def IX_ETHNPE_QM_Q_FIELD_FLAG_MASK
*
* @brief QMgr Queue FLAG field mask
*
* Multicast bit : BIT(4)
* Broadcast bit : BIT(5)
* IP bit : BIT(6) (linux only)
*
*/
#ifdef __vxworks
#define IX_ETHNPE_QM_Q_FIELD_FLAG_MASK 0x30
#else
#define IX_ETHNPE_QM_Q_FIELD_FLAG_MASK 0x70
#endif
/**
* @def IX_ETHNPE_QM_Q_FIELD_NPEID_L
*
* @brief QMgr Queue NPE ID field left boundary
*/
#define IX_ETHNPE_QM_Q_FIELD_NPEID_L 1
/**
* @def IX_ETHNPE_QM_Q_FIELD_NPEID_R
*
* @brief QMgr Queue NPE ID field right boundary
*/
#define IX_ETHNPE_QM_Q_FIELD_NPEID_R 0
/**
* @def IX_ETHNPE_QM_Q_FIELD_PRIOR_L
*
* @brief QMgr Queue Priority field left boundary
*/
#define IX_ETHNPE_QM_Q_FIELD_PRIOR_L 2
/**
* @def IX_ETHNPE_QM_Q_FIELD_PRIOR_R
*
* @brief QMgr Queue Priority field right boundary
*/
#define IX_ETHNPE_QM_Q_FIELD_PRIOR_R 0
/**
* @def IX_ETHNPE_QM_Q_FIELD_ADDR_L
*
* @brief QMgr Queue Address field left boundary
*/
#define IX_ETHNPE_QM_Q_FIELD_ADDR_L 31
/**
* @def IX_ETHNPE_QM_Q_FIELD_ADDR_R
*
* @brief QMgr Queue Address field right boundary
*/
#define IX_ETHNPE_QM_Q_FIELD_ADDR_R 5
/*--------------------------------------------------------------------------
* Queue Manager Queue entry bit field masks
*------------------------------------------------------------------------*/
/**
* @def IX_ETHNPE_QM_Q_FREEENET_ADDR_MASK
*
* @brief Macro to mask the Address field of the FreeEnet Queue Manager Entry
*/
#define IX_ETHNPE_QM_Q_FREEENET_ADDR_MASK \
MASK (IX_ETHNPE_QM_Q_FIELD_ADDR_L, \
IX_ETHNPE_QM_Q_FIELD_ADDR_R)
/**
* @def IX_ETHNPE_QM_Q_RXENET_NPEID_MASK
*
* @brief Macro to mask the NPE ID field of the RxEnet Queue Manager Entry
*/
#define IX_ETHNPE_QM_Q_RXENET_NPEID_MASK \
MASK (IX_ETHNPE_QM_Q_FIELD_NPEID_L, \
IX_ETHNPE_QM_Q_FIELD_NPEID_R)
/**
* @def IX_ETHNPE_QM_Q_RXENET_ADDR_MASK
*
* @brief Macro to mask the Mbuf Address field of the RxEnet Queue Manager Entry
*/
#define IX_ETHNPE_QM_Q_RXENET_ADDR_MASK \
MASK (IX_ETHNPE_QM_Q_FIELD_ADDR_L, \
IX_ETHNPE_QM_Q_FIELD_ADDR_R)
/**
* @def IX_ETHNPE_QM_Q_TXENET_PRIOR_MASK
*
* @brief Macro to mask the Priority field of the TxEnet Queue Manager Entry
*/
#define IX_ETHNPE_QM_Q_TXENET_PRIOR_MASK \
MASK (IX_ETHNPE_QM_Q_FIELD_PRIOR_L, \
IX_ETHNPE_QM_Q_FIELD_PRIOR_R)
/**
* @def IX_ETHNPE_QM_Q_TXENET_ADDR_MASK
*
* @brief Macro to mask the Mbuf Address field of the TxEnet Queue Manager Entry
*/
#define IX_ETHNPE_QM_Q_TXENET_ADDR_MASK \
MASK (IX_ETHNPE_QM_Q_FIELD_ADDR_L, \
IX_ETHNPE_QM_Q_FIELD_ADDR_R)
/**
* @def IX_ETHNPE_QM_Q_TXENETDONE_NPEID_MASK
*
* @brief Macro to mask the NPE ID field of the TxEnetDone Queue Manager Entry
*/
#define IX_ETHNPE_QM_Q_TXENETDONE_NPEID_MASK \
MASK (IX_ETHNPE_QM_Q_FIELD_NPEID_L, \
IX_ETHNPE_QM_Q_FIELD_NPEID_R)
/**
* @def IX_ETHNPE_QM_Q_TXENETDONE_ADDR_MASK
*
* @brief Macro to mask the Mbuf Address field of the TxEnetDone Queue Manager
* Entry
*/
#define IX_ETHNPE_QM_Q_TXENETDONE_ADDR_MASK \
MASK (IX_ETHNPE_QM_Q_FIELD_ADDR_L, \
IX_ETHNPE_QM_Q_FIELD_ADDR_R)
/*--------------------------------------------------------------------------
* Queue Manager Queue entry bit field value extraction macros
*------------------------------------------------------------------------*/
/**
* @def IX_ETHNPE_QM_Q_FREEENET_ADDR_VAL(x)
*
* @brief Extraction macro for Address field of FreeNet Queue Manager Entry
*
* Pointer to an mbuf buffer descriptor
*/
#define IX_ETHNPE_QM_Q_FREEENET_ADDR_VAL(x) \
((x) & IX_ETHNPE_QM_Q_FREEENET_ADDR_MASK)
/**
* @def IX_ETHNPE_QM_Q_RXENET_NPEID_VAL(x)
*
* @brief Extraction macro for NPE ID field of RxEnet Queue Manager Entry
*
* Set to 0 for entries originating from the Eth0 NPE;
* Set to 1 for entries originating from the Eth1 NPE.
*/
#define IX_ETHNPE_QM_Q_RXENET_NPEID_VAL(x) \
BITS (x, IX_ETHNPE_QM_Q_FIELD_NPEID_L, \
IX_ETHNPE_QM_Q_FIELD_NPEID_R)
/**
* @def IX_ETHNPE_QM_Q_RXENET_PORTID_VAL(x)
*
* @brief Extraction macro for Port ID field of RxEnet Queue Manager Entry
*
* 0-5: Assignable (by the XScale client) to any of the physical ports.
* 6: It is reserved
* 7: Indication that the NPE did not find the associated frame's destination MAC address within
* its internal filtering database.
*/
#define IX_ETHNPE_QM_Q_RXENET_PORTID_VAL(x) \
BITS (x, IX_ETHNPE_QM_Q_FIELD_PORTID_L, \
IX_ETHNPE_QM_Q_Field_PortID_R)
/**
* @def IX_ETHNPE_QM_Q_RXENET_ADDR_VAL(x)
*
* @brief Extraction macro for Address field of RxEnet Queue Manager Entry
*
* Pointer to an mbuf buffer descriptor
*/
#define IX_ETHNPE_QM_Q_RXENET_ADDR_VAL(x) \
((x) & IX_ETHNPE_QM_Q_RXENET_ADDR_MASK)
/**
* @def IX_ETHNPE_QM_Q_TXENET_PRIOR_VAL(x)
*
* @brief Extraction macro for Priority field of TxEnet Queue Manager Entry
*
* Priority of the packet (as described in IEEE 802.1D). This field is
* cleared upon return from the Ethernet NPE to the TxEnetDone queue.
*/
#define IX_ETHNPE_QM_Q_TXENET_PRIOR_VAL(x) \
BITS (x, IX_ETHNPE_QM_Q_FIELD_PRIOR_L, \
IX_ETHNPE_QM_Q_FIELD_PRIOR_R)
/**
* @def IX_ETHNPE_QM_Q_TXENET_ADDR_VAL(x)
*
* @brief Extraction macro for Address field of Queue Manager TxEnet Queue
* Manager Entry
*
* Pointer to an mbuf buffer descriptor
*/
#define IX_ETHNPE_QM_Q_TXENET_ADDR_VAL(x) \
((x) & IX_ETHNPE_QM_Q_TXENET_ADDR_MASK)
/**
* @def IX_ETHNPE_QM_Q_TXENETDONE_NPEID_VAL(x)
*
* @brief Extraction macro for NPE ID field of TxEnetDone Queue Manager Entry
*
* Set to 0 for entries originating from the Eth0 NPE; set to 1 for en-tries
* originating from the Eth1 NPE.
*/
#define IX_ETHNPE_QM_Q_TXENETDONE_NPEID_VAL(x) \
BITS (x, IX_ETHNPE_QM_Q_FIELD_NPEID_L, \
IX_ETHNPE_QM_Q_FIELD_NPEID_R)
/**
* @def IX_ETHNPE_QM_Q_TXENETDONE_ADDR_VAL(x)
*
* @brief Extraction macro for Address field of TxEnetDone Queue Manager Entry
*
* Pointer to an mbuf buffer descriptor
*/
#define IX_ETHNPE_QM_Q_TXENETDONE_ADDR_VAL(x) \
((x) & IX_ETHNPE_QM_Q_TXENETDONE_ADDR_MASK)
/*--------------------------------------------------------------------------
* NPE limits
*------------------------------------------------------------------------*/
/**
* @def IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN
*
* @brief Macro to check the minimum length of a rx free buffer
*/
#define IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN (64)
/**
* @def IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MASK
*
* @brief Mask to apply to the mbuf length before submitting it to the NPE
* (the NPE handles only rx free mbufs which are multiple of 64)
*
* @sa IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MASK
*/
#define IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MASK (~63)
/**
* @def IX_ETHNPE_ACC_RXFREE_BUFFER_ROUND_UP(size)
*
* @brief Round up to get the size necessary to receive without chaining
* the frames which are (size) bytes (the NPE operates by multiple of 64)
* e.g. To receive 1514 bytes frames, the size of the buffers in replenish
* has to be at least (1514+63)&(~63) = 1536 bytes.
*
*/
#define IX_ETHNPE_ACC_RXFREE_BUFFER_ROUND_UP(size) (((size) + 63) & ~63)
/**
* @def IX_ETHNPE_ACC_RXFREE_BUFFER_ROUND_DOWN(size)
*
* @brief Round down to apply to the mbuf length before submitting
* it to the NPE. (the NPE operates by multiple of 64)
*
*/
#define IX_ETHNPE_ACC_RXFREE_BUFFER_ROUND_DOWN(size) ((size) & ~63)
/**
* @def IX_ETHNPE_ACC_FRAME_LENGTH_MAX
*
* @brief maximum mbuf length supported by the NPE
*
* @sa IX_ETHNPE_ACC_FRAME_LENGTH_MAX
*/
#define IX_ETHNPE_ACC_FRAME_LENGTH_MAX (16320)
/**
* @def IX_ETHNPE_ACC_FRAME_LENGTH_DEFAULT
*
* @brief default mbuf length supported by the NPE
*
* @sa IX_ETHNPE_ACC_FRAME_LENGTH_DEFAULT
*/
#define IX_ETHNPE_ACC_FRAME_LENGTH_DEFAULT (1522)
/**
* @def IX_ETHNPE_ACC_LENGTH_OFFSET
*
* @brief Offset of the cluster length field in the word shared with the NPEs
*/
#define IX_ETHNPE_ACC_LENGTH_OFFSET 16
/**
* @def IX_ETHNPE_ACC_PKTLENGTH_MASK
*
* @brief Mask of the cluster length field in the word shared with the NPEs
*/
#define IX_ETHNPE_ACC_PKTLENGTH_MASK 0x3fff
/**
*@}
*/
#endif /* __doxygen_HIDE */

View file

@ -0,0 +1,742 @@
/**
* @file IxFeatureCtrl.h
*
* @date 30-Jan-2003
* @brief This file contains the public API of the IXP400 Feature Control
* component.
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
/* ------------------------------------------------------
Doxygen group definitions
------------------------------------------------------ */
/**
* @defgroup IxFeatureCtrlAPI IXP400 Feature Control (IxFeatureCtrl) API
*
* @brief The Public API for the IXP400 Feature Control.
*
* @{
*/
#ifndef IXFEATURECTRL_H
#define IXFEATURECTRL_H
/*
* User defined include files
*/
#include "IxOsal.h"
/*
* #defines and macros
*/
/*************************************************************
* The following are IxFeatureCtrlComponentCheck return values.
************************************************************/
/**
* @ingroup IxFeatureCtrlAPI
*
* @def IX_FEATURE_CTRL_COMPONENT_DISABLED
*
* @brief Hardware Component is disabled/unavailable.
* Return status by ixFeatureCtrlComponentCheck()
*/
#define IX_FEATURE_CTRL_COMPONENT_DISABLED 0
/**
* @ingroup IxFeatureCtrlAPI
*
* @def IX_FEATURE_CTRL_COMPONENT_ENABLED
*
* @brief Hardware Component is available.
* Return status by ixFeatureCtrlComponentCheck()
*/
#define IX_FEATURE_CTRL_COMPONENT_ENABLED 1
/***********************************************************************************
* Product ID in XScale CP15 - Register 0
* - It contains information on the maximum XScale Core Frequency and
* Silicon Stepping.
* - XScale Core Frequency Id indicates only the maximum XScale frequency
* achievable and not the running XScale frequency (maybe stepped down).
* - The register is read by using ixFeatureCtrlProductIdRead.
* - Usage example:
* productId = ixFeatureCtrlProductIdRead();
* if( (productId & IX_FEATURE_CTRL_SILICON_STEPPING_MASK) ==
* IX_FEATURE_CTRL_SILICON_TYPE_A0 )
* if( (productId & IX_FEATURE_CTRL_XSCALE_FREQ_MASK) ==
* IX_FEATURE_CTRL_XSCALE_FREQ_533 )
*
* 31 28 27 24 23 20 19 16 15 12 11 9 8 4 3 0
* --------------------------------------------------------------------------------
* | 0x6 | 0x9 | 0x0 | 0x5 | 0x4 | Device ID | XScale Core Freq Id | Si Stepping Id |
* --------------------------------------------------------------------------------
*
* Maximum Achievable XScale Core Frequency Id : 533MHz - 0x1C
* 400MHz - 0x1D
* 266MHz - 0x1F
*
* <b>THE CORE FREQUENCY ID IS NOT APPLICABLE TO IXP46X <\b>
*
* The above is applicable to IXP42X only. CP15 in IXP46X does not contain any
* Frequency ID.
*
* Si Stepping Id : A - 0x0
* B - 0x1
*
* XScale Core freq Id - Device ID [11:9] : IXP42X - 0x0
* IXP46X - 0x1
*************************************************************************************/
/**
* @ingroup IxFeatureCtrlAPI
*
* @def IX_FEATURE_CTRL_SILICON_TYPE_A0
*
* @brief This is the value of A0 Silicon in product ID.
*/
#define IX_FEATURE_CTRL_SILICON_TYPE_A0 0
/**
* @ingroup IxFeatureCtrlAPI
*
* @def IX_FEATURE_CTRL_SILICON_TYPE_B0
*
* @brief This is the value of B0 Silicon in product ID.
*/
#define IX_FEATURE_CTRL_SILICON_TYPE_B0 1
/**
* @ingroup IxFeatureCtrlAPI
*
* @def IX_FEATURE_CTRL_SILICON_STEPPING_MASK
*
* @brief This is the mask of silicon stepping in product ID.
*/
#define IX_FEATURE_CTRL_SILICON_STEPPING_MASK 0xF
/**
* @ingroup IxFeatureCtrlAPI
*
* @def IX_FEATURE_CTRL_DEVICE_TYPE_MASK
*
* @brief This is the mask of silicon stepping in product ID.
*/
#define IX_FEATURE_CTRL_DEVICE_TYPE_MASK (0x7)
/**
* @ingroup IxFeatureCtrlAPI
*
* @def IX_FEATURE_CTRL_DEVICE_TYPE_OFFSET
*
* @brief This is the mask of silicon stepping in product ID.
*/
#define IX_FEATURE_CTRL_DEVICE_TYPE_OFFSET 9
/**
* @ingroup IxFeatureCtrlAPI
*
* @def IX_FEATURE_CTRL_XSCALE_FREQ_533
*
* @brief This is the value of 533MHz XScale Core in product ID.
*/
#define IX_FEATURE_CTRL_XSCALE_FREQ_533 ((0x1C)<<4)
/**
* @ingroup IxFeatureCtrlAPI
*
* @def IX_FEATURE_CTRL_XSCALE_FREQ_400
*
* @brief This is the value of 400MHz XScale Core in product ID.
*/
#define IX_FEATURE_CTRL_XSCALE_FREQ_400 ((0x1D)<<4)
/**
* @ingroup IxFeatureCtrlAPI
*
* @def IX_FEATURE_CTRL_XSCALE_FREQ_266
*
* @brief This is the value of 266MHz XScale Core in product ID.
*/
#define IX_FEATURE_CTRL_XSCALE_FREQ_266 ((0x1F)<<4)
/**
* @ingroup IxFeatureCtrlAPI
*
* @def IX_FEATURE_CTRL_XSCALE_FREQ_MASK
*
* @brief This is the mask of XScale Core in product ID.
*/
#define IX_FEATURE_CTRL_XSCALE_FREQ_MASK ((0xFF)<<4)
/**
* @ingroup IxFeatureCtrlAPI
*
* @def IX_FEATURECTRL_REG_UTOPIA_32PHY
*
* @brief Maximum UTOPIA PHY available is 32.
*
*/
#define IX_FEATURECTRL_REG_UTOPIA_32PHY 0x0
/**
* @ingroup IxFeatureCtrlAPI
*
* @def IX_FEATURECTRL_REG_UTOPIA_16PHY
*
* @brief Maximum UTOPIA PHY available is 16.
*
*/
#define IX_FEATURECTRL_REG_UTOPIA_16PHY 0x1
/**
* @ingroup IxFeatureCtrlAPI
*
* @def IX_FEATURECTRL_REG_UTOPIA_8PHY
*
* @brief Maximum UTOPIA PHY available to is 8.
*
*/
#define IX_FEATURECTRL_REG_UTOPIA_8PHY 0x2
/**
* @ingroup IxFeatureCtrlAPI
*
* @def IX_FEATURECTRL_REG_UTOPIA_4PHY
*
* @brief Maximum UTOPIA PHY available to is 4.
*
*/
#define IX_FEATURECTRL_REG_UTOPIA_4PHY 0x3
#ifdef __ixp46X
/**
* @ingroup IxFeatureCtrlAPI
*
* @def IX_FEATURECTRL_REG_XSCALE_533FREQ
*
* @brief Maximum frequency available to IXP46x is 533 MHz.
*
*/
#define IX_FEATURECTRL_REG_XSCALE_533FREQ 0x0
/**
* @ingroup IxFeatureCtrlAPI
*
* @def IX_FEATURECTRL_REG_XSCALE_667FREQ
*
* @brief Maximum frequency available to IXP46x is 667 MHz.
*
*/
#define IX_FEATURECTRL_REG_XSCALE_667FREQ 0x1
/**
* @ingroup IxFeatureCtrlAPI
*
* @def IX_FEATURECTRL_REG_XSCALE_400FREQ
*
* @brief Maximum frequency available to IXP46x is 400 MHz.
*
*/
#define IX_FEATURECTRL_REG_XSCALE_400FREQ 0x2
/**
* @ingroup IxFeatureCtrlAPI
*
* @def IX_FEATURECTRL_REG_XSCALE_266FREQ
*
* @brief Maximum frequency available to IXP46x is 266 MHz.
*
*/
#define IX_FEATURECTRL_REG_XSCALE_266FREQ 0x3
#endif /* __ixp46X */
/**
* @ingroup IxFeatureCtrlAPI
*
* @def IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE
*
* @brief Component selected is not available for device
*
*/
#define IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE 0x0000
/**
* @ingroup IxFeatureCtrlAPI
*
* @def IX_FEATURECTRL_COMPONENT_ALWAYS_AVAILABLE
*
* @brief Component selected is not available for device
*
*/
#define IX_FEATURECTRL_COMPONENT_ALWAYS_AVAILABLE 0xffff
/**
* @defgroup IxFeatureCtrlSwConfig Software Configuration for Access Component
*
* @ingroup IxFeatureCtrlAPI
*
* @brief This section describes software configuration in access component. The
* configuration can be changed at run-time. ixFeatureCtrlSwConfigurationCheck( )
* will be used across applicable access component to check the configuration.
* ixFeatureCtrlSwConfigurationWrite( ) is used to write the software configuration.
*
* @note <b>All software configurations are default to be enabled.</b>
*
* @{
*/
/**
* @ingroup IxFeatureCtrlSwConfig
*
* @def IX_FEATURE_CTRL_SWCONFIG_DISABLED
*
* @brief Software configuration is disabled.
*
*/
#define IX_FEATURE_CTRL_SWCONFIG_DISABLED 0
/**
* @ingroup IxFeatureCtrlSwConfig
*
* @def IX_FEATURE_CTRL_SWCONFIG_ENABLED
*
* @brief Software configuration is enabled.
*
*/
#define IX_FEATURE_CTRL_SWCONFIG_ENABLED 1
/**
* Section for enums
**/
/**
* @ingroup IxFeatureCtrlBuildDevice
*
* @enum IxFeatureCtrlBuildDevice
*
* @brief Indicates software build type.
*
* Default build type is IXP42X
*
*/
typedef enum
{
IX_FEATURE_CTRL_SW_BUILD_IXP42X = 0, /**<Build type is IXP42X */
IX_FEATURE_CTRL_SW_BUILD_IXP46X /**<Build type is IXP46X */
} IxFeatureCtrlBuildDevice;
/**
* @ingroup IxFeatureCtrlSwConfig
*
* @enum IxFeatureCtrlSwConfig
*
* @brief Enumeration for software configuration in access components.
*
* Entry for new run-time software configuration should be added here.
*/
typedef enum
{
IX_FEATURECTRL_ETH_LEARNING = 0, /**< EthDB Learning Feature */
IX_FEATURECTRL_ORIGB0_DISPATCHER, /**< IXP42X B0 and IXP46X dispatcher without
livelock prevention functionality Feature */
IX_FEATURECTRL_SWCONFIG_MAX /**< Maximum boudary for IxFeatureCtrlSwConfig */
} IxFeatureCtrlSwConfig;
/************************************************************************
* IXP400 Feature Control Register
* - It contains the information (available/unavailable) of IXP425&IXP46X
* hardware components in their corresponding bit location.
* - Bit value of 0 means the hardware component is available
* or not software disabled. Hardware component that is available
* can be software disabled.
* - Bit value of 1 means the hardware is unavailable or software
* disabled.Hardware component that is unavailable cannot be software
* enabled.
* - Use ixFeatureCtrlHwCapabilityRead() to read the hardware component's
* availability.
* - Use ixFeatureCtrlRead() to get the current IXP425/IXP46X feature control
* register value.
*
* Bit Field Description (Hardware Component Availability)
* --- ---------------------------------------------------
* 0 RComp Circuitry
* 1 USB Controller
* 2 Hashing Coprocessor
* 3 AES Coprocessor
* 4 DES Coprocessor
* 5 HDLC Coprocessor
* 6 AAL Coprocessor - Always available in IXP46X
* 7 HSS Coprocesspr
* 8 Utopia Coprocessor
* 9 Ethernet 0 Coprocessor
* 10 Ethernet 1 Coprocessor
* 11 NPE A
* 12 NPE B
* 13 NPE C
* 14 PCI Controller
* 15 ECC/TimeSync Coprocessor - Only applicable to IXP46X
* 16-17 Utopia PHY Limit Status : 0x0 - 32 PHY
* 0x1 - 16 PHY
* 0x2 - 8 PHY
* 0x3 - 4 PHY
*
* Portions below are only applicable to IXP46X
* 18 USB Host Coprocessor
* 19 NPE A Ethernet - 0 for Enable if Utopia = 1
* 20 NPE B Ethernet coprocessor 1-3.
* 21 RSA Crypto Block coprocessor.
* 22-23 Processor frequency : 0x0 - 533 MHz
* 0x1 - 667 MHz
* 0x2 - 400 MHz
* 0x3 - 266 MHz
* 24-31 Reserved
*
************************************************************************/
/*Section generic to both IXP42X and IXP46X*/
/**
* @ingroup IxFeatureCtrlAPI
*
* @enum IxFeatureCtrlComponentType
*
* @brief Enumeration for components availavble
*
*/
typedef enum
{
IX_FEATURECTRL_RCOMP = 0, /**<bit location for RComp Circuitry*/
IX_FEATURECTRL_USB, /**<bit location for USB Controller*/
IX_FEATURECTRL_HASH, /**<bit location for Hashing Coprocessor*/
IX_FEATURECTRL_AES, /**<bit location for AES Coprocessor*/
IX_FEATURECTRL_DES, /**<bit location for DES Coprocessor*/
IX_FEATURECTRL_HDLC, /**<bit location for HDLC Coprocessor*/
IX_FEATURECTRL_AAL, /**<bit location for AAL Coprocessor*/
IX_FEATURECTRL_HSS, /**<bit location for HSS Coprocessor*/
IX_FEATURECTRL_UTOPIA, /**<bit location for UTOPIA Coprocessor*/
IX_FEATURECTRL_ETH0, /**<bit location for Ethernet 0 Coprocessor*/
IX_FEATURECTRL_ETH1, /**<bit location for Ethernet 1 Coprocessor*/
IX_FEATURECTRL_NPEA, /**<bit location for NPE A*/
IX_FEATURECTRL_NPEB, /**<bit location for NPE B*/
IX_FEATURECTRL_NPEC, /**<bit location for NPE C*/
IX_FEATURECTRL_PCI, /**<bit location for PCI Controller*/
IX_FEATURECTRL_ECC_TIMESYNC, /**<bit location for TimeSync Coprocessor*/
IX_FEATURECTRL_UTOPIA_PHY_LIMIT, /**<bit location for Utopia PHY Limit Status*/
IX_FEATURECTRL_UTOPIA_PHY_LIMIT_BIT2, /**<2nd bit of PHY limit status*/
IX_FEATURECTRL_USB_HOST_CONTROLLER, /**<bit location for USB host controller*/
IX_FEATURECTRL_NPEA_ETH, /**<bit location for NPE-A Ethernet Disable*/
IX_FEATURECTRL_NPEB_ETH, /**<bit location for NPE-B Ethernet 1-3 Coprocessors Disable*/
IX_FEATURECTRL_RSA, /**<bit location for RSA Crypto block Coprocessors Disable*/
IX_FEATURECTRL_XSCALE_MAX_FREQ, /**<bit location for XScale max frequency*/
IX_FEATURECTRL_XSCALE_MAX_FREQ_BIT2, /**<2nd xscale max freq bit NOT TO BE USED */
IX_FEATURECTRL_MAX_COMPONENTS
} IxFeatureCtrlComponentType;
/**
* @ingroup IxFeatureCtrlDeviceId
*
* @enum IxFeatureCtrlDeviceId
*
* @brief Enumeration for device type.
*
* @warning This enum is closely related to the npe image. Its format should comply
* with formats used in the npe image ImageID. This is indicated by the
* first nibble of the image ID. This should also be in sync with the
* with what is defined in CP15. Current available formats are
* - IXP42X - 0000
* - IXP46X - 0001
*
*/
typedef enum
{
IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X = 0, /**<Device type is IXP42X */
IX_FEATURE_CTRL_DEVICE_TYPE_IXP46X, /**<Device type is IXP46X */
IX_FEATURE_CTRL_DEVICE_TYPE_MAX /**<Max devices */
} IxFeatureCtrlDeviceId;
/**
* @} addtogroup IxFeatureCtrlSwConfig
*/
/*
* Typedefs
*/
/**
* @ingroup IxFeatureCtrlAPI
*
* @typedef IxFeatureCtrlReg
*
* @brief Feature Control Register that contains hardware components'
* availability information.
*/
typedef UINT32 IxFeatureCtrlReg;
/**
* @ingroup IxFeatureCtrlAPI
*
* @typedef IxFeatureCtrlProductId
*
* @brief Product ID of Silicon that contains Silicon Stepping and
* Maximum XScale Core Frequency information.
*/
typedef UINT32 IxFeatureCtrlProductId;
/*
* Prototypes for interface functions
*/
/**
* @ingroup IxFeatureCtrlAPI
*
* @fn IxFeatureCtrlReg ixFeatureCtrlRead (void)
*
* @brief This function reads out the CURRENT value of Feature Control Register.
* The current value may not be the same as that of the hardware component
* availability.
*
* The bit location of each hardware component is defined above.
* A value of '1' in bit means the hardware component is not available. A value of '0'
* means the hardware component is available.
*
* @return
* - IxFeatureCtrlReg - the current value of IXP400 Feature Control Register
*/
PUBLIC IxFeatureCtrlReg
ixFeatureCtrlRead (void);
/**
* @ingroup IxFeatureCtrlAPI
*
* @fn IxFeatureDeviceId ixFeatureCtrlDeviceRead (void)
*
* @brief This function gets the type of device that the software is currently running
* on
*
* This function reads the feature Ctrl register specifically to obtain the device id.
* The definitions of the avilable IDs are as above.
*
* @return
* - IxFeatureCtrlDeviceId - the type of device currently running
*/
IxFeatureCtrlDeviceId
ixFeatureCtrlDeviceRead (void);
/**
* @ingroup IxFeatureCtrlAPI
*
* @fn IxFeatureCtrlBuildDevice ixFeatureCtrlSoftwareBuildGet (void)
*
* @brief This function refers to the value set by the compiler flag to determine
* the type of device the software is built for.
*
* The function reads the compiler flag to determine the device the software is
* built for. When the user executes build in the command line,
* a compile time flag (__ixp42X/__ixp46X is set. This API reads this
* flag and returns the software build type to the calling client.
*
* @return
* - IxFeatureCtrlBuildDevice - the type of device software is built for.
*/
IxFeatureCtrlBuildDevice
ixFeatureCtrlSoftwareBuildGet (void);
/**
* @ingroup IxFeatureCtrlAPI
*
* @fn IxFeatureCtrlReg ixFeatureCtrlHwCapabilityRead (void)
*
* @brief This function reads out the hardware capability of a silicon type as defined in
* feature control register.This value is different from that returned by
* ixFeatureCtrlRead() because this function returns the actual hardware component
* availability.
*
* The bit location of each hardware component is defined above.
* A value of '1' in bit means the hardware component is not available. A value of '0'
* means the hardware component is available.
*
* @return
* - IxFeatureCtrlReg - the hardware capability of IXP400.
*
* @warning
* - This function must not be called when IXP400 is running as the result
* is undefined.
*/
PUBLIC IxFeatureCtrlReg
ixFeatureCtrlHwCapabilityRead (void);
/**
* @ingroup IxFeatureCtrlAPI
*
* @fn void ixFeatureCtrlWrite (IxFeatureCtrlReg expUnitReg)
*
* @brief This function write the value stored in IxFeatureCtrlReg expUnitReg
* to the Feature Control Register.
*
* The bit location of each hardware component is defined above.
* The write is only effective on available hardware components. Writing '1' in a
* bit will software disable the respective hardware component. A '0' will mean that
* the hardware component will remain to be operable.
*
* @param expUnitReg @ref IxFeatureCtrlReg [in] - The value to be written to feature control
* register.
*
* @return none
*
*/
PUBLIC void
ixFeatureCtrlWrite (IxFeatureCtrlReg expUnitReg);
/**
* @ingroup IxFeatureCtrlAPI
*
* @fn IX_STATUS ixFeatureCtrlComponentCheck (IxFeatureCtrlComponentType componentType)
*
* @brief This function will check the availability of hardware component specified
* as componentType value.
*
* Usage Example:<br>
* - if(IX_FEATURE_CTRL_COMPONENT_DISABLED !=
* ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0)) <br>
* - if(IX_FEATURE_CTRL_COMPONENT_ENABLED ==
* ixFeatureCtrlComponentCheck(IX_FEATURECTRL_PCI)) <br>
*
* This function is typically called during component initialization time.
*
* @param componentType @ref IxFeatureCtrlComponentType [in] - the type of a component as
* defined above as IX_FEATURECTRL_XXX (Exp: IX_FEATURECTRL_PCI, IX_FEATURECTRL_ETH0)
*
* @return
* - IX_FEATURE_CTRL_COMPONENT_ENABLED if component is available
* - IX_FEATURE_CTRL_COMPONENT_DISABLED if component is unavailable
*/
PUBLIC IX_STATUS
ixFeatureCtrlComponentCheck (IxFeatureCtrlComponentType componentType);
/**
* @ingroup IxFeatureCtrlAPI
*
* @fn IxFeatureCtrlProductId ixFeatureCtrlProductIdRead (void)
*
* @brief This function will return IXP400 product ID i.e. CP15,
* Register 0.
*
* @return
* - IxFeatureCtrlProductId - the value of product ID.
*
*/
PUBLIC IxFeatureCtrlProductId
ixFeatureCtrlProductIdRead (void) ;
/**
* @ingroup IxFeatureCtrlAPI
*
* @fn IX_STATUS ixFeatureCtrlSwConfigurationCheck (IxFeatureCtrlSwConfig swConfigType)
*
* @brief This function checks whether the specified software configuration is
* enabled or disabled.
*
* Usage Example:<br>
* - if(IX_FEATURE_CTRL_SWCONFIG_DISABLED !=
* ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING)) <br>
* - if(IX_FEATURE_CTRL_SWCONFIG_ENABLED ==
* ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING)) <br>
*
* This function is typically called during access component initialization time.
*
* @param swConfigType @ref IxFeatureCtrlSwConfig [in] - the type of a software configuration
* defined in IxFeatureCtrlSwConfig enumeration.
*
* @return
* - IX_FEATURE_CTRL_SWCONFIG_ENABLED if software configuration is enabled.
* - IX_FEATURE_CTRL_SWCONFIG_DISABLED if software configuration is disabled.
*/
PUBLIC IX_STATUS
ixFeatureCtrlSwConfigurationCheck (IxFeatureCtrlSwConfig swConfigType);
/**
* @ingroup IxFeatureCtrlAPI
*
* @fn void ixFeatureCtrlSwConfigurationWrite (IxFeatureCtrlSwConfig swConfigType, BOOL enabled)
*
* @brief This function enable/disable the specified software configuration.
*
* Usage Example:<br>
* - ixFeatureCtrlSwConfigurationWrite(IX_FEATURECTRL_ETH_LEARNING, TRUE) is used
* to enable Ethernet Learning Feature <br>
* - ixFeatureCtrlSwConfigurationWrite(IX_FEATURECTRL_ETH_LEARNING, FALSE) is used
* to disable Ethernet Learning Feature <br>
*
* @param swConfigType IxFeatureCtrlSwConfig [in] - the type of a software configuration
* defined in IxFeatureCtrlSwConfig enumeration.
* @param enabled BOOL [in] - To enable(TRUE) / disable (FALSE) the specified software
* configuration.
*
* @return none
*
*/
PUBLIC void
ixFeatureCtrlSwConfigurationWrite (IxFeatureCtrlSwConfig swConfigType, BOOL enabled);
/**
* @ingroup IxFeatureCtrlAPI
*
* @fn void ixFeatureCtrlIxp400SwVersionShow (void)
*
* @brief This function shows the current software release information for IXP400
*
* @return none
*
*/
PUBLIC void
ixFeatureCtrlIxp400SwVersionShow (void);
#endif /* IXFEATURECTRL_H */
/**
* @} defgroup IxFeatureCtrlAPI
*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,867 @@
/**
* @file IxI2cDrv.h
*
* @brief Header file for the IXP400 I2C Driver (IxI2cDrv)
*
* @version $Revision: 0.1 $
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
/**
* @defgroup IxI2cDrv IXP400 I2C Driver(IxI2cDrv) API
*
* @brief IXP400 I2C Driver Public API
*
* @{
*/
#ifndef IXI2CDRV_H
#define IXI2CDRV_H
#ifdef __ixp46X
#include "IxOsal.h"
/*
* Section for #define
*/
/**
* @ingroup IxI2cDrv
* @brief The interval of micro/mili seconds the IXP will wait before it polls for
* status from the ixI2cIntrXferStatus; Every 20us is 1 byte @
* 400Kbps and 4 bytes @ 100Kbps. This is dependent on delay type selected
* through the API ixI2cDrvDelayTypeSelect.
*/
#define IX_I2C_US_POLL_FOR_XFER_STATUS 20
/**
* @ingroup IxI2cDrv
* @brief The number of tries that will be attempted to call a callback
* function if the callback does not or is unable to resolve the
* issue it is called to resolve
*/
#define IX_I2C_NUM_OF_TRIES_TO_CALL_CALLBACK_FUNC 10
/**
* @ingroup IxI2cDrv
* @brief Number of tries slave will poll the IDBR Rx full bit before it
* gives up
*/
#define IX_I2C_NUM_TO_POLL_IDBR_RX_FULL 0x100
/**
* @ingroup IxI2cDrv
* @brief Number of tries slave will poll the IDBR Tx empty bit before it
* gives up
*/
#define IX_I2C_NUM_TO_POLL_IDBR_TX_EMPTY 0x100
/*
* Section for enum
*/
/**
* @ingroup IxI2cDrv
*
* @enum IxI2cMasterStatus
*
* @brief The master status - transfer complete, bus error or arbitration loss
*/
typedef enum
{
IX_I2C_MASTER_XFER_COMPLETE = IX_SUCCESS,
IX_I2C_MASTER_XFER_BUS_ERROR,
IX_I2C_MASTER_XFER_ARB_LOSS
} IxI2cMasterStatus;
/**
* @ingroup IxI2cDrv
*
* @enum IX_I2C_STATUS
*
* @brief The status that can be returned in a I2C driver initialization
*/
typedef enum
{
IX_I2C_SUCCESS = IX_SUCCESS, /**< Success status */
IX_I2C_FAIL, /**< Fail status */
IX_I2C_NOT_SUPPORTED, /**< hardware does not have dedicated I2C hardware */
IX_I2C_NULL_POINTER, /**< parameter passed in is NULL */
IX_I2C_INVALID_SPEED_MODE_ENUM_VALUE, /**< speed mode selected is invalid */
IX_I2C_INVALID_FLOW_MODE_ENUM_VALUE, /**< flow mode selected is invalid */
IX_I2C_SLAVE_ADDR_CB_MISSING, /**< slave callback is NULL */
IX_I2C_GEN_CALL_CB_MISSING, /**< general callback is NULL */
IX_I2C_INVALID_SLAVE_ADDR, /**< invalid slave address specified */
IX_I2C_INT_BIND_FAIL, /**< interrupt bind fail */
IX_I2C_INT_UNBIND_FAIL, /**< interrupt unbind fail */
IX_I2C_NOT_INIT, /**< I2C is not initialized yet */
IX_I2C_MASTER_BUS_BUSY, /**< master detected a I2C bus busy */
IX_I2C_MASTER_ARB_LOSS, /**< master experienced arbitration loss */
IX_I2C_MASTER_XFER_ERROR, /**< master experienced a transfer error */
IX_I2C_MASTER_BUS_ERROR, /**< master detected a I2C bus error */
IX_I2C_MASTER_NO_BUFFER, /**< no buffer provided for master transfer */
IX_I2C_MASTER_INVALID_XFER_MODE, /**< xfer mode selected is invalid */
IX_I2C_SLAVE_ADDR_NOT_DETECTED, /**< polled slave addr not detected */
IX_I2C_GEN_CALL_ADDR_DETECTED, /**< polling detected general call */
IX_I2C_SLAVE_READ_DETECTED, /**< polling detected slave read request */
IX_I2C_SLAVE_WRITE_DETECTED, /**< polling detected slave write request */
IX_I2C_SLAVE_NO_BUFFER, /**< no buffer provided for slave transfers */
IX_I2C_DATA_SIZE_ZERO, /**< data size transfer is zero - invalid */
IX_I2C_SLAVE_WRITE_BUFFER_EMPTY, /**< slave buffer is used till empty */
IX_I2C_SLAVE_WRITE_ERROR, /**< slave write experienced an error */
IX_I2C_SLAVE_OR_GEN_READ_BUFFER_FULL, /**< slave buffer is filled up */
IX_I2C_SLAVE_OR_GEN_READ_ERROR /**< slave read experienced an error */
} IX_I2C_STATUS;
/**
* @ingroup IxI2cDrv
*
* @enum IxI2cSpeedMode
*
* @brief Type of speed modes supported by the I2C hardware.
*/
typedef enum
{
IX_I2C_NORMAL_MODE = 0x0,
IX_I2C_FAST_MODE
} IxI2cSpeedMode;
/**
* @ingroup IxI2cDrv
*
* @enum IxI2cXferMode
*
* @brief Used for indicating it is a repeated start or normal transfer
*/
typedef enum
{
IX_I2C_NORMAL = 0x0,
IX_I2C_REPEATED_START
} IxI2cXferMode;
/**
* @ingroup IxI2cDrv
*
* @enum IxI2cFlowMode
*
* @brief Used for indicating it is a poll or interrupt mode
*/
typedef enum
{
IX_I2C_POLL_MODE = 0x0,
IX_I2C_INTERRUPT_MODE
} IxI2cFlowMode;
/**
* @ingroup IxI2cDrv
*
* @enum IxI2cDelayMode
*
* @brief Used for selecting looping delay or OS scheduler delay
*/
typedef enum
{
IX_I2C_LOOP_DELAY = 1, /**< delay in microseconds */
IX_I2C_SCHED_DELAY /**< delay in miliseconds */
} IxI2cDelayMode;
/**
* @ingroup IxI2cDrv
*
* @brief The pointer to the function that will be called when the master
* has completed its receive. The parameter that is passed will
* provide the status of the read (success, arb loss, or bus
* error), the transfer mode (normal or repeated start, the
* buffer pointer and number of bytes transferred.
*/
typedef void (*IxI2cMasterReadCallbackP)(IxI2cMasterStatus, IxI2cXferMode, char*, UINT32);
/**
* @ingroup IxI2cDrv
*
* @brief The pointer to the function that will be called when the master
* has completed its transmit. The parameter that is passed will
* provide the status of the write (success, arb loss, or buss
* error), the transfer mode (normal or repeated start), the
* buffer pointer and number of bytes transferred.
*/
typedef void (*IxI2cMasterWriteCallbackP)(IxI2cMasterStatus, IxI2cXferMode, char*, UINT32);
/**
* @ingroup IxI2cDrv
*
* @brief The pointer to the function that will be called when a slave
* address detected in interrupt mode for a read. The parameters
* that is passed will provide the read status, buffer pointer,
* buffer size, and the bytes received. When a start of a read
* is initiated there will be no buffer allocated and this callback
* will be called to request for a buffer. While receiving, if the
* buffer gets filled, this callback will be called to request for
* a new buffer while sending the filled buffer's pointer and size,
* and data size received. When the receive is complete, this
* callback will be called to process the data and free the memory
* by passing the buffer's pointer and size, and data size received.
*/
typedef void (*IxI2cSlaveReadCallbackP)(IX_I2C_STATUS, char*, UINT32, UINT32);
/**
* @ingroup IxI2cDrv
*
* @brief The pointer to the function that will be called when a slave
* address detected in interrupt mode for a write. The parameters
* that is passed will provide the write status, buffer pointer,
* buffer size, and the bytes received. When a start of a write is
* initiated there will be no buffer allocated and this callback
* will be called to request for a buffer and to fill it with data.
* While transmitting, if the data in the buffer empties, this
* callback will be called to request for more data to be filled in
* the same or new buffer. When the transmit is complete, this
* callback will be called to free the memory or other actions to
* be taken.
*/
typedef void (*IxI2cSlaveWriteCallbackP)(IX_I2C_STATUS, char*, UINT32, UINT32);
/**
* @ingroup IxI2cDrv
*
* @brief The pointer to the function that will be called when a general
* call detected in interrupt mode for a read. The parameters that
* is passed will provide the read status, buffer pointer, buffer
* size, and the bytes received. When a start of a read is
* initiated there will be no buffer allocated and this callback
* will be called to request for a buffer. While receiving, if the
* buffer gets filled, this callback will be called to request for
* a new buffer while sending the filled buffer's pointer and size,
* and data size received. When the receive is complete, this
* callback will be called to process the data and free the memory
* by passing the buffer's pointer and size, and data size received.
*/
typedef void (*IxI2cGenCallCallbackP)(IX_I2C_STATUS, char*, UINT32, UINT32);
/*
* Section for struct
*/
/**
* @brief contains all the variables required to initialize the I2C unit
*
* Structure to be filled and used for calling initialization
*/
typedef struct
{
IxI2cSpeedMode I2cSpeedSelect; /**<Select either normal (100kbps)
or fast mode (400kbps)*/
IxI2cFlowMode I2cFlowSelect; /**<Select interrupt or poll mode*/
IxI2cMasterReadCallbackP MasterReadCBP;
/**<The master read callback pointer */
IxI2cMasterWriteCallbackP MasterWriteCBP;
/**<The master write callback pointer */
IxI2cSlaveReadCallbackP SlaveReadCBP;
/**<The slave read callback pointer */
IxI2cSlaveWriteCallbackP SlaveWriteCBP;
/**<The slave write callback pointer */
IxI2cGenCallCallbackP GenCallCBP;
/**<The general call callback pointer */
BOOL I2cGenCallResponseEnable; /**<Enable/disable the unit to
respond to generall calls.*/
BOOL I2cSlaveAddrResponseEnable;/**<Enable/disable the unit to
respond to the slave address set in
ISAR*/
BOOL SCLEnable; /**<Enable/disable the unit from
driving the SCL line during master
mode operation*/
UINT8 I2cHWAddr; /**<The address the unit will
response to as a slave device*/
} IxI2cInitVars;
/**
* @brief contains results of counters and their overflow
*
* Structure contains all values of counters and associated overflows.
*/
typedef struct
{
UINT32 ixI2cMasterXmitCounter; /**<Total bytes transmitted as
master.*/
UINT32 ixI2cMasterFailedXmitCounter; /**<Total bytes failed for
transmission as master.*/
UINT32 ixI2cMasterRcvCounter; /**<Total bytes received as
master.*/
UINT32 ixI2cMasterFailedRcvCounter; /**<Total bytes failed for
receival as master.*/
UINT32 ixI2cSlaveXmitCounter; /**<Total bytes transmitted as
slave.*/
UINT32 ixI2cSlaveFailedXmitCounter; /**<Total bytes failed for
transmission as slave.*/
UINT32 ixI2cSlaveRcvCounter; /**<Total bytes received as
slave.*/
UINT32 ixI2cSlaveFailedRcvCounter; /**<Total bytes failed for
receival as slave.*/
UINT32 ixI2cGenAddrCallSucceedCounter; /**<Total bytes successfully
transmitted for general address.*/
UINT32 ixI2cGenAddrCallFailedCounter; /**<Total bytes failed transmission
for general address.*/
UINT32 ixI2cArbLossCounter; /**<Total instances of arbitration
loss has occured.*/
} IxI2cStatsCounters;
/*
* Section for prototypes interface functions
*/
/**
* @ingroup IxI2cDrv
*
* @fn ixI2cDrvInit(
IxI2cInitVars *InitVarsSelected)
*
* @brief Initializes the I2C Driver.
*
* @param "IxI2cInitVars [in] *InitVarsSelected" - struct containing required
* variables for initialization
*
* Global Data :
* - None.
*
* This API will check if the hardware supports this I2C driver and the validity
* of the parameters passed in. It will continue to process the parameters
* passed in by setting the speed of the I2C unit (100kbps or 400kbps), setting
* the flow to either interrupt or poll mode, setting the address of the I2C unit,
* enabling/disabling the respond to General Calls, enabling/disabling the respond
* to Slave Address and SCL line driving. If it is interrupt mode, then it will
* register the callback routines for master, slavetransfer and general call receive.
*
* @return
* - IX_I2C_SUCCESS - Successfully initialize and enable the I2C
* hardware.
* - IX_I2C_NOT_SUPPORTED - The hardware does not support or have a
* dedicated I2C unit to support this driver
* - IX_I2C_NULL_POINTER - The parameter passed in is a NULL pointed
* - IX_I2C_INVALID_SPEED_MODE_ENUM_VALUE - The speed mode selected in the
* InitVarsSelected is invalid
* - IX_I2C_INVALID_FLOW_MODE_ENUM_VALUE - The flow mode selected in the
* InitVarsSelected is invalid
* - IX_I2C_INVALID_SLAVE_ADDR - The address 0x0 is reserved for
* general call.
* - IX_I2C_SLAVE_ADDR_CB_MISSING - interrupt mode is selected but
* slave address callback pointer is NULL
* - IX_I2C_GEN_CALL_CB_MISSING - interrupt mode is selected but
* general call callback pointer is NULL
* - IX_I2C_INT_BIND_FAIL - The ISR for the I2C failed to bind
* - IX_I2C_INT_UNBIND_FAIL - The ISR for the I2C failed to unbind
*
* @li Reentrant : yes
* @li ISR Callable : yes
*
*/
PUBLIC IX_I2C_STATUS
ixI2cDrvInit(IxI2cInitVars *InitVarsSelected);
/**
* @ingroup IxI2cDrv
*
* @fn ixI2cDrvUninit(
void)
*
* @brief Disables the I2C hardware
*
* @param - None
*
* Global Data :
* - None.
*
* This API will disable the I2C hardware, unbind interrupt, and unmap memory.
*
* @return
* - IX_I2C_SUCCESS - successfully un-initialized I2C
* - IX_I2C_INT_UNBIND_FAIL - failed to unbind the I2C interrupt
* - IX_I2C_NOT_INIT - I2C not init yet.
*
* @li Reentrant : yes
* @li ISR Callable : yes
*
*/
PUBLIC IX_I2C_STATUS
ixI2cDrvUninit(void);
/**
* @ingroup IxI2cDrv
*
* @fn ixI2cDrvSlaveAddrSet(
UINT8 SlaveAddrSet)
*
* @brief Sets the I2C Slave Address
*
* @param "UINT8 [in] SlaveAddrSet" - Slave Address to be inserted into ISAR
*
* Global Data :
* - None.
*
* This API will insert the SlaveAddrSet into the ISAR.
*
* @return
* - IX_I2C_SUCCESS - successfuly set the slave addr
* - IX_I2C_INVALID_SLAVE_ADDR - invalid slave address (zero) specified
* - IX_I2C_NOT_INIT - I2C not init yet.
*
* @li Reentrant : yes
* @li ISR Callable : yes
*
*/
PUBLIC IX_I2C_STATUS
ixI2cDrvSlaveAddrSet(UINT8 SlaveAddrSet);
/**
* @ingroup IxI2cDrv
*
* @fn ixI2cDrvBusScan(
void)
*
* @brief scans the I2C bus for slave devices
*
* @param - None
*
* Global Data :
* - None.
*
* This API will prompt all slave addresses for a reply except its own
*
* @return
* - IX_I2C_SUCCESS - found at least one slave device
* - IX_I2C_FAIL - Fail to find even one slave device
* - IX_I2C_BUS_BUSY - The I2C bus is busy (held by another I2C master)
* - IX_I2C_ARB_LOSS - The I2C bus was loss to another I2C master
* - IX_I2C_NOT_INIT - I2C not init yet.
*
* @li Reentrant : yes
* @li ISR Callable : yes
*
*/
PUBLIC IX_I2C_STATUS
ixI2cDrvBusScan(void);
/**
* @ingroup IxI2cDrv
*
* @fn ixI2cDrvWriteTransfer(
UINT8 SlaveAddr,
char *bufP,
UINT32 dataSize,
IxI2cXferMode XferModeSelect)
*
* @param "UINT8 [in] SlaveAddr" - The slave address to request data from.
* @param "char [in] *bufP" - The pointer to the data to be transmitted.
* @param "UINT32 [in] dataSize" - The number of bytes requested.
* @param "IxI2cXferMode [in] XferModeSelect" - the transfer mode selected,
* either repeated start (ends w/o stop) or normal (start and stop)
*
* Global Data :
* - None.
*
* This API will try to obtain master control of the I2C bus and transmit the
* number of bytes, specified by dataSize, to the user specified slave
* address from the buffer pointer. It will use either interrupt or poll mode
* depending on the method selected.
*
* If in interrupt mode and IxI2cMasterWriteCallbackP is not NULL, the driver
* will initiate the transfer and return immediately. The function pointed to
* by IxI2cMasterWriteCallbackP will be called in the interrupt service
* handlers when the operation is complete.
*
* If in interrupt mode and IxI2cMasterWriteCallbackP is NULL, then the driver
* will wait for the operation to complete, and then return.
*
* And if the repeated start transfer mode is selected, then it will not send a
* stop signal at the end of all the transfers.
* *NOTE*: If repeated start transfer mode is selected, it has to end with a
* normal mode transfer mode else the bus will continue to be held
* by the IXP.
*
* @return
* - IX_I2C_SUCCESS - Successfuuly wrote data to slave.
* - IX_I2C_MASTER_BUS_BUSY - The I2C bus is busy (held by another I2C master)
* - IX_I2C_MASTER_ARB_LOSS - The I2C bus was loss to another I2C master
* - IX_I2C_MASTER_XFER_ERROR - There was a transfer error
* - IX_I2C_MASTER_BUS_ERROR - There was a bus error during transfer
* - IX_I2C_MASTER_NO_BUFFER - buffer pointer is NULL
* - IX_I2C_MASTER_INVALID_XFER_MODE - Xfer mode selected is invalid
* - IX_I2C_DATA_SIZE_ZERO - dataSize passed in is zero, which is invalid
* - IX_I2C_NOT_INIT - I2C not init yet.
*
* @li Reentrant : no
* @li ISR Callable : no
*
*/
PUBLIC IX_I2C_STATUS
ixI2cDrvWriteTransfer(
UINT8 SlaveAddr,
char *bufP,
UINT32 dataSize,
IxI2cXferMode XferModeSelect);
/**
* @ingroup IxI2cDrv
*
* @fn ixI2cDrvReadTransfer(
UINT8 SlaveAddr,
char *bufP,
UINT32 dataSize,
IxI2cXferMode XferModeSelect)
*
* @brief Initiates a transfer to receive bytes of data from a slave
* device through the I2C bus.
*
* @param "UINT8 [in] SlaveAddr" - The slave address to request data from.
* @param "char [out] *bufP" - The pointer to the buffer to store the
* requested data.
* @param "UINT32 [in] dataSize" - The number of bytes requested.
* @param "IxI2cXferMode [in] XferModeSelect" - the transfer mode selected,
* either repeated start (ends w/o stop) or normal (start and stop)
*
* Global Data :
* - None.
*
* This API will try to obtain master control of the I2C bus and receive the
* number of bytes, specified by dataSize, from the user specified address
* into the receive buffer. It will use either interrupt or poll mode depending
* on the mode selected.
*
* If in interrupt mode and IxI2cMasterReadCallbackP is not NULL, the driver
* will initiate the transfer and return immediately. The function pointed to
* by IxI2cMasterReadCallbackP will be called in the interrupt service
* handlers when the operation is complete.
*
* If in interrupt mode and IxI2cMasterReadCallbackP is NULL, then the driver will
* wait for the operation to complete, and then return.
*
* And if the repeated start transfer mode is selected, then it will not send a
* stop signal at the end of all the transfers.
* *NOTE*: If repeated start transfer mode is selected, it has to end with a
* normal mode transfer mode else the bus will continue to be held
* by the IXP.
*
* @return
* - IX_I2C_SUCCESS - Successfuuly read slave data
* - IX_I2C_MASTER_BUS_BUSY - The I2C bus is busy (held by another I2C master)
* - IX_I2C_MASTER_ARB_LOSS - The I2C bus was loss to another I2C master
* - IX_I2C_MASTER_XFER_ERROR - There was a bus error during transfer
* - IX_I2C_MASTER_BUS_ERROR - There was a bus error during transfer
* - IX_I2C_MASTER_NO_BUFFER - buffer pointer is NULL
* - IX_I2C_MASTER_INVALID_XFER_MODE - Xfer mode selected is invalid
* - IX_I2C_INVALID_SLAVE_ADDR - invalid slave address (zero) specified
* - IX_I2C_DATA_SIZE_ZERO - dataSize passed in is zero, which is invalid
* - IX_I2C_NOT_INIT - I2C not init yet.
*
* @li Reentrant : no
* @li ISR Callable : no
*
*/
PUBLIC IX_I2C_STATUS
ixI2cDrvReadTransfer(
UINT8 SlaveAddr,
char *bufP,
UINT32 dataSize,
IxI2cXferMode XferModeSelect);
/**
* @ingroup IxI2cDrv
*
* @fn ixI2cDrvSlaveAddrAndGenCallDetectedCheck(
void)
*
* @brief Checks the I2C Status Register to determine if a slave address is
* detected
*
* @param - None
*
* Global Data :
* - None.
*
* This API is used in polled mode to determine if the I2C unit is requested
* for a slave or general call transfer. If it is requested for a slave
* transfer then it will determine if it is a general call (read only), read,
* or write transfer requested.
*
* @return
* - IX_I2C_SLAVE_ADDR_NOT_DETECTED - The I2C unit is not requested for slave
* transfer
* - IX_I2C_GEN_CALL_ADDR_DETECTED - The I2C unit is not requested for slave
* transfer but for general call
* - IX_I2C_SLAVE_READ_DETECTED - The I2C unit is requested for a read
* - IX_I2C_SLAVE_WRITE_DETECTED - The I2C unit is requested for a write
* - IX_I2C_NOT_INIT - I2C not init yet.
*
* @li Reentrant : no
* @li ISR Callable : no
*
*/
PUBLIC IX_I2C_STATUS
ixI2cDrvSlaveAddrAndGenCallDetectedCheck(void);
/**
* @ingroup IxI2cDrv
*
* @fn ixI2cDrvSlaveOrGenDataReceive(
char *bufP,
UINT32 bufSize,
UINT32 *dataSizeRcvd)
*
* @brief Performs the slave receive or general call receive data transfer
*
* @param "char [in] *bufP" - the pointer to the buffer to store data
* "UINT32 [in] bufSize" - the buffer size allocated
* "UINT32 [in] *dataSizeRcvd" - the length of data received in bytes
*
* Global Data :
* - None.
*
* This API is only used in polled mode to perform the slave read or general call
* receive data. It will continuously store the data received into bufP until
* complete or until bufP is full in which it will return
* IX_I2C_SLAVE_OR_GEN_READ_BUFFER_FULL. If in interrupt mode, the callback will be
* used.
*
* @return
* - IX_I2C_SUCCESS - The I2C driver transferred the data successfully.
* - IX_I2C_SLAVE_OR_GEN_READ_BUFFER_FULL - The I2C driver has ran out of
* space to store the received data.
* - IX_I2C_SLAVE_OR_GEN_READ_ERROR - The I2C driver didn't manage to
* detect the IDBR Rx Full bit
* - IX_I2C_DATA_SIZE_ZERO - bufSize passed in is zero, which is invalid
* - IX_I2C_SLAVE_NO_BUFFER - buffer pointer is NULL
* - IX_I2C_NULL_POINTER - dataSizeRcvd is NULL
* - IX_I2C_NOT_INIT - I2C not init yet.
*
* @li Reentrant : no
* @li ISR Callable : no
*
*/
PUBLIC IX_I2C_STATUS
ixI2cDrvSlaveOrGenDataReceive(
char *bufP,
UINT32 bufSize,
UINT32 *dataSizeRcvd);
/**
* @ingroup IxI2cDrv
*
* @fn ixI2cDrvSlaveDataTransmit(
char *bufP,
UINT32 dataSize,
UINT32 *dataSizeXmtd)
*
* @brief Performs the slave write data transfer
*
* @param "char [in] *bufP" - the pointer to the buffer for data to be
* transmitted
* "UINT32 [in] bufSize" - the buffer size allocated
* "UINT32 [in] *dataSizeRcvd" - the length of data trasnmitted in
* bytes
*
* Global Data :
* - None.
*
* This API is only used in polled mode to perform the slave transmit data. It
* will continuously transmit the data from bufP until complete or until bufP
* is empty in which it will return IX_I2C_SLAVE_WRITE_BUFFER_EMPTY. If in
* interrupt mode, the callback will be used.
*
* @return
* - IX_I2C_SUCCESS - The I2C driver transferred the data successfully.
* - IX_I2C_SLAVE_WRITE_BUFFER_EMPTY - The I2C driver needs more data to
* transmit.
* - IX_I2C_SLAVE_WRITE_ERROR -The I2C driver didn't manage to detect the
* IDBR Tx empty bit or the slave stop bit.
* - IX_I2C_DATA_SIZE_ZERO - dataSize passed in is zero, which is invalid
* - IX_I2C_SLAVE_NO_BUFFER - buffer pointer is NULL
* - IX_I2C_NULL_POINTER - dataSizeXmtd is NULL
* - IX_I2C_NOT_INIT - I2C not init yet.
*
* @li Reentrant : no
* @li ISR Callable : no
*
*/
PUBLIC IX_I2C_STATUS
ixI2cDrvSlaveDataTransmit(
char *bufP,
UINT32 dataSize,
UINT32 *dataSizeXmtd);
/**
* @ingroup IxI2cDrv
*
* @fn ixI2cDrvSlaveOrGenCallBufReplenish(
char *bufP,
UINT32 bufSize)
*
* @brief Replenishes the buffer which stores buffer info for both slave and
* general call
*
* @param "char [in] *bufP" - pointer to the buffer allocated
* "UINT32 [in] bufSize" - size of the buffer
*
* Global Data :
* - None.
*
* This API is only used in interrupt mode for replenishing the same buffer
* that is used by both slave and generall call by updating the buffer info
* with new info and clearing previous offsets set by previous transfers.
*
* @return
* - None
*
* @li Reentrant : no
* @li ISR Callable : no
*
*/
PUBLIC void
ixI2cDrvSlaveOrGenCallBufReplenish(
char *bufP,
UINT32 bufSize);
/**
* @ingroup IxI2cDrv
*
* @fn ixI2cDrvStatsGet(IxI2cStatsCounters *I2cStats)
*
* @brief Returns the I2C Statistics through the pointer passed in
*
* @param - "IxI2cStatsCounters [out] *I2cStats" - I2C statistics counter will
* be read and written to the location pointed by this pointer.
*
* Global Data :
* - None.
*
* This API will return the statistics counters of the I2C driver.
*
* @return
* - IX_I2C_NULL_POINTER - pointer passed in is NULL
* - IX_I2C_SUCCESS - successfully obtained I2C statistics
*
* @li Reentrant : yes
* @li ISR Callable : no
*
*/
PUBLIC IX_I2C_STATUS
ixI2cDrvStatsGet(IxI2cStatsCounters *I2cStats);
/**
* @ingroup IxI2cDrv
*
* @fn ixI2cDrvStatsReset(void)
*
* @brief Reset I2C statistics counters.
*
* @param - None
*
* Global Data :
* - None.
*
* This API will reset the statistics counters of the I2C driver.
*
* @return
* - None
*
* @li Reentrant : yes
* @li ISR Callable : no
*
*/
PUBLIC void
ixI2cDrvStatsReset(void);
/**
* @ingroup IxI2cDrv
*
* @fn ixI2cDrvShow(void)
*
* @brief Displays the I2C status register and the statistics counter.
*
* @param - None
*
* Global Data :
* - None.
*
* This API will display the I2C Status register and is useful if any error
* occurs. It displays the detection of bus error, slave address, general call,
* address, IDBR receive full, IDBR transmit empty, arbitration loss, slave
* STOP signal, I2C bus busy, unit busy, ack/nack, and read/write mode. It will
* also call the ixI2cDrvGetStats and then display the statistics counter.
*
* @return
* - IX_I2C_SUCCESS - successfully displayed statistics and status register
* - IX_I2C_NOT_INIT - I2C not init yet.
*
* @li Reentrant : yes
* @li ISR Callable : no
*
*/
PUBLIC IX_I2C_STATUS
ixI2cDrvShow(void);
/**
* @ingroup IxI2cDrv
*
* @fn ixI2cDrvDelayTypeSelect (IxI2cDelayMode delayMechanismSelect)
*
* @brief Sets the delay type of either looping delay or OS scheduler delay
* according to the argument provided.
*
* @param - "IxI2cDelayMode [in] delayTypeSelect" - the I2C delay type selected
*
* Global Data :
* - None.
*
* This API will set the delay type used by the I2C Driver to either looping
* delay or OS scheduler delay.
*
* @return
* - None
*
* @li Reentrant : yes
* @li ISR Callable : no
*
*/
PUBLIC void
ixI2cDrvDelayTypeSelect (IxI2cDelayMode delayTypeSelect);
#endif /* __ixp46X */
#endif /* IXI2CDRV_H */

View file

@ -0,0 +1,782 @@
#ifndef __doxygen_HIDE /* This file is not part of the API */
/**
* @file IxNpeA.h
*
* @date 22-Mar-2002
*
* @brief Header file for the IXP400 ATM NPE API
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
/**
* @defgroup IxNpeA IXP400 NPE-A (IxNpeA) API
*
* @brief The Public API for the IXP400 NPE-A
*
* @{
*/
#ifndef IX_NPE_A_H
#define IX_NPE_A_H
#include "IxQMgr.h"
#include "IxOsal.h"
#include "IxQueueAssignments.h"
/* General Message Ids */
/* ATM Message Ids */
/**
* @def IX_NPE_A_MSSG_ATM_UTOPIA_CONFIG_WRITE
*
* @brief ATM Message ID command to write the data to the offset in the
* Utopia Configuration Table
*/
#define IX_NPE_A_MSSG_ATM_UTOPIA_CONFIG_WRITE 0x20
/**
* @def IX_NPE_A_MSSG_ATM_UTOPIA_CONFIG_LOAD
*
* @brief ATM Message ID command triggers the NPE to copy the Utopia
* Configuration Table to the Utopia coprocessor
*/
#define IX_NPE_A_MSSG_ATM_UTOPIA_CONFIG_LOAD 0x21
/**
* @def IX_NPE_A_MSSG_ATM_UTOPIA_STATUS_UPLOAD
*
* @brief ATM Message ID command triggers the NPE to read-back the Utopia
* status registers and update the Utopia Status Table.
*/
#define IX_NPE_A_MSSG_ATM_UTOPIA_STATUS_UPLOAD 0x22
/**
* @def IX_NPE_A_MSSG_ATM_UTOPIA_STATUS_READ
*
* @brief ATM Message ID command to read the Utopia Status Table at the
* specified offset.
*/
#define IX_NPE_A_MSSG_ATM_UTOPIA_STATUS_READ 0x23
/**
* @def IX_NPE_A_MSSG_ATM_TX_ENABLE
*
* @brief ATM Message ID command triggers the NPE to re-enable processing
* of any entries on the TxVcQ for this port.
*
* This command will be ignored for a port already enabled
*/
#define IX_NPE_A_MSSG_ATM_TX_ENABLE 0x25
/**
* @def IX_NPE_A_MSSG_ATM_TX_DISABLE
*
* @brief ATM Message ID command triggers the NPE to disable processing on
* this port
*
* This command will be ignored for a port already disabled
*/
#define IX_NPE_A_MSSG_ATM_TX_DISABLE 0x26
/**
* @def IX_NPE_A_MSSG_ATM_RX_ENABLE
*
* @brief ATM Message ID command triggers the NPE to process any received
* cells for this VC according to the VC Lookup Table.
*
* Re-issuing this command with different contents for a VC that is not
* disabled will cause unpredictable behavior.
*/
#define IX_NPE_A_MSSG_ATM_RX_ENABLE 0x27
/**
* @def IX_NPE_A_MSSG_ATM_RX_DISABLE
*
* @brief ATM Message ID command triggers the NPE to disable processing for
* this VC.
*
* This command will be ignored for a VC already disabled
*/
#define IX_NPE_A_MSSG_ATM_RX_DISABLE 0x28
/**
* @def IX_NPE_A_MSSG_ATM_STATUS_READ
*
* @brief ATM Message ID command to read the ATM status. The data is returned via
* a response message
*/
#define IX_NPE_A_MSSG_ATM_STATUS_READ 0x29
/*--------------------------------------------------------------------------
* HSS Message IDs
*--------------------------------------------------------------------------*/
/**
* @def IX_NPE_A_MSSG_HSS_PORT_CONFIG_WRITE
*
* @brief HSS Message ID command writes the ConfigWord value to the location
* in the HSS_CONFIG_TABLE specified by offset for HSS port hPort.
*/
#define IX_NPE_A_MSSG_HSS_PORT_CONFIG_WRITE 0x40
/**
* @def IX_NPE_A_MSSG_HSS_PORT_CONFIG_LOAD
*
* @brief HSS Message ID command triggers the NPE to copy the contents of the
* HSS Configuration Table to the appropriate configuration registers in the
* HSS coprocessor for the port specified by hPort.
*/
#define IX_NPE_A_MSSG_HSS_PORT_CONFIG_LOAD 0x41
/**
* @def IX_NPE_A_MSSG_HSS_PORT_ERROR_READ
*
* @brief HSS Message ID command triggers the NPE to return an HssErrorReadResponse
* message for HSS port hPort.
*/
#define IX_NPE_A_MSSG_HSS_PORT_ERROR_READ 0x42
/**
* @def IX_NPE_A_MSSG_HSS_CHAN_FLOW_ENABLE
*
* @brief HSS Message ID command triggers the NPE to reset internal status and
* enable the HssChannelized operation on the HSS port specified by hPort.
*/
#define IX_NPE_A_MSSG_HSS_CHAN_FLOW_ENABLE 0x43
/**
* @def IX_NPE_A_MSSG_HSS_CHAN_FLOW_DISABLE
*
* @brief HSS Message ID command triggers the NPE to disable the HssChannelized
* operation on the HSS port specified by hPort.
*/
#define IX_NPE_A_MSSG_HSS_CHAN_FLOW_DISABLE 0x44
/**
* @def IX_NPE_A_MSSG_HSS_CHAN_IDLE_PATTERN_WRITE
*
* @brief HSS Message ID command writes the HSSnC_IDLE_PATTERN value for HSS
* port hPort. (n=hPort)
*/
#define IX_NPE_A_MSSG_HSS_CHAN_IDLE_PATTERN_WRITE 0x45
/**
* @def IX_NPE_A_MSSG_HSS_CHAN_NUM_CHANS_WRITE
*
* @brief HSS Message ID command writes the HSSnC_NUM_CHANNELS value for HSS
* port hPort. (n=hPort)
*/
#define IX_NPE_A_MSSG_HSS_CHAN_NUM_CHANS_WRITE 0x46
/**
* @def IX_NPE_A_MSSG_HSS_CHAN_RX_BUF_ADDR_WRITE
*
* @brief HSS Message ID command writes the HSSnC_RX_BUF_ADDR value for HSS
* port hPort. (n=hPort)
*/
#define IX_NPE_A_MSSG_HSS_CHAN_RX_BUF_ADDR_WRITE 0x47
/**
* @def IX_NPE_A_MSSG_HSS_CHAN_RX_BUF_CFG_WRITE
*
* @brief HSS Message ID command writes the HSSnC_RX_BUF_SIZEB and
* HSSnC_RX_TRIG_PERIOD values for HSS port hPort. (n=hPort)
*/
#define IX_NPE_A_MSSG_HSS_CHAN_RX_BUF_CFG_WRITE 0x48
/**
* @def IX_NPE_A_MSSG_HSS_CHAN_TX_BLK_CFG_WRITE
*
* @brief HSS Message ID command writes the HSSnC_TX_BLK1_SIZEB,
* HSSnC_TX_BLK1_SIZEW, HSSnC_TX_BLK2_SIZEB, and HSSnC_TX_BLK2_SIZEW values
* for HSS port hPort. (n=hPort)
*/
#define IX_NPE_A_MSSG_HSS_CHAN_TX_BLK_CFG_WRITE 0x49
/**
* @def IX_NPE_A_MSSG_HSS_CHAN_TX_BUF_ADDR_WRITE
* @brief HSS Message ID command writes the HSSnC_TX_BUF_ADDR value for HSS
* port hPort. (n=hPort)
*/
#define IX_NPE_A_MSSG_HSS_CHAN_TX_BUF_ADDR_WRITE 0x4A
/**
* @def IX_NPE_A_MSSG_HSS_CHAN_TX_BUF_SIZE_WRITE
*
* @brief HSS Message ID command writes the HSSnC_TX_BUF_SIZEN value for HSS
* port hPort. (n=hPort)
*/
#define IX_NPE_A_MSSG_HSS_CHAN_TX_BUF_SIZE_WRITE 0x4B
/**
* @def IX_NPE_A_MSSG_HSS_PKT_PIPE_FLOW_ENABLE
*
* @brief HSS Message ID command triggers the NPE to reset internal status and
* enable the HssPacketized operation for the flow specified by pPipe on
* the HSS port specified by hPort.
*/
#define IX_NPE_A_MSSG_HSS_PKT_PIPE_FLOW_ENABLE 0x50
/**
* @def IX_NPE_A_MSSG_HSS_PKT_PIPE_FLOW_DISABLE
* @brief HSS Message ID command triggers the NPE to disable the HssPacketized
* operation for the flow specified by pPipe on the HSS port specified by hPort.
*/
#define IX_NPE_A_MSSG_HSS_PKT_PIPE_FLOW_DISABLE 0x51
/**
* @def IX_NPE_A_MSSG_HSS_PKT_NUM_PIPES_WRITE
* @brief HSS Message ID command writes the HSSnP_NUM_PIPES value for HSS
* port hPort.(n=hPort)
*/
#define IX_NPE_A_MSSG_HSS_PKT_NUM_PIPES_WRITE 0x52
/**
* @def IX_NPE_A_MSSG_HSS_PKT_PIPE_FIFO_SIZEW_WRITE
*
* @brief HSS Message ID command writes the HSSnP_PIPEp_FIFOSIZEW value for
* packet-pipe pPipe on HSS port hPort. (n=hPort, p=pPipe)
*/
#define IX_NPE_A_MSSG_HSS_PKT_PIPE_FIFO_SIZEW_WRITE 0x53
/**
* @def IX_NPE_A_MSSG_HSS_PKT_PIPE_HDLC_CFG_WRITE
*
* @brief HSS Message ID command writes the HSSnP_PIPEp_HDLC_RXCFG and
* HSSnP_PIPEp_HDLC_TXCFG values for packet-pipe pPipe on HSS port hPort.
* (n=hPort, p=pPipe)
*/
#define IX_NPE_A_MSSG_HSS_PKT_PIPE_HDLC_CFG_WRITE 0x54
/**
* @def IX_NPE_A_MSSG_HSS_PKT_PIPE_IDLE_PATTERN_WRITE
*
* @brief HSS Message ID command writes the HSSnP_PIPEp_IDLE_PATTERN value
* for packet-pipe pPipe on HSS port hPort. (n=hPort, p=pPipe)
*/
#define IX_NPE_A_MSSG_HSS_PKT_PIPE_IDLE_PATTERN_WRITE 0x55
/**
* @def IX_NPE_A_MSSG_HSS_PKT_PIPE_RX_SIZE_WRITE
*
* @brief HSS Message ID command writes the HSSnP_PIPEp_RXSIZEB value for
* packet-pipe pPipe on HSS port hPort. (n=hPort, p=pPipe)
*/
#define IX_NPE_A_MSSG_HSS_PKT_PIPE_RX_SIZE_WRITE 0x56
/**
* @def IX_NPE_A_MSSG_HSS_PKT_PIPE_MODE_WRITE
*
* @brief HSS Message ID command writes the HSSnP_PIPEp_MODE value for
* packet-pipe pPipe on HSS port hPort. (n=hPort, p=pPipe)
*/
#define IX_NPE_A_MSSG_HSS_PKT_PIPE_MODE_WRITE 0x57
/* Queue Entry Masks */
/*--------------------------------------------------------------------------
* ATM Descriptor Structure offsets
*--------------------------------------------------------------------------*/
/**
* @def IX_NPE_A_RXDESCRIPTOR_STATUS_OFFSET
*
* @brief ATM Descriptor structure offset for Receive Descriptor Status field
*
* It is used for descriptor error reporting.
*/
#define IX_NPE_A_RXDESCRIPTOR_STATUS_OFFSET 0
/**
* @def IX_NPE_A_RXDESCRIPTOR_VCID_OFFSET
*
* @brief ATM Descriptor structure offset for Receive Descriptor VC ID field
*
* It is used to hold an identifier number for this VC
*/
#define IX_NPE_A_RXDESCRIPTOR_VCID_OFFSET 1
/**
* @def IX_NPE_A_RXDESCRIPTOR_CURRMBUFSIZE_OFFSET
*
* @brief ATM Descriptor structure offset for Receive Descriptor Current Mbuf
* Size field
*
* Number of bytes the current mbuf data buffer can hold
*/
#define IX_NPE_A_RXDESCRIPTOR_CURRMBUFSIZE_OFFSET 2
/**
* @def IX_NPE_A_RXDESCRIPTOR_ATMHEADER_OFFSET
*
* @brief ATM Descriptor structure offset for Receive Descriptor ATM Header
*/
#define IX_NPE_A_RXDESCRIPTOR_ATMHEADER_OFFSET 4
/**
* @def IX_NPE_A_RXDESCRIPTOR_CURRMBUFLEN_OFFSET
*
* @brief ATM Descriptor structure offset for Receive Descriptor Current MBuf length
*
*
* RX - Initialized to zero. The NPE updates this field as each cell is received and
* zeroes it with every new mbuf for chaining. Will not be bigger than currBbufSize.
*/
#define IX_NPE_A_RXDESCRIPTOR_CURRMBUFLEN_OFFSET 12
/**
* @def IX_NPE_A_RXDESCRIPTOR_TIMELIMIT__OFFSET
*
* @brief ATM Descriptor structure offset for Receive Descriptor Time Limit field
*
* Contains the Payload Reassembly Time Limit (used for aal0_xx only)
*/
#define IX_NPE_A_RXDESCRIPTOR_TIMELIMIT_OFFSET 14
/**
* @def IX_NPE_A_RXDESCRIPTOR_PCURRMBUFF_OFFSET
*
* @brief ATM Descriptor structure offset for Receive Descriptor Current MBuf Pointer
*
* The current mbuf pointer of a chain of mbufs.
*/
#define IX_NPE_A_RXDESCRIPTOR_PCURRMBUFF_OFFSET 20
/**
* @def IX_NPE_A_RXDESCRIPTOR_PCURRMBUFDATA_OFFSET
*
* @brief ATM Descriptor structure offset for Receive Descriptor Current MBuf Pointer
*
* Pointer to the next byte to be read or next free location to be written.
*/
#define IX_NPE_A_RXDESCRIPTOR_PCURRMBUFDATA_OFFSET 24
/**
* @def IX_NPE_A_RXDESCRIPTOR_PNEXTMBUF_OFFSET
*
* @brief ATM Descriptor structure offset for Receive Descriptor Next MBuf Pointer
*
* Pointer to the next MBuf in a chain of MBufs.
*/
#define IX_NPE_A_RXDESCRIPTOR_PNEXTMBUF_OFFSET 28
/**
* @def IX_NPE_A_RXDESCRIPTOR_TOTALLENGTH_OFFSET
*
* @brief ATM Descriptor structure offset for Receive Descriptor Total Length
*
* Total number of bytes written to the chain of MBufs by the NPE
*/
#define IX_NPE_A_RXDESCRIPTOR_TOTALLENGTH_OFFSET 32
/**
* @def IX_NPE_A_RXDESCRIPTOR_AAL5CRCRESIDUE_OFFSET
*
* @brief ATM Descriptor structure offset for Receive Descriptor AAL5 CRC Residue
*
* Current CRC value for a PDU
*/
#define IX_NPE_A_RXDESCRIPTOR_AAL5CRCRESIDUE_OFFSET 36
/**
* @def IX_NPE_A_RXDESCRIPTOR_SIZE
*
* @brief ATM Descriptor structure offset for Receive Descriptor Size
*
* The size of the Receive descriptor
*/
#define IX_NPE_A_RXDESCRIPTOR_SIZE 40
/**
* @def IX_NPE_A_TXDESCRIPTOR_PORT_OFFSET
*
* @brief ATM Descriptor structure offset for Transmit Descriptor Port
*
* Port identifier.
*/
#define IX_NPE_A_TXDESCRIPTOR_PORT_OFFSET 0
/**
* @def IX_NPE_A_TXDESCRIPTOR_RSVD_OFFSET
*
* @brief ATM Descriptor structure offset for Transmit Descriptor RSVD
*/
#define IX_NPE_A_TXDESCRIPTOR_RSVD_OFFSET 1
/**
* @def IX_NPE_A_TXDESCRIPTOR_CURRMBUFLEN_OFFSET
*
* @brief ATM Descriptor structure offset for Transmit Descriptor Current MBuf Length
*
* TX - Initialized by the XScale to the number of bytes in the current MBuf data buffer.
* The NPE decrements this field for every transmitted cell. Thus, when the NPE writes a
* descriptor the TxDone queue, this field will equal zero.
*/
#define IX_NPE_A_TXDESCRIPTOR_CURRMBUFLEN_OFFSET 2
/**
* @def IX_NPE_A_TXDESCRIPTOR_ATMHEADER_OFFSET
* @brief ATM Descriptor structure offset for Transmit Descriptor ATM Header
*/
#define IX_NPE_A_TXDESCRIPTOR_ATMHEADER_OFFSET 4
/**
* @def IX_NPE_A_TXDESCRIPTOR_PCURRMBUFF_OFFSET
*
* @brief ATM Descriptor structure offset for Transmit Descriptor Pointer to the current MBuf chain
*/
#define IX_NPE_A_TXDESCRIPTOR_PCURRMBUFF_OFFSET 8
/**
* @def IX_NPE_A_TXDESCRIPTOR_PCURRMBUFDATA_OFFSET
*
* @brief ATM Descriptor structure offset for Transmit Descriptor Pointer to the current MBuf Data
*
* Pointer to the next byte to be read or next free location to be written.
*/
#define IX_NPE_A_TXDESCRIPTOR_PCURRMBUFDATA_OFFSET 12
/**
* @def IX_NPE_A_TXDESCRIPTOR_PNEXTMBUF_OFFSET
*
* @brief ATM Descriptor structure offset for Transmit Descriptor Pointer to the Next MBuf chain
*/
#define IX_NPE_A_TXDESCRIPTOR_PNEXTMBUF_OFFSET 16
/**
* @def IX_NPE_A_TXDESCRIPTOR_TOTALLENGTH_OFFSET
*
* @brief ATM Descriptor structure offset for Transmit Descriptor Total Length
*
* Total number of bytes written to the chain of MBufs by the NPE
*/
#define IX_NPE_A_TXDESCRIPTOR_TOTALLENGTH_OFFSET 20
/**
* @def IX_NPE_A_TXDESCRIPTOR_AAL5CRCRESIDUE_OFFSET
*
* @brief ATM Descriptor structure offset for Transmit Descriptor AAL5 CRC Residue
*
* Current CRC value for a PDU
*/
#define IX_NPE_A_TXDESCRIPTOR_AAL5CRCRESIDUE_OFFSET 24
/**
* @def IX_NPE_A_TXDESCRIPTOR_SIZE
*
* @brief ATM Descriptor structure offset for Transmit Descriptor Size
*/
#define IX_NPE_A_TXDESCRIPTOR_SIZE 28
/**
* @def IX_NPE_A_CHAIN_DESC_COUNT_MAX
*
* @brief Maximum number of chained MBufs that can be chained together
*/
#define IX_NPE_A_CHAIN_DESC_COUNT_MAX 256
/*
* Definition of the ATM cell header
*
* This would most conviently be defined as the bit field shown below.
* Endian portability prevents this, therefore a set of macros
* are defined to access the fields within the cell header assumed to
* be passed as a UINT32.
*
* Changes to field sizes or orders must be reflected in the offset
* definitions above.
*
* typedef struct
* {
* unsigned int gfc:4;
* unsigned int vpi:8;
* unsigned int vci:16;
* unsigned int pti:3;
* unsigned int clp:1;
* } IxNpeA_AtmCellHeader;
*
*/
/** Mask to acess GFC */
#define GFC_MASK 0xf0000000
/** return GFC from ATM cell header */
#define IX_NPE_A_ATMCELLHEADER_GFC_GET( header ) \
(((header) & GFC_MASK) >> 28)
/** set GFC into ATM cell header */
#define IX_NPE_A_ATMCELLHEADER_GFC_SET( header,gfc ) \
do { \
(header) &= ~GFC_MASK; \
(header) |= (((gfc) << 28) & GFC_MASK); \
} while(0)
/** Mask to acess VPI */
#define VPI_MASK 0x0ff00000
/** return VPI from ATM cell header */
#define IX_NPE_A_ATMCELLHEADER_VPI_GET( header ) \
(((header) & VPI_MASK) >> 20)
/** set VPI into ATM cell header */
#define IX_NPE_A_ATMCELLHEADER_VPI_SET( header, vpi ) \
do { \
(header) &= ~VPI_MASK; \
(header) |= (((vpi) << 20) & VPI_MASK); \
} while(0)
/** Mask to acess VCI */
#define VCI_MASK 0x000ffff0
/** return VCI from ATM cell header */
#define IX_NPE_A_ATMCELLHEADER_VCI_GET( header ) \
(((header) & VCI_MASK) >> 4)
/** set VCI into ATM cell header */
#define IX_NPE_A_ATMCELLHEADER_VCI_SET( header, vci ) \
do { \
(header) &= ~VCI_MASK; \
(header) |= (((vci) << 4) & VCI_MASK); \
} while(0)
/** Mask to acess PTI */
#define PTI_MASK 0x0000000e
/** return PTI from ATM cell header */
#define IX_NPE_A_ATMCELLHEADER_PTI_GET( header ) \
(((header) & PTI_MASK) >> 1)
/** set PTI into ATM cell header */
#define IX_NPE_A_ATMCELLHEADER_PTI_SET( header, pti ) \
do { \
(header) &= ~PTI_MASK; \
(header) |= (((pti) << 1) & PTI_MASK); \
} while(0)
/** Mask to acess CLP */
#define CLP_MASK 0x00000001
/** return CLP from ATM cell header */
#define IX_NPE_A_ATMCELLHEADER_CLP_GET( header ) \
((header) & CLP_MASK)
/** set CLP into ATM cell header */
#define IX_NPE_A_ATMCELLHEADER_CLP_SET( header, clp ) \
do { \
(header) &= ~CLP_MASK; \
(header) |= ((clp) & CLP_MASK); \
} while(0)
/*
* Definition of the Rx bitfield
*
* This would most conviently be defined as the bit field shown below.
* Endian portability prevents this, therefore a set of macros
* are defined to access the fields within the rxBitfield assumed to
* be passed as a UINT32.
*
* Changes to field sizes or orders must be reflected in the offset
* definitions above.
*
* Rx bitfield
* struct
* { IX_NPEA_RXBITFIELD(
* unsigned int status:1,
* unsigned int port:7,
* unsigned int vcId:8,
* unsigned int currMbufSize:16);
* } rxBitField;
*
*/
/** Mask to acess the rxBitField status */
#define STATUS_MASK 0x80000000
/** return the rxBitField status */
#define IX_NPE_A_RXBITFIELD_STATUS_GET( rxbitfield ) \
(((rxbitfield) & STATUS_MASK) >> 31)
/** set the rxBitField status */
#define IX_NPE_A_RXBITFIELD_STATUS_SET( rxbitfield, status ) \
do { \
(rxbitfield) &= ~STATUS_MASK; \
(rxbitfield) |= (((status) << 31) & STATUS_MASK); \
} while(0)
/** Mask to acess the rxBitField port */
#define PORT_MASK 0x7f000000
/** return the rxBitField port */
#define IX_NPE_A_RXBITFIELD_PORT_GET( rxbitfield ) \
(((rxbitfield) & PORT_MASK) >> 24)
/** set the rxBitField port */
#define IX_NPE_A_RXBITFIELD_PORT_SET( rxbitfield, port ) \
do { \
(rxbitfield) &= ~PORT_MASK; \
(rxbitfield) |= (((port) << 24) & PORT_MASK); \
} while(0)
/** Mask to acess the rxBitField vcId */
#define VCID_MASK 0x00ff0000
/** return the rxBitField vcId */
#define IX_NPE_A_RXBITFIELD_VCID_GET( rxbitfield ) \
(((rxbitfield) & VCID_MASK) >> 16)
/** set the rxBitField vcId */
#define IX_NPE_A_RXBITFIELD_VCID_SET( rxbitfield, vcid ) \
do { \
(rxbitfield) &= ~VCID_MASK; \
(rxbitfield) |= (((vcid) << 16) & VCID_MASK); \
} while(0)
/** Mask to acess the rxBitField mbuf size */
#define CURRMBUFSIZE_MASK 0x0000ffff
/** return the rxBitField mbuf size */
#define IX_NPE_A_RXBITFIELD_CURRMBUFSIZE_GET( rxbitfield ) \
((rxbitfield) & CURRMBUFSIZE_MASK)
/** set the rxBitField mbuf size */
#define IX_NPE_A_RXBITFIELD_CURRMBUFSIZE_SET( rxbitfield, currmbufsize ) \
do { \
(rxbitfield) &= ~CURRMBUFSIZE_MASK; \
(rxbitfield) |= ((currmbufsize) & CURRMBUFSIZE_MASK); \
} while(0)
/**
* @brief Tx Descriptor definition
*/
typedef struct
{
UINT8 port; /**< Tx Port number */
UINT8 aalType; /**< AAL Type */
UINT16 currMbufLen; /**< mbuf length */
UINT32 atmCellHeader; /**< ATM cell header */
IX_OSAL_MBUF *pCurrMbuf; /**< pointer to mbuf */
unsigned char *pCurrMbufData; /**< Pointer to mbuf->dat */
IX_OSAL_MBUF *pNextMbuf; /**< Pointer to next mbuf */
UINT32 totalLen; /**< Total Length */
UINT32 aal5CrcResidue; /**< AAL5 CRC Residue */
} IxNpeA_TxAtmVc;
/* Changes to field sizes or orders must be reflected in the offset
* definitions above. */
/**
* @brief Rx Descriptor definition
*/
typedef struct
{
UINT32 rxBitField; /**< Recieved bit field */
UINT32 atmCellHeader; /**< ATM Cell Header */
UINT32 rsvdWord0; /**< Reserved field */
UINT16 currMbufLen; /**< Mbuf Length */
UINT8 timeLimit; /**< Payload Reassembly timeLimit (used for aal0_xx only) */
UINT8 rsvdByte0; /**< Reserved field */
UINT32 rsvdWord1; /**< Reserved field */
IX_OSAL_MBUF *pCurrMbuf; /**< Pointer to current mbuf */
unsigned char *pCurrMbufData; /**< Pointer to current mbuf->data */
IX_OSAL_MBUF *pNextMbuf; /**< Pointer to next mbuf */
UINT32 totalLen; /**< Total Length */
UINT32 aal5CrcResidue; /**< AAL5 CRC Residue */
} IxNpeA_RxAtmVc;
/**
* @brief NPE-A AAL Type
*/
typedef enum
{
IX_NPE_A_AAL_TYPE_INVALID = 0, /**< Invalid AAL type */
IX_NPE_A_AAL_TYPE_0_48 = 0x1, /**< AAL0 - 48 byte */
IX_NPE_A_AAL_TYPE_0_52 = 0x2, /**< AAL0 - 52 byte */
IX_NPE_A_AAL_TYPE_5 = 0x5, /**< AAL5 */
IX_NPE_A_AAL_TYPE_OAM = 0xF /**< OAM */
} IxNpeA_AalType;
/**
* @brief NPE-A Payload format 52-bytes & 48-bytes
*/
typedef enum
{
IX_NPE_A_52_BYTE_PAYLOAD = 0, /**< 52 byte payload */
IX_NPE_A_48_BYTE_PAYLOAD /**< 48 byte payload */
} IxNpeA_PayloadFormat;
/**
* @brief HSS Packetized NpePacket Descriptor Structure
*/
typedef struct
{
UINT8 status; /**< Status of the packet passed to the client */
UINT8 errorCount; /**< Number of errors */
UINT8 chainCount; /**< Mbuf chain count e.g. 0 - No mbuf chain */
UINT8 rsvdByte0; /**< Reserved byte to make the descriptor word align */
UINT16 packetLength; /**< Packet Length */
UINT16 rsvdShort0; /**< Reserved short to make the descriptor a word align */
IX_OSAL_MBUF *pRootMbuf; /**< Pointer to Root mbuf */
IX_OSAL_MBUF *pNextMbuf; /**< Pointer to next mbuf */
UINT8 *pMbufData; /**< Pointer to the current mbuf->data */
UINT32 mbufLength; /**< Current mbuf length */
} IxNpeA_NpePacketDescriptor;
#endif
/**
*@}
*/
#endif /* __doxygen_HIDE */

View file

@ -0,0 +1,980 @@
/**
* @file IxNpeDl.h
*
* @date 14 December 2001
* @brief This file contains the public API of the IXP400 NPE Downloader
* component.
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
/**
* @defgroup IxNpeDl IXP400 NPE-Downloader (IxNpeDl) API
*
* @brief The Public API for the IXP400 NPE Downloader
*
* @{
*/
#ifndef IXNPEDL_H
#define IXNPEDL_H
/*
* Put the user defined include files required
*/
#include "IxOsalTypes.h"
#include "IxNpeMicrocode.h"
/*
* #defines for function return types, etc.
*/
/**
* @def IX_NPEDL_PARAM_ERR
*
* @brief NpeDl function return value for a parameter error
*/
#define IX_NPEDL_PARAM_ERR 2
/**
* @def IX_NPEDL_RESOURCE_ERR
*
* @brief NpeDl function return value for a resource error
*/
#define IX_NPEDL_RESOURCE_ERR 3
/**
* @def IX_NPEDL_CRITICAL_NPE_ERR
*
* @brief NpeDl function return value for a Critical NPE error occuring during
download. Assume NPE is left in unstable condition if this value is
returned or NPE is hang / halt.
*/
#define IX_NPEDL_CRITICAL_NPE_ERR 4
/**
* @def IX_NPEDL_CRITICAL_MICROCODE_ERR
*
* @brief NpeDl function return value for a Critical Microcode error
* discovered during download. Assume NPE is left in unstable condition
* if this value is returned.
*/
#define IX_NPEDL_CRITICAL_MICROCODE_ERR 5
/**
* @def IX_NPEDL_DEVICE_ERR
*
* @brief NpeDl function return value when image being downloaded
* is not meant for the device in use
*/
#define IX_NPEDL_DEVICE_ERR 6
/**
* @defgroup NPEImageID IXP400 NPE Image ID Definition
*
* @ingroup IxNpeDl
*
* @brief Definition of NPE Image ID to be passed to ixNpeDlNpeInitAndStart()
* as input of type UINT32 which has the following fields format:
*
* Field [Bit Location] <BR>
* -------------------- <BR>
* Device ID [31 - 28] <BR>
* NPE ID [27 - 24] <BR>
* NPE Functionality ID [23 - 16] <BR>
* Major Release Number [15 - 8] <BR>
* Minor Release Number [7 - 0] <BR>
*
*
* @{
*/
/**
* @def IX_NPEDL_NPEIMAGE_FIELD_MASK
*
* @brief Mask for NPE Image ID's Field
*
* @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
* It will be removed in a future release.
* See @ref ixNpeDlNpeInitAndStart for more information.
*/
#define IX_NPEDL_NPEIMAGE_FIELD_MASK 0xff
/**
* @def IX_NPEDL_NPEIMAGE_NPEID_MASK
*
* @brief Mask for NPE Image NPE ID's Field
*
*/
#define IX_NPEDL_NPEIMAGE_NPEID_MASK 0xf
/**
* @def IX_NPEDL_NPEIMAGE_DEVICEID_MASK
*
* @brief Mask for NPE Image Device ID's Field
*
*/
#define IX_NPEDL_NPEIMAGE_DEVICEID_MASK 0xf
/**
* @def IX_NPEDL_NPEIMAGE_BIT_LOC_NPEID
*
* @brief Location of NPE ID field in term of bit.
*
* @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
* It will be removed in a future release.
* See @ref ixNpeDlNpeInitAndStart for more information.
*/
#define IX_NPEDL_NPEIMAGE_BIT_LOC_NPEID 24
/**
* @def IX_NPEDL_NPEIMAGE_BIT_LOC_FUNCTIONALITYID
*
* @brief Location of Functionality ID field in term of bit.
*
* @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
* It will be removed in a future release.
* See @ref ixNpeDlNpeInitAndStart for more information.
*/
#define IX_NPEDL_NPEIMAGE_BIT_LOC_FUNCTIONALITYID 16
/**
* @def IX_NPEDL_NPEIMAGE_BIT_LOC_MAJOR
*
* @brief Location of Major Release Number field in term of bit.
*
* @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
* It will be removed in a future release.
* See @ref ixNpeDlNpeInitAndStart for more information.
*/
#define IX_NPEDL_NPEIMAGE_BIT_LOC_MAJOR 8
/**
* @def IX_NPEDL_NPEIMAGE_BIT_LOC_MINOR
*
* @brief Location of Minor Release Number field in term of bit.
*
* @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
* It will be removed in a future release.
* See @ref ixNpeDlNpeInitAndStart for more information.
*/
#define IX_NPEDL_NPEIMAGE_BIT_LOC_MINOR 0
/**
* @} addtogroup NPEImageID
*/
/**
* @def ixNpeDlMicrocodeImageOverride(x)
*
* @brief Map old terminology that uses term "image" to new term
* "image library"
*
* @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
* It will be removed in a future release.
* See @ref ixNpeDlNpeInitAndStart for more information.
*/
#define ixNpeDlMicrocodeImageOverride(x) ixNpeDlMicrocodeImageLibraryOverride(x)
/**
* @def IxNpeDlVersionId
*
* @brief Map old terminology that uses term "version" to new term
* "image"
*
* @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
* It will be removed in a future release.
* See @ref ixNpeDlNpeInitAndStart for more information.
*/
#define IxNpeDlVersionId IxNpeDlImageId
/**
* @def ixNpeDlVersionDownload
*
* @brief Map old terminology that uses term "version" to new term
* "image"
*
* @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
* It will be removed in a future release.
* See @ref ixNpeDlNpeInitAndStart for more information.
*/
#define ixNpeDlVersionDownload(x,y) ixNpeDlImageDownload(x,y)
/**
* @def ixNpeDlAvailableVersionsCountGet
*
* @brief Map old terminology that uses term "version" to new term
* "image"
*
* @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
* It will be removed in a future release.
* See @ref ixNpeDlNpeInitAndStart for more information.
*/
#define ixNpeDlAvailableVersionsCountGet(x) ixNpeDlAvailableImagesCountGet(x)
/**
* @def ixNpeDlAvailableVersionsListGet
*
* @brief Map old terminology that uses term "version" to new term
* "image"
*
* @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
* It will be removed in a future release.
* See @ref ixNpeDlNpeInitAndStart for more information.
*/
#define ixNpeDlAvailableVersionsListGet(x,y) ixNpeDlAvailableImagesListGet(x,y)
/**
* @def ixNpeDlLoadedVersionGet
*
* @brief Map old terminology that uses term "version" to new term
* "image"
*
* @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
* It will be removed in a future release.
* See @ref ixNpeDlNpeInitAndStart for more information.
*/
#define ixNpeDlLoadedVersionGet(x,y) ixNpeDlLoadedImageGet(x,y)
/**
* @def clientImage
*
* @brief Map old terminology that uses term "image" to new term
* "image library"
*
* @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
* It will be removed in a future release.
* See @ref ixNpeDlNpeInitAndStart for more information.
*/
#define clientImage clientImageLibrary
/**
* @def versionIdPtr
*
* @brief Map old terminology that uses term "version" to new term
* "image"
*
* @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
* It will be removed in a future release.
* See @ref ixNpeDlNpeInitAndStart for more information.
*/
#define versionIdPtr imageIdPtr
/**
* @def numVersionsPtr
*
* @brief Map old terminology that uses term "version" to new term
* "image"
*
* @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
* It will be removed in a future release.
* See @ref ixNpeDlNpeInitAndStart for more information.
*/
#define numVersionsPtr numImagesPtr
/**
* @def versionIdListPtr
*
* @brief Map old terminology that uses term "version" to new term
* "image"
*
* @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
* It will be removed in a future release.
* See @ref ixNpeDlNpeInitAndStart for more information.
*/
#define versionIdListPtr imageIdListPtr
/**
* @def IxNpeDlBuildId
*
* @brief Map old terminology that uses term "buildId" to new term
* "functionalityId"
*
* @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
* It will be removed in a future release.
* See @ref ixNpeDlNpeInitAndStart for more information.
*/
#define IxNpeDlBuildId IxNpeDlFunctionalityId
/**
* @def buildId
*
* @brief Map old terminology that uses term "buildId" to new term
* "functionalityId"
*
* @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
* It will be removed in a future release.
* See @ref ixNpeDlNpeInitAndStart for more information.
*/
#define buildId functionalityId
/**
* @def IX_NPEDL_MicrocodeImage
*
* @brief Map old terminology that uses term "image" to new term
* "image library"
*
* @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
* It will be removed in a future release.
* See @ref ixNpeDlNpeInitAndStart for more information.
*/
#define IX_NPEDL_MicrocodeImage IX_NPEDL_MicrocodeImageLibrary
/*
* Typedefs
*/
/**
* @typedef IxNpeDlFunctionalityId
* @brief Used to make up Functionality ID field of Image Id
*
* @warning <b>THIS typedef HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
* It will be removed in a future release.
* See @ref ixNpeDlNpeInitAndStart for more information.
*/
typedef UINT8 IxNpeDlFunctionalityId;
/**
* @typedef IxNpeDlMajor
* @brief Used to make up Major Release field of Image Id
*
* @warning <b>THIS typedef HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
* It will be removed in a future release.
* See @ref ixNpeDlNpeInitAndStart for more information.
*/
typedef UINT8 IxNpeDlMajor;
/**
* @typedef IxNpeDlMinor
* @brief Used to make up Minor Revision field of Image Id
*
* @warning <b>THIS typedef HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
* It will be removed in a future release.
* See @ref ixNpeDlNpeInitAndStart for more information.
*/
typedef UINT8 IxNpeDlMinor;
/*
* Enums
*/
/**
* @brief NpeId numbers to identify NPE A, B or C
* @note In this context, for IXP425 Silicon (B0):<br>
* - NPE-A has HDLC, HSS, AAL and UTOPIA Coprocessors.<br>
* - NPE-B has Ethernet Coprocessor.<br>
* - NPE-C has Ethernet, AES, DES and HASH Coprocessors.<br>
* - IXP400 Product Line have different combinations of coprocessors.
*/
typedef enum
{
IX_NPEDL_NPEID_NPEA = 0, /**< Identifies NPE A */
IX_NPEDL_NPEID_NPEB, /**< Identifies NPE B */
IX_NPEDL_NPEID_NPEC, /**< Identifies NPE C */
IX_NPEDL_NPEID_MAX /**< Total Number of NPEs */
} IxNpeDlNpeId;
/*
* Structs
*/
/**
* @brief Image Id to identify each image contained in an image library
*
* @warning <b>THIS struct HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
* It will be removed in a future release.
* See @ref ixNpeDlNpeInitAndStart for more information.
*/
typedef struct
{
IxNpeDlNpeId npeId; /**< NPE ID */
IxNpeDlFunctionalityId functionalityId; /**< Build ID indicates functionality of image */
IxNpeDlMajor major; /**< Major Release Number */
IxNpeDlMinor minor; /**< Minor Revision Number */
} IxNpeDlImageId;
/*
* Prototypes for interface functions
*/
/**
* @ingroup IxNpeDl
*
* @fn PUBLIC IX_STATUS ixNpeDlNpeInitAndStart (UINT32 imageId)
*
* @brief Stop, reset, download microcode (firmware) and finally start NPE.
*
* @param imageId UINT32 [in] - Id of the microcode image to download.
*
* This function locates the image specified by the <i>imageId</i> parameter
* from the default microcode image library which is included internally by
* this component.
* It then stops and resets the NPE, loads the firmware image onto the NPE,
* and then restarts the NPE.
*
* @note A list of valid image IDs is included in this header file.
* See #defines with prefix IX_NPEDL_NPEIMAGE_...
*
* @note This function, along with @ref ixNpeDlCustomImageNpeInitAndStart
* and @ref ixNpeDlLoadedImageFunctionalityGet, supercedes the following
* functions which are deprecated and will be removed completely in a
* future release:
* - @ref ixNpeDlImageDownload
* - @ref ixNpeDlAvailableImagesCountGet
* - @ref ixNpeDlAvailableImagesListGet
* - @ref ixNpeDlLatestImageGet
* - @ref ixNpeDlLoadedImageGet
* - @ref ixNpeDlMicrocodeImageLibraryOverride
* - @ref ixNpeDlNpeExecutionStop
* - @ref ixNpeDlNpeStopAndReset
* - @ref ixNpeDlNpeExecutionStart
*
* @pre
* - The Client is responsible for ensuring mutual access to the NPE.
* @post
* - The NPE Instruction Pipeline will be cleared if State Information
* has been downloaded.
* - If the download fails with a critical error, the NPE may
* be left in an ususable state.
* @return
* - IX_SUCCESS if the download was successful;
* - IX_NPEDL_PARAM_ERR if a parameter error occured
* - IX_NPEDL_CRITICAL_NPE_ERR if a critical NPE error occured during
* download
* - IX_NPEDL_CRITICAL_MICROCODE_ERR if a critical microcode error
* occured during download
* - IX_NPEDL_DEVICE_ERR if the image being loaded is not meant for
* the device currently running.
* - IX_FAIL if NPE is not available or image is failed to be located.
* A warning is issued if the NPE is not present.
*/
PUBLIC IX_STATUS
ixNpeDlNpeInitAndStart (UINT32 npeImageId);
/**
* @ingroup IxNpeDl
*
* @fn PUBLIC IX_STATUS ixNpeDlCustomImageNpeInitAndStart (UINT32 *imageLibrary,
UINT32 imageId)
*
* @brief Stop, reset, download microcode (firmware) and finally start NPE
*
* @param imageId UINT32 [in] - Id of the microcode image to download.
*
* This function locates the image specified by the <i>imageId</i> parameter
* from the specified microcode image library which is pointed to by the
* <i>imageLibrary</i> parameter.
* It then stops and resets the NPE, loads the firmware image onto the NPE,
* and then restarts the NPE.
*
* This is a facility for users who wish to use an image from an external
* library of NPE firmware images. To use a standard image from the
* built-in library, see @ref ixNpeDlNpeInitAndStart instead.
*
* @note A list of valid image IDs is included in this header file.
* See #defines with prefix IX_NPEDL_NPEIMAGE_...
*
* @note This function, along with @ref ixNpeDlNpeInitAndStart
* and @ref ixNpeDlLoadedImageFunctionalityGet, supercedes the following
* functions which are deprecated and will be removed completely in a
* future release:
* - @ref ixNpeDlImageDownload
* - @ref ixNpeDlAvailableImagesCountGet
* - @ref ixNpeDlAvailableImagesListGet
* - @ref ixNpeDlLatestImageGet
* - @ref ixNpeDlLoadedImageGet
* - @ref ixNpeDlMicrocodeImageLibraryOverride
* - @ref ixNpeDlNpeExecutionStop
* - @ref ixNpeDlNpeStopAndReset
* - @ref ixNpeDlNpeExecutionStart
*
* @pre
* - The Client is responsible for ensuring mutual access to the NPE.
* - The image library supplied must be in the correct format for use
* by the NPE Downloader (IxNpeDl) component. Details of the library
* format are contained in the Functional Specification document for
* IxNpeDl.
* @post
* - The NPE Instruction Pipeline will be cleared if State Information
* has been downloaded.
* - If the download fails with a critical error, the NPE may
* be left in an ususable state.
* @return
* - IX_SUCCESS if the download was successful;
* - IX_NPEDL_PARAM_ERR if a parameter error occured
* - IX_NPEDL_CRITICAL_NPE_ERR if a critical NPE error occured during
* download
* - IX_NPEDL_CRITICAL_MICROCODE_ERR if a critical microcode error
* occured during download
* - IX_NPEDL_DEVICE_ERR if the image being loaded is not meant for
* the device currently running.
* - IX_FAIL if NPE is not available or image is failed to be located.
* A warning is issued if the NPE is not present.
*/
PUBLIC IX_STATUS
ixNpeDlCustomImageNpeInitAndStart (UINT32 *imageLibrary,
UINT32 npeImageId);
/**
* @ingroup IxNpeDl
*
* @fn PUBLIC IX_STATUS ixNpeDlLoadedImageFunctionalityGet (IxNpeDlNpeId npeId,
UINT8 *functionalityId)
*
* @brief Gets the functionality of the image last loaded on a particular NPE
*
* @param npeId @ref IxNpeDlNpeId [in] - Id of the target NPE.
* @param functionalityId UINT8* [out] - the functionality ID of the image
* last loaded on the NPE.
*
* This function retrieves the functionality ID of the image most recently
* downloaded successfully to the specified NPE. If the NPE does not contain
* a valid image, this function returns a FAIL status.
*
* @warning This function is not intended for general use, as a knowledge of
* how to interpret the functionality ID is required. As such, this function
* should only be used by other Access Layer components of the IXP400 Software
* Release.
*
* @pre
*
* @post
*
* @return
* - IX_SUCCESS if the operation was successful
* - IX_NPEDL_PARAM_ERR if a parameter error occured
* - IX_FAIL if the NPE does not have a valid image loaded
*/
PUBLIC IX_STATUS
ixNpeDlLoadedImageFunctionalityGet (IxNpeDlNpeId npeId,
UINT8 *functionalityId);
/**
* @ingroup IxNpeDl
*
* @fn IX_STATUS ixNpeDlMicrocodeImageLibraryOverride (UINT32 *clientImageLibrary)
*
* @brief This instructs NPE Downloader to use client-supplied microcode image library.
*
* @param clientImageLibrary UINT32* [in] - Pointer to the client-supplied
* NPE microcode image library
*
* This function sets NPE Downloader to use a client-supplied microcode image library
* instead of the standard image library which is included by the NPE Downloader.
* <b>This function is provided mainly for increased testability and should not
* be used in normal circumstances.</b> When not used, NPE Downloader will use
* a "built-in" image library, local to this component, which should always contain the
* latest microcode for the NPEs.
*
* @warning <b>THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
* It will be removed in a future release.
* See @ref ixNpeDlCustomImageNpeInitAndStart.
*
* @pre
* - <i>clientImageLibrary</i> should point to a microcode image library valid for use
* by the NPE Downloader component.
*
* @post
* - the client-supplied image library will be used for all subsequent operations
* performed by the NPE Downloader
*
* @return
* - IX_SUCCESS if the operation was successful
* - IX_NPEDL_PARAM_ERR if a parameter error occured
* - IX_FAIL if the client-supplied image library did not contain a valid signature
*/
PUBLIC IX_STATUS
ixNpeDlMicrocodeImageLibraryOverride (UINT32 *clientImageLibrary);
/**
* @ingroup IxNpeDl
*
* @fn PUBLIC IX_STATUS ixNpeDlImageDownload (IxNpeDlImageId *imageIdPtr,
BOOL verify)
*
* @brief Stop, reset, download microcode and finally start NPE.
*
* @param imageIdPtr @ref IxNpeDlImageId* [in] - Pointer to Id of the microcode
* image to download.
* @param verify BOOL [in] - ON/OFF option to verify the download. If ON
* (verify == TRUE), the Downloader will read back
* each word written to the NPE registers to
* ensure the download operation was successful.
*
* Using the <i>imageIdPtr</i>, this function locates a particular image of
* microcode in the microcode image library in memory, and downloads the microcode
* to a particular NPE.
*
* @warning <b>THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
* It will be removed in a future release.
* See @ref ixNpeDlNpeInitAndStart and @ref ixNpeDlCustomImageNpeInitAndStart.
*
* @pre
* - The Client is responsible for ensuring mutual access to the NPE.
* - The Client should use ixNpeDlLatestImageGet() to obtain the latest
* version of the image before attempting download.
* @post
* - The NPE Instruction Pipeline will be cleared if State Information
* has been downloaded.
* - If the download fails with a critical error, the NPE may
* be left in an ususable state.
* @return
* - IX_SUCCESS if the download was successful;
* - IX_NPEDL_PARAM_ERR if a parameter error occured
* - IX_NPEDL_CRITICAL_NPE_ERR if a critical NPE error occured during
* download
* - IX_PARAM_CRITICAL_MICROCODE_ERR if a critical microcode error
* occured during download
* - IX_FAIL if NPE is not available or image is failed to be located.
* A warning is issued if the NPE is not present.
*/
PUBLIC IX_STATUS
ixNpeDlImageDownload (IxNpeDlImageId *imageIdPtr,
BOOL verify);
/**
* @ingroup IxNpeDl
*
* @fn PUBLIC IX_STATUS ixNpeDlAvailableImagesCountGet (UINT32 *numImagesPtr)
*
* @brief Get the number of Images available in a microcode image library
*
* @param numImagesPtr UINT32* [out] - A pointer to the number of images in
* the image library.
*
* Gets the number of images available in the microcode image library.
* Then returns this in a variable pointed to by <i>numImagesPtr</i>.
*
* @warning <b>THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
* It will be removed in a future release.
* See @ref ixNpeDlNpeInitAndStart and @ref ixNpeDlCustomImageNpeInitAndStart.
*
* @pre
* - The Client should declare the variable to which numImagesPtr points
*
* @post
*
* @return
* - IX_SUCCESS if the operation was successful
* - IX_NPEDL_PARAM_ERR if a parameter error occured
* - IX_FAIL otherwise
*/
PUBLIC IX_STATUS
ixNpeDlAvailableImagesCountGet (UINT32 *numImagesPtr);
/**
* @ingroup IxNpeDl
*
* @fn PUBLIC IX_STATUS ixNpeDlAvailableImagesListGet (IxNpeDlImageId *imageIdListPtr,
UINT32 *listSizePtr)
*
* @brief Get a list of the images available in a microcode image library
*
* @param imageIdListPtr @ref IxNpeDlImageId* [out] - Array to contain list of
* image Ids (memory
* allocated by Client).
* @param listSizePtr UINT32* [inout] - As an input, this param should point
* to the max number of Ids the
* <i>imageIdListPtr</i> array can
* hold. NpeDl will replace the input
* value of this parameter with the
* number of image Ids actually filled
* into the array before returning.
*
* Finds list of images available in the microcode image library.
* Fills these into the array pointed to by <i>imageIdListPtr</i>
*
* @warning <b>THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
* It will be removed in a future release.
* See @ref ixNpeDlNpeInitAndStart and @ref ixNpeDlCustomImageNpeInitAndStart.
*
* @pre
* - The Client should declare the variable to which numImagesPtr points
* - The Client should create an array (<i>imageIdListPtr</i>) large
* enough to contain all the image Ids in the image library
*
* @post
*
* @return
* - IX_SUCCESS if the operation was successful
* - IX_NPEDL_PARAM_ERR if a parameter error occured
* - IX_FAIL otherwise
*/
PUBLIC IX_STATUS
ixNpeDlAvailableImagesListGet (IxNpeDlImageId *imageIdListPtr,
UINT32 *listSizePtr);
/**
* @ingroup IxNpeDl
*
* @fn PUBLIC IX_STATUS ixNpeDlLoadedImageGet (IxNpeDlNpeId npeId,
IxNpeDlImageId *imageIdPtr)
*
* @brief Gets the Id of the image currently loaded on a particular NPE
*
* @param npeId @ref IxNpeDlNpeId [in] - Id of the target NPE.
* @param imageIdPtr @ref IxNpeDlImageId* [out] - Pointer to the where the
* image id should be stored.
*
* If an image of microcode was previously downloaded successfully to the NPE
* by NPE Downloader, this function returns in <i>imageIdPtr</i> the image
* Id of that image loaded on the NPE.
*
* @pre
* - The Client has allocated memory to the <i>imageIdPtr</i> pointer.
*
* @post
*
* @return
* - IX_SUCCESS if the operation was successful
* - IX_NPEDL_PARAM_ERR if a parameter error occured
* - IX_FAIL if the NPE doesn't currently have a image loaded
*/
PUBLIC IX_STATUS
ixNpeDlLoadedImageGet (IxNpeDlNpeId npeId,
IxNpeDlImageId *imageIdPtr);
/**
* @fn PUBLIC IX_STATUS ixNpeDlLatestImageGet (IxNpeDlNpeId npeId, IxNpeDlFunctionalityId
functionalityId, IxNpeDlImageId *imageIdPtr)
*
* @brief This instructs NPE Downloader to get Id of the latest version for an
* image that is specified by the client.
*
* @param npeId @ref IxNpeDlNpeId [in] - Id of the target NPE.
* @param functionalityId @ref IxNpeDlFunctionalityId [in] - functionality of the image
* @param imageIdPtr @ref IxNpeDlImageId* [out] - Pointer to the where the
* image id should be stored.
*
* This function sets NPE Downloader to return the id of the latest version for
* image. The user will select the image by providing a particular NPE
* (specifying <i>npeId</i>) with particular functionality (specifying
* <i>FunctionalityId</i>). The most recent version available as determined by the
* highest Major and Minor revision numbers is returned in <i>imageIdPtr</i>.
*
* @warning <b>THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
* It will be removed in a future release.
* See @ref ixNpeDlNpeInitAndStart and @ref ixNpeDlCustomImageNpeInitAndStart.
*
* @return
* - IX_SUCCESS if the operation was successful
* - IX_NPEDL_PARAM_ERR if a parameter error occured
* - IX_FAIL otherwise
*/
PUBLIC IX_STATUS
ixNpeDlLatestImageGet (IxNpeDlNpeId npeId,
IxNpeDlFunctionalityId functionalityId,
IxNpeDlImageId *imageIdPtr);
/**
* @ingroup IxNpeDl
*
* @fn PUBLIC IX_STATUS ixNpeDlNpeStopAndReset (IxNpeDlNpeId npeId)
*
* @brief Stops and Resets an NPE
*
* @param npeId @ref IxNpeDlNpeId [in] - Id of the target NPE.
*
* This function performs a soft NPE reset by writing reset values to
* particular NPE registers. Note that this does not reset NPE co-processors.
* This implicitly stops NPE code execution before resetting the NPE.
*
* @note It is no longer necessary to call this function before downloading
* a new image to the NPE. It is left on the API only to allow greater control
* of NPE execution if required. Where appropriate, use @ref ixNpeDlNpeInitAndStart
* or @ref ixNpeDlCustomImageNpeInitAndStart instead.
*
* @warning <b>THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
* It will be removed in a future release.
* See @ref ixNpeDlNpeInitAndStart and @ref ixNpeDlCustomImageNpeInitAndStart.
*
* @pre
* - The Client is responsible for ensuring mutual access to the NPE.
*
* @post
*
* @return
* - IX_SUCCESS if the operation was successful
* - IX_NPEDL_PARAM_ERR if a parameter error occured
* - IX_FAIL otherwise
* - IX_NPEDL_CRITICAL_NPE_ERR failed to reset NPE due to timeout error.
* Timeout error could happen if NPE hang
*/
PUBLIC IX_STATUS
ixNpeDlNpeStopAndReset (IxNpeDlNpeId npeId);
/**
* @ingroup IxNpeDl
*
* @fn PUBLIC IX_STATUS ixNpeDlNpeExecutionStart (IxNpeDlNpeId npeId)
*
* @brief Starts code execution on a NPE
*
* @param npeId @ref IxNpeDlNpeId [in] - Id of the target NPE
*
* Starts execution of code on a particular NPE. A client would typically use
* this after a download to NPE is performed, to start/restart code execution
* on the NPE.
*
* @note It is no longer necessary to call this function after downloading
* a new image to the NPE. It is left on the API only to allow greater control
* of NPE execution if required. Where appropriate, use @ref ixNpeDlNpeInitAndStart
* or @ref ixNpeDlCustomImageNpeInitAndStart instead.
*
* @warning <b>THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
* It will be removed in a future release.
* See @ref ixNpeDlNpeInitAndStart and @ref ixNpeDlCustomImageNpeInitAndStart.
*
* @pre
* - The Client is responsible for ensuring mutual access to the NPE.
* - Note that this function does not set the NPE Next Program Counter
* (NextPC), so it should be set beforehand if required by downloading
* appropriate State Information (using ixNpeDlVersionDownload()).
*
* @post
*
* @return
* - IX_SUCCESS if the operation was successful
* - IX_NPEDL_PARAM_ERR if a parameter error occured
* - IX_FAIL otherwise
*/
PUBLIC IX_STATUS
ixNpeDlNpeExecutionStart (IxNpeDlNpeId npeId);
/**
* @ingroup IxNpeDl
*
* @fn PUBLIC IX_STATUS ixNpeDlNpeExecutionStop (IxNpeDlNpeId npeId)
*
* @brief Stops code execution on a NPE
*
* @param npeId @ref IxNpeDlNpeId [in] - Id of the target NPE
*
* Stops execution of code on a particular NPE. This would typically be used
* by a client before a download to NPE is performed, to stop code execution on
* an NPE, unless ixNpeDlNpeStopAndReset() is used instead. Unlike
* ixNpeDlNpeStopAndReset(), this function only halts the NPE and leaves
* all registers and settings intact. This is useful, for example, between
* stages of a multi-stage download, to stop the NPE prior to downloading the
* next image while leaving the current state of the NPE intact..
*
* @warning <b>THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
* It will be removed in a future release.
* See @ref ixNpeDlNpeInitAndStart and @ref ixNpeDlCustomImageNpeInitAndStart.
*
* @pre
* - The Client is responsible for ensuring mutual access to the NPE.
*
* @post
*
* @return
* - IX_SUCCESS if the operation was successful
* - IX_NPEDL_PARAM_ERR if a parameter error occured
* - IX_FAIL otherwise
*/
PUBLIC IX_STATUS
ixNpeDlNpeExecutionStop (IxNpeDlNpeId npeId);
/**
* @ingroup IxNpeDl
*
* @fn PUBLIC IX_STATUS ixNpeDlUnload (void)
*
* @brief This function will uninitialise the IxNpeDl component.
*
* This function will uninitialise the IxNpeDl component. It should only be
* called once, and only if the IxNpeDl component has already been initialised by
* calling any of the following functions:
* - @ref ixNpeDlNpeInitAndStart
* - @ref ixNpeDlCustomImageNpeInitAndStart
* - @ref ixNpeDlImageDownload (deprecated)
* - @ref ixNpeDlNpeStopAndReset (deprecated)
* - @ref ixNpeDlNpeExecutionStop (deprecated)
* - @ref ixNpeDlNpeExecutionStart (deprecated)
*
* If possible, this function should be called before a soft reboot or unloading
* a kernel module to perform any clean up operations required for IxNpeDl.
*
* The following actions will be performed by this function:
* - Unmapping of any kernel memory mapped by IxNpeDl
*
* @return
* - IX_SUCCESS if the operation was successful
* - IX_FAIL otherwise
*/
PUBLIC IX_STATUS
ixNpeDlUnload (void);
/**
* @ingroup IxNpeDl
*
* @fn PUBLIC void ixNpeDlStatsShow (void)
*
* @brief This function will display run-time statistics from the IxNpeDl
* component
*
* @return none
*/
PUBLIC void
ixNpeDlStatsShow (void);
/**
* @ingroup IxNpeDl
*
* @fn PUBLIC void ixNpeDlStatsReset (void)
*
* @brief This function will reset the statistics of the IxNpeDl component
*
* @return none
*/
PUBLIC void
ixNpeDlStatsReset (void);
#endif /* IXNPEDL_H */
/**
* @} defgroup IxNpeDl
*/

View file

@ -0,0 +1,363 @@
/**
* @file IxNpeDlImageMgr_p.h
*
* @author Intel Corporation
* @date 14 December 2001
* @brief This file contains the private API for the ImageMgr module
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
/**
* @defgroup IxNpeDlImageMgr_p IxNpeDlImageMgr_p
*
* @brief The private API for the IxNpeDl ImageMgr module
*
* @{
*/
#ifndef IXNPEDLIMAGEMGR_P_H
#define IXNPEDLIMAGEMGR_P_H
/*
* Put the user defined include files required.
*/
#include "IxNpeDl.h"
#include "IxOsalTypes.h"
/*
* #defines and macros
*/
/**
* @def IX_NPEDL_IMAGEMGR_SIGNATURE
*
* @brief Signature found as 1st word in a microcode image library
*/
#define IX_NPEDL_IMAGEMGR_SIGNATURE 0xDEADBEEF
/**
* @def IX_NPEDL_IMAGEMGR_END_OF_HEADER
*
* @brief Marks end of header in a microcode image library
*/
#define IX_NPEDL_IMAGEMGR_END_OF_HEADER 0xFFFFFFFF
/**
* @def IX_NPEDL_IMAGEID_NPEID_OFFSET
*
* @brief Offset from LSB of NPE ID field in Image ID
*/
#define IX_NPEDL_IMAGEID_NPEID_OFFSET 24
/**
* @def IX_NPEDL_IMAGEID_DEVICEID_OFFSET
*
* @brief Offset from LSB of Device ID field in Image ID
*/
#define IX_NPEDL_IMAGEID_DEVICEID_OFFSET 28
/**
* @def IX_NPEDL_IMAGEID_FUNCTIONID_OFFSET
*
* @brief Offset from LSB of Functionality ID field in Image ID
*/
#define IX_NPEDL_IMAGEID_FUNCTIONID_OFFSET 16
/**
* @def IX_NPEDL_IMAGEID_MAJOR_OFFSET
*
* @brief Offset from LSB of Major revision field in Image ID
*/
#define IX_NPEDL_IMAGEID_MAJOR_OFFSET 8
/**
* @def IX_NPEDL_IMAGEID_MINOR_OFFSET
*
* @brief Offset from LSB of Minor revision field in Image ID
*/
#define IX_NPEDL_IMAGEID_MINOR_OFFSET 0
/**
* @def IX_NPEDL_NPEID_FROM_IMAGEID_GET
*
* @brief Macro to extract NPE ID field from Image ID
*/
#define IX_NPEDL_NPEID_FROM_IMAGEID_GET(imageId) \
(((imageId) >> IX_NPEDL_IMAGEID_NPEID_OFFSET) & \
IX_NPEDL_NPEIMAGE_NPEID_MASK)
/**
* @def IX_NPEDL_DEVICEID_FROM_IMAGEID_GET
*
* @brief Macro to extract NPE ID field from Image ID
*/
#define IX_NPEDL_DEVICEID_FROM_IMAGEID_GET(imageId) \
(((imageId) >> IX_NPEDL_IMAGEID_DEVICEID_OFFSET) & \
IX_NPEDL_NPEIMAGE_DEVICEID_MASK)
/**
* @def IX_NPEDL_FUNCTIONID_FROM_IMAGEID_GET
*
* @brief Macro to extract Functionality ID field from Image ID
*/
#define IX_NPEDL_FUNCTIONID_FROM_IMAGEID_GET(imageId) \
(((imageId) >> IX_NPEDL_IMAGEID_FUNCTIONID_OFFSET) & \
IX_NPEDL_NPEIMAGE_FIELD_MASK)
/**
* @def IX_NPEDL_MAJOR_FROM_IMAGEID_GET
*
* @brief Macro to extract Major revision field from Image ID
*/
#define IX_NPEDL_MAJOR_FROM_IMAGEID_GET(imageId) \
(((imageId) >> IX_NPEDL_IMAGEID_MAJOR_OFFSET) & \
IX_NPEDL_NPEIMAGE_FIELD_MASK)
/**
* @def IX_NPEDL_MINOR_FROM_IMAGEID_GET
*
* @brief Macro to extract Minor revision field from Image ID
*/
#define IX_NPEDL_MINOR_FROM_IMAGEID_GET(imageId) \
(((imageId) >> IX_NPEDL_IMAGEID_MINOR_OFFSET) & \
IX_NPEDL_NPEIMAGE_FIELD_MASK)
/*
* Prototypes for interface functions
*/
/**
* @fn IX_STATUS ixNpeDlImageMgrMicrocodeImageLibraryOverride (UINT32 *clientImageLibrary)
*
* @brief This instructs NPE Downloader to use client-supplied microcode image library.
*
* This function sets NPE Downloader to use a client-supplied microcode image library
* instead of the standard image library which is included by the NPE Downloader.
*
* @note THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.
* It will be removed in a future release.
* See API header file IxNpeDl.h for more information.
*
* @pre
* - <i>clientImageLibrary</i> should point to a microcode image library valid for use
* by the NPE Downloader component.
*
* @post
* - the client-supplied image uibrary will be used for all subsequent operations
* performed by the NPE Downloader
*
* @return
* - IX_SUCCESS if the operation was successful
* - IX_FAIL if the client-supplied image library did not contain a valid signature
*/
IX_STATUS
ixNpeDlImageMgrMicrocodeImageLibraryOverride (UINT32 *clientImageLibrary);
/**
* @fn IX_STATUS ixNpeDlImageMgrImageListExtract (IxNpeDlImageId *imageListPtr,
UINT32 *numImages)
*
* @brief Extracts a list of images available in the NPE microcode image library.
*
* @param IxNpeDlImageId* [out] imageListPtr - pointer to array to contain
* a list of images. If NULL,
* only the number of images
* is returned (in
* <i>numImages</i>)
* @param UINT32* [inout] numImages - As input, it points to a variable
* containing the number of images which
* can be stored in the
* <i>imageListPtr</i> array. Its value
* is ignored as input if
* <i>imageListPtr</i> is NULL. As an
* output, it will contain number of
* images in the image library.
*
* This function reads the header of the microcode image library and extracts a list of the
* images available in the image library. It can also be used to find the number of
* images in the image library.
*
* @note THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.
* It will be removed in a future release.
* See API header file IxNpeDl.h for more information.
*
* @pre
* - if <i>imageListPtr</i> != NULL, <i>numImages</i> should reflect the
* number of image Id elements the <i>imageListPtr</i> can contain.
*
* @post
* - <i>numImages</i> will reflect the number of image Id's found in the
* microcode image library.
*
* @return
* - IX_SUCCESS if the operation was successful
* - IX_FAIL otherwise
*/
IX_STATUS
ixNpeDlImageMgrImageListExtract (IxNpeDlImageId *imageListPtr,
UINT32 *numImages);
/**
* @fn IX_STATUS ixNpeDlImageMgrImageLocate (IxNpeDlImageId *imageId,
UINT32 **imagePtr,
UINT32 *imageSize)
*
* @brief Finds a image block in the NPE microcode image library.
*
* @param IxNpeDlImageId* [in] imageId - the id of the image to locate
* @param UINT32** [out] imagePtr - pointer to the image in memory
* @param UINT32* [out] imageSize - size (in 32-bit words) of image
*
* This function examines the header of the microcode image library for the location
* and size of the specified image.
*
* @note THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.
* It will be removed in a future release.
* See API header file IxNpeDl.h for more information.
*
* @pre
*
* @post
*
* @return
* - IX_SUCCESS if the operation was successful
* - IX_FAIL otherwise
*/
IX_STATUS
ixNpeDlImageMgrImageLocate (IxNpeDlImageId *imageId,
UINT32 **imagePtr,
UINT32 *imageSize);
/**
* @fn IX_STATUS ixNpeDlImageMgrLatestImageExtract (IxNpeDlImageId *imageId)
*
* @brief Finds the most recent version of an image in the NPE image library.
*
* @param IxNpeDlImageId* [inout] imageId - the id of the image
*
* This function determines the most recent version of a specified image by its
* higest major release and minor revision numbers
*
* @note THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.
* It will be removed in a future release.
* See API header file IxNpeDl.h for more information.
*
* @pre
*
* @post
*
* @return
* - IX_SUCCESS if the operation was successful
* - IX_FAIL otherwise
*/
IX_STATUS
ixNpeDlImageMgrLatestImageExtract (IxNpeDlImageId *imageId);
/**
* @fn void ixNpeDlImageMgrStatsShow (void)
*
* @brief This function will display the statistics of the IxNpeDl ImageMgr
* module
*
* @return none
*/
void
ixNpeDlImageMgrStatsShow (void);
/**
* @fn void ixNpeDlImageMgrStatsReset (void)
*
* @brief This function will reset the statistics of the IxNpeDl ImageMgr
* module
*
* @return none
*/
void
ixNpeDlImageMgrStatsReset (void);
/**
* @fn IX_STATUS ixNpeDlImageMgrImageGet (UINT32 *imageLibrary,
UINT32 imageId,
UINT32 **imagePtr,
UINT32 *imageSize)
*
* @brief Finds a image block in the NPE microcode image library.
*
* @param UINT32* [in] imageLibrary - the image library to use
* @param UINT32 [in] imageId - the id of the image to locate
* @param UINT32** [out] imagePtr - pointer to the image in memory
* @param UINT32* [out] imageSize - size (in 32-bit words) of image
*
* This function examines the header of the specified microcode image library
* for the location and size of the specified image. It returns a pointer to
* the image in the <i>imagePtr</i> parameter.
* If no image library is specified (imageLibrary == NULL), then the default
* built-in image library will be used.
*
* @pre
*
* @post
*
* @return
* - IX_SUCCESS if the operation was successful
* - IX_FAIL otherwise
*/
IX_STATUS
ixNpeDlImageMgrImageFind (UINT32 *imageLibrary,
UINT32 imageId,
UINT32 **imagePtr,
UINT32 *imageSize);
#endif /* IXNPEDLIMAGEMGR_P_H */
/**
* @} defgroup IxNpeDlImageMgr_p
*/

View file

@ -0,0 +1,414 @@
/**
* @file IxNpeDlMacros_p.h
*
* @author Intel Corporation
* @date 21 January 2002
*
* @brief This file contains the macros for the IxNpeDl component.
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
/**
* @defgroup IxNpeDlMacros_p IxNpeDlMacros_p
*
* @brief Macros for the IxNpeDl component.
*
* @{
*/
#ifndef IXNPEDLMACROS_P_H
#define IXNPEDLMACROS_P_H
/*
* Put the user defined include files required.
*/
#if (CPU != XSCALE)
/* To support IxNpeDl unit tests... */
#include <stdio.h>
#include "test/IxNpeDlTestReg.h"
#else
#include "IxOsal.h"
#endif
/*
* Typedefs
*/
/**
* @typedef IxNpeDlTraceTypes
* @brief Enumeration defining IxNpeDl trace levels
*/
typedef enum
{
IX_NPEDL_TRACE_OFF, /**< no trace */
IX_NPEDL_DEBUG, /**< debug */
IX_NPEDL_FN_ENTRY_EXIT /**< function entry/exit */
} IxNpeDlTraceTypes;
/*
* #defines and macros.
*/
/* Implementation of the following macros for use with IxNpeDl unit test code */
#if (CPU != XSCALE)
/**
* @def IX_NPEDL_TRACE_LEVEL
*
* @brief IxNpeDl debug trace level
*/
#define IX_NPEDL_TRACE_LEVEL IX_NPEDL_FN_ENTRY_EXIT
/**
* @def IX_NPEDL_ERROR_REPORT
*
* @brief Mechanism for reporting IxNpeDl software errors
*
* @param char* [in] STR - Error string to report
*
* This macro simply prints the error string passed.
* Intended for use with IxNpeDl unit test code.
*
* @return none
*/
#define IX_NPEDL_ERROR_REPORT(STR) printf ("IxNpeDl ERROR: %s\n", (STR));
/**
* @def IX_NPEDL_WARNING_REPORT
*
* @brief Mechanism for reporting IxNpeDl software errors
*
* @param char* [in] STR - Error string to report
*
* This macro simply prints the error string passed.
* Intended for use with IxNpeDl unit test code.
*
* @return none
*/
#define IX_NPEDL_WARNING_REPORT(STR) printf ("IxNpeDl WARNING: %s\n", (STR));
/**
* @def IX_NPEDL_TRACE0
*
* @brief Mechanism for tracing debug for the IxNpeDl component, for no arguments
*
* @param unsigned [in] LEVEL - one of IxNpeDlTraceTypes enumerated values
* @param char* [in] STR - Trace string
*
* This macro simply prints the trace string passed, if the level is supported.
* Intended for use with IxNpeDl unit test code.
*
* @return none
*/
#define IX_NPEDL_TRACE0(LEVEL, STR) \
{ \
if (LEVEL <= IX_NPEDL_TRACE_LEVEL) \
{ \
printf ("IxNpeDl TRACE: "); \
printf ((STR)); \
printf ("\n"); \
} \
}
/**
* @def IX_NPEDL_TRACE1
*
* @brief Mechanism for tracing debug for the IxNpeDl component, with 1 argument
*
* @param unsigned [in] LEVEL - one of IxNpeDlTraceTypes enumerated values
* @param char* [in] STR - Trace string
* @param argType [in] ARG1 - Argument to trace
*
* This macro simply prints the trace string passed, if the level is supported.
* Intended for use with IxNpeDl unit test code.
*
* @return none
*/
#define IX_NPEDL_TRACE1(LEVEL, STR, ARG1) \
{ \
if (LEVEL <= IX_NPEDL_TRACE_LEVEL) \
{ \
printf ("IxNpeDl TRACE: "); \
printf (STR, ARG1); \
printf ("\n"); \
} \
}
/**
* @def IX_NPEDL_TRACE2
*
* @brief Mechanism for tracing debug for the IxNpeDl component, with 2 arguments
*
* @param unsigned [in] LEVEL - one of IxNpeDlTraceTypes enumerated values
* @param char* [in] STR - Trace string
* @param argType [in] ARG1 - Argument to trace
* @param argType [in] ARG2 - Argument to trace
*
* This macro simply prints the trace string passed, if the level is supported.
* Intended for use with IxNpeDl unit test code.
*
* @return none
*/
#define IX_NPEDL_TRACE2(LEVEL, STR, ARG1, ARG2) \
{ \
if (LEVEL <= IX_NPEDL_TRACE_LEVEL) \
{ \
printf ("IxNpeDl TRACE: "); \
printf (STR, ARG1, ARG2); \
printf ("\n"); \
} \
}
/**
* @def IX_NPEDL_REG_WRITE
*
* @brief Mechanism for writing to a memory-mapped register
*
* @param UINT32 [in] base - Base memory address for this NPE's registers
* @param UINT32 [in] offset - Offset from base memory address
* @param UINT32 [in] value - Value to write to register
*
* This macro calls a function from Unit Test code to write a register. This
* allows extra flexibility for unit testing of the IxNpeDl component.
*
* @return none
*/
#define IX_NPEDL_REG_WRITE(base, offset, value) \
{ \
ixNpeDlTestRegWrite (base, offset, value); \
}
/**
* @def IX_NPEDL_REG_READ
*
* @brief Mechanism for reading from a memory-mapped register
*
* @param UINT32 [in] base - Base memory address for this NPE's registers
* @param UINT32 [in] offset - Offset from base memory address
* @param UINT32 *[out] value - Value read from register
*
* This macro calls a function from Unit Test code to read a register. This
* allows extra flexibility for unit testing of the IxNpeDl component.
*
* @return none
*/
#define IX_NPEDL_REG_READ(base, offset, value) \
{ \
ixNpeDlTestRegRead (base, offset, value); \
}
/* Implementation of the following macros when integrated with IxOsal */
#else /* #if (CPU != XSCALE) */
/**
* @def IX_NPEDL_TRACE_LEVEL
*
* @brief IxNpeDl debug trace level
*/
#define IX_NPEDL_TRACE_LEVEL IX_NPEDL_DEBUG
/**
* @def IX_NPEDL_ERROR_REPORT
*
* @brief Mechanism for reporting IxNpeDl software errors
*
* @param char* [in] STR - Error string to report
*
* This macro is used to report IxNpeDl software errors.
*
* @return none
*/
#define IX_NPEDL_ERROR_REPORT(STR) \
ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, STR, 0, 0, 0, 0, 0, 0);
/**
* @def IX_NPEDL_WARNING_REPORT
*
* @brief Mechanism for reporting IxNpeDl software warnings
*
* @param char* [in] STR - Warning string to report
*
* This macro is used to report IxNpeDl software warnings.
*
* @return none
*/
#define IX_NPEDL_WARNING_REPORT(STR) \
ixOsalLog (IX_OSAL_LOG_LVL_WARNING, IX_OSAL_LOG_DEV_STDOUT, STR, 0, 0, 0, 0, 0, 0);
/**
* @def IX_NPEDL_TRACE0
*
* @brief Mechanism for tracing debug for the IxNpeDl component, for no arguments
*
* @param unsigned [in] LEVEL - one of IxNpeDlTraceTypes enumerated values
* @param char* [in] STR - Trace string
*
* This macro simply prints the trace string passed, if the level is supported.
*
* @return none
*/
#define IX_NPEDL_TRACE0(LEVEL, STR) \
{ \
if (LEVEL <= IX_NPEDL_TRACE_LEVEL) \
{ \
if (LEVEL == IX_NPEDL_FN_ENTRY_EXIT) \
{ \
ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3, IX_OSAL_LOG_DEV_STDOUT, STR, 0, 0, 0, 0, 0, 0); \
} \
else if (LEVEL == IX_NPEDL_DEBUG) \
{ \
ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, STR, 0, 0, 0, 0, 0, 0); \
} \
} \
}
/**
* @def IX_NPEDL_TRACE1
*
* @brief Mechanism for tracing debug for the IxNpeDl component, with 1 argument
*
* @param unsigned [in] LEVEL - one of IxNpeDlTraceTypes enumerated values
* @param char* [in] STR - Trace string
* @param argType [in] ARG1 - Argument to trace
*
* This macro simply prints the trace string passed, if the level is supported.
*
* @return none
*/
#define IX_NPEDL_TRACE1(LEVEL, STR, ARG1) \
{ \
if (LEVEL <= IX_NPEDL_TRACE_LEVEL) \
{ \
if (LEVEL == IX_NPEDL_FN_ENTRY_EXIT) \
{ \
ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3, IX_OSAL_LOG_DEV_STDOUT, STR, ARG1, 0, 0, 0, 0, 0); \
} \
else if (LEVEL == IX_NPEDL_DEBUG) \
{ \
ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, STR, ARG1, 0, 0, 0, 0, 0); \
} \
} \
}
/**
* @def IX_NPEDL_TRACE2
*
* @brief Mechanism for tracing debug for the IxNpeDl component, with 2 arguments
*
* @param unsigned [in] LEVEL - one of IxNpeDlTraceTypes enumerated values
* @param char* [in] STR - Trace string
* @param argType [in] ARG1 - Argument to trace
* @param argType [in] ARG2 - Argument to trace
*
* This macro simply prints the trace string passed, if the level is supported.
*
* @return none
*/
#define IX_NPEDL_TRACE2(LEVEL, STR, ARG1, ARG2) \
{ \
if (LEVEL <= IX_NPEDL_TRACE_LEVEL) \
{ \
if (LEVEL == IX_NPEDL_FN_ENTRY_EXIT) \
{ \
ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3, IX_OSAL_LOG_DEV_STDOUT, STR, ARG1, ARG2, 0, 0, 0, 0); \
} \
else if (LEVEL == IX_NPEDL_DEBUG) \
{ \
ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, STR, ARG1, ARG2, 0, 0, 0, 0); \
} \
} \
}
/**
* @def IX_NPEDL_REG_WRITE
*
* @brief Mechanism for writing to a memory-mapped register
*
* @param UINT32 [in] base - Base memory address for this NPE's registers
* @param UINT32 [in] offset - Offset from base memory address
* @param UINT32 [in] value - Value to write to register
*
* This macro forms the address of the register from base address + offset, and
* dereferences that address to write the contents of the register.
*
* @return none
*/
#define IX_NPEDL_REG_WRITE(base, offset, value) \
IX_OSAL_WRITE_LONG(((base) + (offset)), (value))
/**
* @def IX_NPEDL_REG_READ
*
* @brief Mechanism for reading from a memory-mapped register
*
* @param UINT32 [in] base - Base memory address for this NPE's registers
* @param UINT32 [in] offset - Offset from base memory address
* @param UINT32 *[out] value - Value read from register
*
* This macro forms the address of the register from base address + offset, and
* dereferences that address to read the register contents.
*
* @return none
*/
#define IX_NPEDL_REG_READ(base, offset, value) \
*(value) = IX_OSAL_READ_LONG(((base) + (offset)))
#endif /* #if (CPU != XSCALE) */
#endif /* IXNPEDLMACROS_P_H */
/**
* @} defgroup IxNpeDlMacros_p
*/

View file

@ -0,0 +1,893 @@
/**
* @file IxNpeDlNpeMgrEcRegisters_p.h
*
* @author Intel Corporation
* @date 14 December 2001
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
#ifndef IXNPEDLNPEMGRECREGISTERS_P_H
#define IXNPEDLNPEMGRECREGISTERS_P_H
#include "IxOsal.h"
/*
* Base Memory Addresses for accessing NPE registers
*/
#define IX_NPEDL_NPE_BASE (IX_OSAL_IXP400_PERIPHERAL_PHYS_BASE)
#define IX_NPEDL_NPEA_OFFSET (0x6000) /**< NPE-A register base offset */
#define IX_NPEDL_NPEB_OFFSET (0x7000) /**< NPE-B register base offset */
#define IX_NPEDL_NPEC_OFFSET (0x8000) /**< NPE-C register base offset */
/**
* @def IX_NPEDL_NPEBASEADDRESS_NPEA
* @brief Base Memory Address of NPE-A Configuration Bus registers
*/
#define IX_NPEDL_NPEBASEADDRESS_NPEA (IX_NPEDL_NPE_BASE + IX_NPEDL_NPEA_OFFSET)
/**
* @def IX_NPEDL_NPEBASEADDRESS_NPEB
* @brief Base Memory Address of NPE-B Configuration Bus registers
*/
#define IX_NPEDL_NPEBASEADDRESS_NPEB (IX_NPEDL_NPE_BASE + IX_NPEDL_NPEB_OFFSET)
/**
* @def IX_NPEDL_NPEBASEADDRESS_NPEC
* @brief Base Memory Address of NPE-C Configuration Bus registers
*/
#define IX_NPEDL_NPEBASEADDRESS_NPEC (IX_NPEDL_NPE_BASE + IX_NPEDL_NPEC_OFFSET)
/*
* Instruction Memory Size (in words) for each NPE
*/
/**
* @def IX_NPEDL_INS_MEMSIZE_WORDS_NPEA
* @brief Size (in words) of NPE-A Instruction Memory
*/
#define IX_NPEDL_INS_MEMSIZE_WORDS_NPEA 4096
/**
* @def IX_NPEDL_INS_MEMSIZE_WORDS_NPEB
* @brief Size (in words) of NPE-B Instruction Memory
*/
#define IX_NPEDL_INS_MEMSIZE_WORDS_NPEB 2048
/**
* @def IX_NPEDL_INS_MEMSIZE_WORDS_NPEC
* @brief Size (in words) of NPE-B Instruction Memory
*/
#define IX_NPEDL_INS_MEMSIZE_WORDS_NPEC 2048
/*
* Data Memory Size (in words) for each NPE
*/
/**
* @def IX_NPEDL_DATA_MEMSIZE_WORDS_NPEA
* @brief Size (in words) of NPE-A Data Memory
*/
#define IX_NPEDL_DATA_MEMSIZE_WORDS_NPEA 2048
/**
* @def IX_NPEDL_DATA_MEMSIZE_WORDS_NPEB
* @brief Size (in words) of NPE-B Data Memory
*/
#define IX_NPEDL_DATA_MEMSIZE_WORDS_NPEB 2048
/**
* @def IX_NPEDL_DATA_MEMSIZE_WORDS_NPEC
* @brief Size (in words) of NPE-C Data Memory
*/
#define IX_NPEDL_DATA_MEMSIZE_WORDS_NPEC 2048
/*
* Configuration Bus Register offsets (in bytes) from NPE Base Address
*/
/**
* @def IX_NPEDL_REG_OFFSET_EXAD
* @brief Offset (in bytes) of EXAD (Execution Address) register from NPE Base
* Address
*/
#define IX_NPEDL_REG_OFFSET_EXAD 0x00000000
/**
* @def IX_NPEDL_REG_OFFSET_EXDATA
* @brief Offset (in bytes) of EXDATA (Execution Data) register from NPE Base
* Address
*/
#define IX_NPEDL_REG_OFFSET_EXDATA 0x00000004
/**
* @def IX_NPEDL_REG_OFFSET_EXCTL
* @brief Offset (in bytes) of EXCTL (Execution Control) register from NPE Base
* Address
*/
#define IX_NPEDL_REG_OFFSET_EXCTL 0x00000008
/**
* @def IX_NPEDL_REG_OFFSET_EXCT
* @brief Offset (in bytes) of EXCT (Execution Count) register from NPE Base
* Address
*/
#define IX_NPEDL_REG_OFFSET_EXCT 0x0000000C
/**
* @def IX_NPEDL_REG_OFFSET_AP0
* @brief Offset (in bytes) of AP0 (Action Point 0) register from NPE Base
* Address
*/
#define IX_NPEDL_REG_OFFSET_AP0 0x00000010
/**
* @def IX_NPEDL_REG_OFFSET_AP1
* @brief Offset (in bytes) of AP1 (Action Point 1) register from NPE Base
* Address
*/
#define IX_NPEDL_REG_OFFSET_AP1 0x00000014
/**
* @def IX_NPEDL_REG_OFFSET_AP2
* @brief Offset (in bytes) of AP2 (Action Point 2) register from NPE Base
* Address
*/
#define IX_NPEDL_REG_OFFSET_AP2 0x00000018
/**
* @def IX_NPEDL_REG_OFFSET_AP3
* @brief Offset (in bytes) of AP3 (Action Point 3) register from NPE Base
* Address
*/
#define IX_NPEDL_REG_OFFSET_AP3 0x0000001C
/**
* @def IX_NPEDL_REG_OFFSET_WFIFO
* @brief Offset (in bytes) of WFIFO (Watchpoint FIFO) register from NPE Base
* Address
*/
#define IX_NPEDL_REG_OFFSET_WFIFO 0x00000020
/**
* @def IX_NPEDL_REG_OFFSET_WC
* @brief Offset (in bytes) of WC (Watch Count) register from NPE Base
* Address
*/
#define IX_NPEDL_REG_OFFSET_WC 0x00000024
/**
* @def IX_NPEDL_REG_OFFSET_PROFCT
* @brief Offset (in bytes) of PROFCT (Profile Count) register from NPE Base
* Address
*/
#define IX_NPEDL_REG_OFFSET_PROFCT 0x00000028
/**
* @def IX_NPEDL_REG_OFFSET_STAT
* @brief Offset (in bytes) of STAT (Messaging Status) register from NPE Base
* Address
*/
#define IX_NPEDL_REG_OFFSET_STAT 0x0000002C
/**
* @def IX_NPEDL_REG_OFFSET_CTL
* @brief Offset (in bytes) of CTL (Messaging Control) register from NPE Base
* Address
*/
#define IX_NPEDL_REG_OFFSET_CTL 0x00000030
/**
* @def IX_NPEDL_REG_OFFSET_MBST
* @brief Offset (in bytes) of MBST (Mailbox Status) register from NPE Base
* Address
*/
#define IX_NPEDL_REG_OFFSET_MBST 0x00000034
/**
* @def IX_NPEDL_REG_OFFSET_FIFO
* @brief Offset (in bytes) of FIFO (messaging in/out FIFO) register from NPE
* Base Address
*/
#define IX_NPEDL_REG_OFFSET_FIFO 0x00000038
/*
* Non-zero reset values for the Configuration Bus registers
*/
/**
* @def IX_NPEDL_REG_RESET_FIFO
* @brief Reset value for Mailbox (MBST) register
* NOTE that if used, it should be complemented with an NPE intruction
* to clear the Mailbox at the NPE side as well
*/
#define IX_NPEDL_REG_RESET_MBST 0x0000F0F0
/*
* Bit-masks used to read/write particular bits in Configuration Bus registers
*/
/**
* @def IX_NPEDL_MASK_WFIFO_VALID
* @brief Masks the VALID bit in the WFIFO register
*/
#define IX_NPEDL_MASK_WFIFO_VALID 0x80000000
/**
* @def IX_NPEDL_MASK_STAT_OFNE
* @brief Masks the OFNE bit in the STAT register
*/
#define IX_NPEDL_MASK_STAT_OFNE 0x00010000
/**
* @def IX_NPEDL_MASK_STAT_IFNE
* @brief Masks the IFNE bit in the STAT register
*/
#define IX_NPEDL_MASK_STAT_IFNE 0x00080000
/*
* EXCTL (Execution Control) Register commands
*/
/**
* @def IX_NPEDL_EXCTL_CMD_NPE_STEP
* @brief EXCTL Command to Step execution of an NPE Instruction
*/
#define IX_NPEDL_EXCTL_CMD_NPE_STEP 0x01
/**
* @def IX_NPEDL_EXCTL_CMD_NPE_START
* @brief EXCTL Command to Start NPE execution
*/
#define IX_NPEDL_EXCTL_CMD_NPE_START 0x02
/**
* @def IX_NPEDL_EXCTL_CMD_NPE_STOP
* @brief EXCTL Command to Stop NPE execution
*/
#define IX_NPEDL_EXCTL_CMD_NPE_STOP 0x03
/**
* @def IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE
* @brief EXCTL Command to Clear NPE instruction pipeline
*/
#define IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE 0x04
/**
* @def IX_NPEDL_EXCTL_CMD_RD_INS_MEM
* @brief EXCTL Command to read NPE instruction memory at address in EXAD
* register and return value in EXDATA register
*/
#define IX_NPEDL_EXCTL_CMD_RD_INS_MEM 0x10
/**
* @def IX_NPEDL_EXCTL_CMD_WR_INS_MEM
* @brief EXCTL Command to write NPE instruction memory at address in EXAD
* register with data in EXDATA register
*/
#define IX_NPEDL_EXCTL_CMD_WR_INS_MEM 0x11
/**
* @def IX_NPEDL_EXCTL_CMD_RD_DATA_MEM
* @brief EXCTL Command to read NPE data memory at address in EXAD
* register and return value in EXDATA register
*/
#define IX_NPEDL_EXCTL_CMD_RD_DATA_MEM 0x12
/**
* @def IX_NPEDL_EXCTL_CMD_WR_DATA_MEM
* @brief EXCTL Command to write NPE data memory at address in EXAD
* register with data in EXDATA register
*/
#define IX_NPEDL_EXCTL_CMD_WR_DATA_MEM 0x13
/**
* @def IX_NPEDL_EXCTL_CMD_RD_ECS_REG
* @brief EXCTL Command to read Execution Access register at address in EXAD
* register and return value in EXDATA register
*/
#define IX_NPEDL_EXCTL_CMD_RD_ECS_REG 0x14
/**
* @def IX_NPEDL_EXCTL_CMD_WR_ECS_REG
* @brief EXCTL Command to write Execution Access register at address in EXAD
* register with data in EXDATA register
*/
#define IX_NPEDL_EXCTL_CMD_WR_ECS_REG 0x15
/**
* @def IX_NPEDL_EXCTL_CMD_CLR_PROFILE_CNT
* @brief EXCTL Command to clear Profile Count register
*/
#define IX_NPEDL_EXCTL_CMD_CLR_PROFILE_CNT 0x0C
/*
* EXCTL (Execution Control) Register status bit masks
*/
/**
* @def IX_NPEDL_EXCTL_STATUS_RUN
* @brief Masks the RUN status bit in the EXCTL register
*/
#define IX_NPEDL_EXCTL_STATUS_RUN 0x80000000
/**
* @def IX_NPEDL_EXCTL_STATUS_STOP
* @brief Masks the STOP status bit in the EXCTL register
*/
#define IX_NPEDL_EXCTL_STATUS_STOP 0x40000000
/**
* @def IX_NPEDL_EXCTL_STATUS_CLEAR
* @brief Masks the CLEAR status bit in the EXCTL register
*/
#define IX_NPEDL_EXCTL_STATUS_CLEAR 0x20000000
/**
* @def IX_NPEDL_EXCTL_STATUS_ECS_K
* @brief Masks the K (pipeline Klean) status bit in the EXCTL register
*/
#define IX_NPEDL_EXCTL_STATUS_ECS_K 0x00800000
/*
* Executing Context Stack (ECS) level registers
*/
/**
* @def IX_NPEDL_ECS_BG_CTXT_REG_0
* @brief Execution Access register address for register 0 at Backgound
* Executing Context Stack level
*/
#define IX_NPEDL_ECS_BG_CTXT_REG_0 0x00
/**
* @def IX_NPEDL_ECS_BG_CTXT_REG_1
* @brief Execution Access register address for register 1 at Backgound
* Executing Context Stack level
*/
#define IX_NPEDL_ECS_BG_CTXT_REG_1 0x01
/**
* @def IX_NPEDL_ECS_BG_CTXT_REG_2
* @brief Execution Access register address for register 2 at Backgound
* Executing Context Stack level
*/
#define IX_NPEDL_ECS_BG_CTXT_REG_2 0x02
/**
* @def IX_NPEDL_ECS_PRI_1_CTXT_REG_0
* @brief Execution Access register address for register 0 at Priority 1
* Executing Context Stack level
*/
#define IX_NPEDL_ECS_PRI_1_CTXT_REG_0 0x04
/**
* @def IX_NPEDL_ECS_PRI_1_CTXT_REG_1
* @brief Execution Access register address for register 1 at Priority 1
* Executing Context Stack level
*/
#define IX_NPEDL_ECS_PRI_1_CTXT_REG_1 0x05
/**
* @def IX_NPEDL_ECS_PRI_1_CTXT_REG_2
* @brief Execution Access register address for register 2 at Priority 1
* Executing Context Stack level
*/
#define IX_NPEDL_ECS_PRI_1_CTXT_REG_2 0x06
/**
* @def IX_NPEDL_ECS_PRI_2_CTXT_REG_0
* @brief Execution Access register address for register 0 at Priority 2
* Executing Context Stack level
*/
#define IX_NPEDL_ECS_PRI_2_CTXT_REG_0 0x08
/**
* @def IX_NPEDL_ECS_PRI_2_CTXT_REG_1
* @brief Execution Access register address for register 1 at Priority 2
* Executing Context Stack level
*/
#define IX_NPEDL_ECS_PRI_2_CTXT_REG_1 0x09
/**
* @def IX_NPEDL_ECS_PRI_2_CTXT_REG_2
* @brief Execution Access register address for register 2 at Priority 2
* Executing Context Stack level
*/
#define IX_NPEDL_ECS_PRI_2_CTXT_REG_2 0x0A
/**
* @def IX_NPEDL_ECS_DBG_CTXT_REG_0
* @brief Execution Access register address for register 0 at Debug
* Executing Context Stack level
*/
#define IX_NPEDL_ECS_DBG_CTXT_REG_0 0x0C
/**
* @def IX_NPEDL_ECS_DBG_CTXT_REG_1
* @brief Execution Access register address for register 1 at Debug
* Executing Context Stack level
*/
#define IX_NPEDL_ECS_DBG_CTXT_REG_1 0x0D
/**
* @def IX_NPEDL_ECS_DBG_CTXT_REG_2
* @brief Execution Access register address for register 2 at Debug
* Executing Context Stack level
*/
#define IX_NPEDL_ECS_DBG_CTXT_REG_2 0x0E
/**
* @def IX_NPEDL_ECS_INSTRUCT_REG
* @brief Execution Access register address for NPE Instruction Register
*/
#define IX_NPEDL_ECS_INSTRUCT_REG 0x11
/*
* Execution Access register reset values
*/
/**
* @def IX_NPEDL_ECS_BG_CTXT_REG_0_RESET
* @brief Reset value for Execution Access Background ECS level register 0
*/
#define IX_NPEDL_ECS_BG_CTXT_REG_0_RESET 0xA0000000
/**
* @def IX_NPEDL_ECS_BG_CTXT_REG_1_RESET
* @brief Reset value for Execution Access Background ECS level register 1
*/
#define IX_NPEDL_ECS_BG_CTXT_REG_1_RESET 0x01000000
/**
* @def IX_NPEDL_ECS_BG_CTXT_REG_2_RESET
* @brief Reset value for Execution Access Background ECS level register 2
*/
#define IX_NPEDL_ECS_BG_CTXT_REG_2_RESET 0x00008000
/**
* @def IX_NPEDL_ECS_PRI_1_CTXT_REG_0_RESET
* @brief Reset value for Execution Access Priority 1 ECS level register 0
*/
#define IX_NPEDL_ECS_PRI_1_CTXT_REG_0_RESET 0x20000080
/**
* @def IX_NPEDL_ECS_PRI_1_CTXT_REG_1_RESET
* @brief Reset value for Execution Access Priority 1 ECS level register 1
*/
#define IX_NPEDL_ECS_PRI_1_CTXT_REG_1_RESET 0x01000000
/**
* @def IX_NPEDL_ECS_PRI_1_CTXT_REG_2_RESET
* @brief Reset value for Execution Access Priority 1 ECS level register 2
*/
#define IX_NPEDL_ECS_PRI_1_CTXT_REG_2_RESET 0x00008000
/**
* @def IX_NPEDL_ECS_PRI_2_CTXT_REG_0_RESET
* @brief Reset value for Execution Access Priority 2 ECS level register 0
*/
#define IX_NPEDL_ECS_PRI_2_CTXT_REG_0_RESET 0x20000080
/**
* @def IX_NPEDL_ECS_PRI_2_CTXT_REG_1_RESET
* @brief Reset value for Execution Access Priority 2 ECS level register 1
*/
#define IX_NPEDL_ECS_PRI_2_CTXT_REG_1_RESET 0x01000000
/**
* @def IX_NPEDL_ECS_PRI_2_CTXT_REG_2_RESET
* @brief Reset value for Execution Access Priority 2 ECS level register 2
*/
#define IX_NPEDL_ECS_PRI_2_CTXT_REG_2_RESET 0x00008000
/**
* @def IX_NPEDL_ECS_DBG_CTXT_REG_0_RESET
* @brief Reset value for Execution Access Debug ECS level register 0
*/
#define IX_NPEDL_ECS_DBG_CTXT_REG_0_RESET 0x20000000
/**
* @def IX_NPEDL_ECS_DBG_CTXT_REG_1_RESET
* @brief Reset value for Execution Access Debug ECS level register 1
*/
#define IX_NPEDL_ECS_DBG_CTXT_REG_1_RESET 0x00000000
/**
* @def IX_NPEDL_ECS_DBG_CTXT_REG_2_RESET
* @brief Reset value for Execution Access Debug ECS level register 2
*/
#define IX_NPEDL_ECS_DBG_CTXT_REG_2_RESET 0x001E0000
/**
* @def IX_NPEDL_ECS_INSTRUCT_REG_RESET
* @brief Reset value for Execution Access NPE Instruction Register
*/
#define IX_NPEDL_ECS_INSTRUCT_REG_RESET 0x1003C00F
/*
* masks used to read/write particular bits in Execution Access registers
*/
/**
* @def IX_NPEDL_MASK_ECS_REG_0_ACTIVE
* @brief Mask the A (Active) bit in Execution Access Register 0 of all ECS
* levels
*/
#define IX_NPEDL_MASK_ECS_REG_0_ACTIVE 0x80000000
/**
* @def IX_NPEDL_MASK_ECS_REG_0_NEXTPC
* @brief Mask the NextPC bits in Execution Access Register 0 of all ECS
* levels (except Debug ECS level)
*/
#define IX_NPEDL_MASK_ECS_REG_0_NEXTPC 0x1FFF0000
/**
* @def IX_NPEDL_MASK_ECS_REG_0_LDUR
* @brief Mask the LDUR bits in Execution Access Register 0 of all ECS levels
*/
#define IX_NPEDL_MASK_ECS_REG_0_LDUR 0x00000700
/**
* @def IX_NPEDL_MASK_ECS_REG_1_CCTXT
* @brief Mask the NextPC bits in Execution Access Register 1 of all ECS levels
*/
#define IX_NPEDL_MASK_ECS_REG_1_CCTXT 0x000F0000
/**
* @def IX_NPEDL_MASK_ECS_REG_1_SELCTXT
* @brief Mask the NextPC bits in Execution Access Register 1 of all ECS levels
*/
#define IX_NPEDL_MASK_ECS_REG_1_SELCTXT 0x0000000F
/**
* @def IX_NPEDL_MASK_ECS_DBG_REG_2_IF
* @brief Mask the IF bit in Execution Access Register 2 of Debug ECS level
*/
#define IX_NPEDL_MASK_ECS_DBG_REG_2_IF 0x00100000
/**
* @def IX_NPEDL_MASK_ECS_DBG_REG_2_IE
* @brief Mask the IE bit in Execution Access Register 2 of Debug ECS level
*/
#define IX_NPEDL_MASK_ECS_DBG_REG_2_IE 0x00080000
/*
* Bit-Offsets from LSB of particular bit-fields in Execution Access registers
*/
/**
* @def IX_NPEDL_OFFSET_ECS_REG_0_NEXTPC
* @brief LSB-offset of NextPC field in Execution Access Register 0 of all ECS
* levels (except Debug ECS level)
*/
#define IX_NPEDL_OFFSET_ECS_REG_0_NEXTPC 16
/**
* @def IX_NPEDL_OFFSET_ECS_REG_0_LDUR
* @brief LSB-offset of LDUR field in Execution Access Register 0 of all ECS
* levels
*/
#define IX_NPEDL_OFFSET_ECS_REG_0_LDUR 8
/**
* @def IX_NPEDL_OFFSET_ECS_REG_1_CCTXT
* @brief LSB-offset of CCTXT field in Execution Access Register 1 of all ECS
* levels
*/
#define IX_NPEDL_OFFSET_ECS_REG_1_CCTXT 16
/**
* @def IX_NPEDL_OFFSET_ECS_REG_1_SELCTXT
* @brief LSB-offset of SELCTXT field in Execution Access Register 1 of all ECS
* levels
*/
#define IX_NPEDL_OFFSET_ECS_REG_1_SELCTXT 0
/*
* NPE core & co-processor instruction templates to load into NPE Instruction
* Register, for read/write of NPE register file registers
*/
/**
* @def IX_NPEDL_INSTR_RD_REG_BYTE
* @brief NPE Instruction, used to read an 8-bit NPE internal logical register
* and return the value in the EXDATA register (aligned to MSB).
* NPE Assembler instruction: "mov8 d0, d0 &&& DBG_WrExec"
*/
#define IX_NPEDL_INSTR_RD_REG_BYTE 0x0FC00000
/**
* @def IX_NPEDL_INSTR_RD_REG_SHORT
* @brief NPE Instruction, used to read a 16-bit NPE internal logical register
* and return the value in the EXDATA register (aligned to MSB).
* NPE Assembler instruction: "mov16 d0, d0 &&& DBG_WrExec"
*/
#define IX_NPEDL_INSTR_RD_REG_SHORT 0x0FC08010
/**
* @def IX_NPEDL_INSTR_RD_REG_WORD
* @brief NPE Instruction, used to read a 16-bit NPE internal logical register
* and return the value in the EXDATA register.
* NPE Assembler instruction: "mov32 d0, d0 &&& DBG_WrExec"
*/
#define IX_NPEDL_INSTR_RD_REG_WORD 0x0FC08210
/**
* @def IX_NPEDL_INSTR_WR_REG_BYTE
* @brief NPE Immediate-Mode Instruction, used to write an 8-bit NPE internal
* logical register.
* NPE Assembler instruction: "mov8 d0, #0"
*/
#define IX_NPEDL_INSTR_WR_REG_BYTE 0x00004000
/**
* @def IX_NPEDL_INSTR_WR_REG_SHORT
* @brief NPE Immediate-Mode Instruction, used to write a 16-bit NPE internal
* logical register.
* NPE Assembler instruction: "mov16 d0, #0"
*/
#define IX_NPEDL_INSTR_WR_REG_SHORT 0x0000C000
/**
* @def IX_NPEDL_INSTR_RD_FIFO
* @brief NPE Immediate-Mode Instruction, used to write a 16-bit NPE internal
* logical register.
* NPE Assembler instruction: "cprd32 d0 &&& DBG_RdInFIFO"
*/
#define IX_NPEDL_INSTR_RD_FIFO 0x0F888220
/**
* @def IX_NPEDL_INSTR_RESET_MBOX
* @brief NPE Instruction, used to reset Mailbox (MBST) register
* NPE Assembler instruction: "mov32 d0, d0 &&& DBG_ClearM"
*/
#define IX_NPEDL_INSTR_RESET_MBOX 0x0FAC8210
/*
* Bit-offsets from LSB, of particular bit-fields in an NPE instruction
*/
/**
* @def IX_NPEDL_OFFSET_INSTR_SRC
* @brief LSB-offset to SRC (source operand) field of an NPE Instruction
*/
#define IX_NPEDL_OFFSET_INSTR_SRC 4
/**
* @def IX_NPEDL_OFFSET_INSTR_DEST
* @brief LSB-offset to DEST (destination operand) field of an NPE Instruction
*/
#define IX_NPEDL_OFFSET_INSTR_DEST 9
/**
* @def IX_NPEDL_OFFSET_INSTR_COPROC
* @brief LSB-offset to COPROC (coprocessor instruction) field of an NPE
* Instruction
*/
#define IX_NPEDL_OFFSET_INSTR_COPROC 18
/*
* masks used to read/write particular bits of an NPE Instruction
*/
/**
* @def IX_NPEDL_MASK_IMMED_INSTR_SRC_DATA
* @brief Mask the bits of 16-bit data value (least-sig 5 bits) to be used in
* SRC field of immediate-mode NPE instruction
*/
#define IX_NPEDL_MASK_IMMED_INSTR_SRC_DATA 0x1F
/**
* @def IX_NPEDL_MASK_IMMED_INSTR_COPROC_DATA
* @brief Mask the bits of 16-bit data value (most-sig 11 bits) to be used in
* COPROC field of immediate-mode NPE instruction
*/
#define IX_NPEDL_MASK_IMMED_INSTR_COPROC_DATA 0xFFE0
/**
* @def IX_NPEDL_OFFSET_IMMED_INSTR_COPROC_DATA
* @brief LSB offset of the bit-field of 16-bit data value (most-sig 11 bits)
* to be used in COPROC field of immediate-mode NPE instruction
*/
#define IX_NPEDL_OFFSET_IMMED_INSTR_COPROC_DATA 5
/**
* @def IX_NPEDL_DISPLACE_IMMED_INSTR_COPROC_DATA
* @brief Number of left-shifts required to align most-sig 11 bits of 16-bit
* data value into COPROC field of immediate-mode NPE instruction
*/
#define IX_NPEDL_DISPLACE_IMMED_INSTR_COPROC_DATA \
(IX_NPEDL_OFFSET_INSTR_COPROC - IX_NPEDL_OFFSET_IMMED_INSTR_COPROC_DATA)
/**
* @def IX_NPEDL_WR_INSTR_LDUR
* @brief LDUR value used with immediate-mode NPE Instructions by the NpeDl
* for writing to NPE internal logical registers
*/
#define IX_NPEDL_WR_INSTR_LDUR 1
/**
* @def IX_NPEDL_RD_INSTR_LDUR
* @brief LDUR value used with NON-immediate-mode NPE Instructions by the NpeDl
* for reading from NPE internal logical registers
*/
#define IX_NPEDL_RD_INSTR_LDUR 0
/**
* @enum IxNpeDlCtxtRegNum
* @brief Numeric values to identify the NPE internal Context Store registers
*/
typedef enum
{
IX_NPEDL_CTXT_REG_STEVT = 0, /**< identifies STEVT */
IX_NPEDL_CTXT_REG_STARTPC, /**< identifies STARTPC */
IX_NPEDL_CTXT_REG_REGMAP, /**< identifies REGMAP */
IX_NPEDL_CTXT_REG_CINDEX, /**< identifies CINDEX */
IX_NPEDL_CTXT_REG_MAX /**< Total number of Context Store registers */
} IxNpeDlCtxtRegNum;
/*
* NPE Context Store register logical addresses
*/
/**
* @def IX_NPEDL_CTXT_REG_ADDR_STEVT
* @brief Logical address of STEVT NPE internal Context Store register
*/
#define IX_NPEDL_CTXT_REG_ADDR_STEVT 0x0000001B
/**
* @def IX_NPEDL_CTXT_REG_ADDR_STARTPC
* @brief Logical address of STARTPC NPE internal Context Store register
*/
#define IX_NPEDL_CTXT_REG_ADDR_STARTPC 0x0000001C
/**
* @def IX_NPEDL_CTXT_REG_ADDR_REGMAP
* @brief Logical address of REGMAP NPE internal Context Store register
*/
#define IX_NPEDL_CTXT_REG_ADDR_REGMAP 0x0000001E
/**
* @def IX_NPEDL_CTXT_REG_ADDR_CINDEX
* @brief Logical address of CINDEX NPE internal Context Store register
*/
#define IX_NPEDL_CTXT_REG_ADDR_CINDEX 0x0000001F
/*
* NPE Context Store register reset values
*/
/**
* @def IX_NPEDL_CTXT_REG_RESET_STEVT
* @brief Reset value of STEVT NPE internal Context Store register
* (STEVT = off, 0x80)
*/
#define IX_NPEDL_CTXT_REG_RESET_STEVT 0x80
/**
* @def IX_NPEDL_CTXT_REG_RESET_STARTPC
* @brief Reset value of STARTPC NPE internal Context Store register
* (STARTPC = 0x0000)
*/
#define IX_NPEDL_CTXT_REG_RESET_STARTPC 0x0000
/**
* @def IX_NPEDL_CTXT_REG_RESET_REGMAP
* @brief Reset value of REGMAP NPE internal Context Store register
* (REGMAP = d0->p0, d8->p2, d16->p4)
*/
#define IX_NPEDL_CTXT_REG_RESET_REGMAP 0x0820
/**
* @def IX_NPEDL_CTXT_REG_RESET_CINDEX
* @brief Reset value of CINDEX NPE internal Context Store register
* (CINDEX = 0)
*/
#define IX_NPEDL_CTXT_REG_RESET_CINDEX 0x00
/*
* numeric range of context levels available on an NPE
*/
/**
* @def IX_NPEDL_CTXT_NUM_MIN
* @brief Lowest NPE Context number in range
*/
#define IX_NPEDL_CTXT_NUM_MIN 0
/**
* @def IX_NPEDL_CTXT_NUM_MAX
* @brief Highest NPE Context number in range
*/
#define IX_NPEDL_CTXT_NUM_MAX 15
/*
* Physical NPE internal registers
*/
/**
* @def IX_NPEDL_TOTAL_NUM_PHYS_REG
* @brief Number of Physical registers currently supported
* Initial NPE implementations will have a 32-word register file.
* Later implementations may have a 64-word register file.
*/
#define IX_NPEDL_TOTAL_NUM_PHYS_REG 32
/**
* @def IX_NPEDL_OFFSET_PHYS_REG_ADDR_REGMAP
* @brief LSB-offset of Regmap number in Physical NPE register address, used
* for Physical To Logical register address mapping in the NPE
*/
#define IX_NPEDL_OFFSET_PHYS_REG_ADDR_REGMAP 1
/**
* @def IX_NPEDL_MASK_PHYS_REG_ADDR_LOGICAL_ADDR
* @brief Mask to extract a logical NPE register address from a physical
* register address, used for Physical To Logical address mapping
*/
#define IX_NPEDL_MASK_PHYS_REG_ADDR_LOGICAL_ADDR 0x1
#endif /* IXNPEDLNPEMGRECREGISTERS_P_H */

View file

@ -0,0 +1,405 @@
/**
* @file IxNpeDlNpeMgrUtils_p.h
*
* @author Intel Corporation
* @date 18 February 2002
* @brief This file contains the private API for the NpeMgr module.
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
/**
* @defgroup IxNpeDlNpeMgrUtils_p IxNpeDlNpeMgrUtils_p
*
* @brief The private API for the IxNpeDl NpeMgr Utils module
*
* @{
*/
#ifndef IXNPEDLNPEMGRUTILS_P_H
#define IXNPEDLNPEMGRUTILS_P_H
/*
* Put the user defined include files required.
*/
#include "IxNpeDl.h"
#include "IxOsalTypes.h"
#include "IxNpeDlNpeMgrEcRegisters_p.h"
/*
* Function Prototypes
*/
/**
* @fn IX_STATUS ixNpeDlNpeMgrInsMemWrite (UINT32 npeBaseAddress,
UINT32 insMemAddress,
UINT32 insMemData,
BOOL verify)
*
* @brief Writes a word to NPE Instruction memory
*
* @param UINT32 [in] npeBaseAddress - Base Address of NPE
* @param UINT32 [in] insMemAddress - NPE instruction memory address to write
* @param UINT32 [in] insMemData - data to write to instruction memory
* @param BOOL [in] verify - if TRUE, verify the memory location is
* written successfully.
*
* This function is used to write a single word of data to a location in NPE
* instruction memory. If the <i>verify</i> option is ON, NpeDl will read back
* from the memory location to verify that it was written successfully
*
* @pre
*
* @post
*
* @return
* - IX_FAIL if verify is TRUE and the memory location was not written
* successfully
* - IX_SUCCESS otherwise
*/
IX_STATUS
ixNpeDlNpeMgrInsMemWrite (UINT32 npeBaseAddress, UINT32 insMemAddress,
UINT32 insMemData, BOOL verify);
/**
* @fn IX_STATUS ixNpeDlNpeMgrDataMemWrite (UINT32 npeBaseAddress,
UINT32 dataMemAddress,
UINT32 dataMemData,
BOOL verify)
*
* @brief Writes a word to NPE Data memory
*
* @param UINT32 [in] npeBaseAddress - Base Address of NPE
* @param UINT32 [in] dataMemAddress - NPE data memory address to write
* @param UINT32 [in] dataMemData - data to write to NPE data memory
* @param BOOL [in] verify - if TRUE, verify the memory location is
* written successfully.
*
* This function is used to write a single word of data to a location in NPE
* data memory. If the <i>verify</i> option is ON, NpeDl will read back from
* the memory location to verify that it was written successfully
*
* @pre
*
* @post
*
* @return
* - IX_FAIL if verify is TRUE and the memory location was not written
* successfully
* - IX_SUCCESS otherwise
*/
IX_STATUS
ixNpeDlNpeMgrDataMemWrite (UINT32 npeBaseAddress, UINT32 dataMemAddress,
UINT32 dataMemData, BOOL verify);
/**
* @fn void ixNpeDlNpeMgrExecAccRegWrite (UINT32 npeBaseAddress,
UINT32 regAddress,
UINT32 regData)
*
* @brief Writes a word to an NPE Execution Access register
*
* @param UINT32 [in] npeBaseAddress - Base Address of NPE
* @param UINT32 [in] regAddress - NPE Execution Access register address
* @param UINT32 [in] regData - data to write to register
*
* This function is used to write a single word of data to an NPE Execution
* Access register.
*
* @pre
*
* @post
*
* @return none
*/
void
ixNpeDlNpeMgrExecAccRegWrite (UINT32 npeBaseAddress, UINT32 regAddress,
UINT32 regData);
/**
* @fn UINT32 ixNpeDlNpeMgrExecAccRegRead (UINT32 npeBaseAddress,
UINT32 regAddress)
*
* @brief Reads the contents of an NPE Execution Access register
*
* @param UINT32 [in] npeBaseAddress - Base Address of NPE
* @param UINT32 [in] regAddress - NPE Execution Access register address
*
* This function is used to read the contents of an NPE Execution
* Access register.
*
* @pre
*
* @post
*
* @return The value read from the Execution Access register
*/
UINT32
ixNpeDlNpeMgrExecAccRegRead (UINT32 npeBaseAddress, UINT32 regAddress);
/**
* @fn void ixNpeDlNpeMgrCommandIssue (UINT32 npeBaseAddress,
UINT32 command)
*
* @brief Issues an NPE Execution Control command
*
* @param UINT32 [in] npeBaseAddress - Base Address of NPE
* @param UINT32 [in] command - Command to issue
*
* This function is used to issue a stand-alone NPE Execution Control command
* (e.g. command to Stop NPE execution)
*
* @pre
*
* @post
*
* @return none
*/
void
ixNpeDlNpeMgrCommandIssue (UINT32 npeBaseAddress, UINT32 command);
/**
* @fn void ixNpeDlNpeMgrDebugInstructionPreExec (UINT32 npeBaseAddress)
*
* @brief Prepare to executes one or more NPE instructions in the Debug
* Execution Stack level.
*
* @param UINT32 [in] npeBaseAddress - Base Address of NPE
*
* This function should be called once before a sequence of calls to
* ixNpeDlNpeMgrDebugInstructionExec().
*
* @pre
*
* @post
* - ixNpeDlNpeMgrDebugInstructionPostExec() should be called to restore
* registers values altered by this function
*
* @return none
*/
void
ixNpeDlNpeMgrDebugInstructionPreExec (UINT32 npeBaseAddress);
/**
* @fn IX_STATUS ixNpeDlNpeMgrDebugInstructionExec (UINT32 npeBaseAddress,
UINT32 npeInstruction,
UINT32 ctxtNum,
UINT32 ldur)
*
* @brief Executes a single instruction on the NPE at the Debug Execution Stack
* level
*
* @param UINT32 [in] npeBaseAddress - Base Address of NPE
* @param UINT32 [in] npeInstruction - Value to write to INSTR (Instruction)
* register
* @param UINT32 [in] ctxtNum - context the instruction will be executed
* in and which context store it may access
* @param UINT32 [in] ldur - Long Immediate Duration, set to non-zero
* to use long-immediate mode instruction
*
* This function is used to execute a single instruction in the NPE pipeline at
* the debug Execution Context Stack level. It won't disturb the state of other
* executing contexts. Its useful for performing NPE operations, such as
* writing to NPE Context Store registers and physical registers, that cannot
* be carried out directly using the Configuration Bus registers. This function
* will return TIMEOUT status if NPE not responding due to NPS is hang / halt.
*
* @pre
* - The NPE should be stopped and in a clean state
* - ixNpeDlNpeMgrDebugInstructionPreExec() should be called once before
* a sequential of 1 or more calls to this function
*
* @post
* - ixNpeDlNpeMgrDebugInstructionPostExec() should be called after
* a sequence of calls to this function
*
* @return
* - IX_NPEDL_CRITICAL_NPE_ERR if execution of instruction failed / timeout
* - IX_SUCCESS otherwise
*/
IX_STATUS
ixNpeDlNpeMgrDebugInstructionExec (UINT32 npeBaseAddress,
UINT32 npeInstruction,
UINT32 ctxtNum, UINT32 ldur);
/**
* @fn void ixNpeDlNpeMgrDebugInstructionPostExec (UINT32 npeBaseAddress)
*
* @brief Clean up after executing one or more NPE instructions in the
* Debug Stack Level
*
* @param UINT32 [in] npeBaseAddress - Base Address of NPE
*
* This function should be called once following a sequence of calls to
* ixNpeDlNpeMgrDebugInstructionExec().
*
* @pre
* - ixNpeDlNpeMgrDebugInstructionPreExec() was called earlier
*
* @post
* - The Instruction Pipeline will cleared
*
* @return none
*/
void
ixNpeDlNpeMgrDebugInstructionPostExec (UINT32 npeBaseAddress);
/**
* @fn IX_STATUS ixNpeDlNpeMgrPhysicalRegWrite (UINT32 npeBaseAddress,
UINT32 regAddr,
UINT32 regValue,
BOOL verify)
*
* @brief Write one of the 32* 32-bit physical registers in the NPE data
* register file
*
* @param UINT32 [in] npeBaseAddress - Base Address of NPE
* @param UINT32 [in] regAddr - number of the physical register (0-31)*
* @param UINT32 [in] regValue - value to write to the physical register
* @param BOOL [in] verify - if TRUE, verify the register is written
* successfully.
*
* This function writes a physical register in the NPE data register file.
* If the <i>verify</i> option is ON, NpeDl will read back the register to
* verify that it was written successfully
* *Note that release 1.0 of this software supports 32 physical
* registers, but 64 may be supported in future versions.
*
* @pre
* - The NPE should be stopped and in a clean state
* - ixNpeDlNpeMgrDebugInstructionPreExec() should be called once before
* a sequential of 1 or more calls to this function
*
* @post
* - Contents of REGMAP Context Store register for Context 0 will be altered
* - ixNpeDlNpeMgrDebugInstructionPostExec() should be called after
* a sequence of calls to this function
*
* @return
* - IX_FAIL if verify is TRUE and the Context Register was not written
* successfully
* - IX_SUCCESS if Context Register was written successfully
* - IX_NPEDL_CRITICAL_NPE_ERR if Context Register was not written
* successfully due to timeout error where NPE is not responding
*/
IX_STATUS
ixNpeDlNpeMgrPhysicalRegWrite (UINT32 npeBaseAddress, UINT32 regAddr,
UINT32 regValue, BOOL verify);
/**
* @fn IX_STATUS ixNpeDlNpeMgrCtxtRegWrite (UINT32 npeBaseAddress,
UINT32 ctxtNum,
IxNpeDlCtxtRegNum ctxtReg,
UINT32 ctxtRegVal,
BOOL verify)
*
* @brief Writes a value to a Context Store register on an NPE
*
* @param UINT32 [in] npeBaseAddress - Base Address of NPE
* @param UINT32 [in] ctxtNum - context store to access
* @param IxNpeDlCtxtRegNum [in] ctxtReg - which Context Store reg to write
* @param UINT32 [in] ctxtRegVal - value to write to the Context Store
* register
* @param BOOL [in] verify - if TRUE, verify the register is
* written successfully.
*
* This function writes the contents of a Context Store register in the NPE
* register file. If the <i>verify</i> option is ON, NpeDl will read back the
* register to verify that it was written successfully
*
* @pre
* - The NPE should be stopped and in a clean state
* - ixNpeDlNpeMgrDebugInstructionPreExec() should be called once before
* a sequential of 1 or more calls to this function
*
* @post
* - ixNpeDlNpeMgrDebugInstructionPostExec() should be called after
* a sequence of calls to this function
*
* @return
* - IX_FAIL if verify is TRUE and the Context Register was not written
* successfully
* - IX_SUCCESS if Context Register was written successfully
* - IX_NPEDL_CRITICAL_NPE_ERR if Context Register was not written
* successfully due to timeout error where NPE is not responding
*/
IX_STATUS
ixNpeDlNpeMgrCtxtRegWrite (UINT32 npeBaseAddress, UINT32 ctxtNum,
IxNpeDlCtxtRegNum ctxtReg, UINT32 ctxtRegVal,
BOOL verify);
/**
* @fn void ixNpeDlNpeMgrUtilsStatsShow (void)
*
* @brief This function will display the statistics of the IxNpeDl NpeMgrUtils
* module
*
* @return none
*/
void
ixNpeDlNpeMgrUtilsStatsShow (void);
/**
* @fn void ixNpeDlNpeMgrUtilsStatsReset (void)
*
* @brief This function will reset the statistics of the IxNpeDl NpeMgrUtils
* module
*
* @return none
*/
void
ixNpeDlNpeMgrUtilsStatsReset (void);
#endif /* IXNPEDLNPEMGRUTILS_P_H */

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